---
apiVersion: v1
kind: Secret
metadata:
  name: gcp-credentials
type: Opaque
data:
  gcp_json: "ewogICJjbGllbnRfaWQiOiAiMTIzNDU2Nzg5YWJjZGVmZy5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsCiAgImNsaWVudF9zZWNyZXQiOiAiZC1GTHlld3VxeWV1cXciLAogICJxdW90YV9wcm9qZWN0X2lkIjogInN1Z2dlc3RlZC1yZXZpZXdlci0xNTA0MDBlNiIsCiAgInJlZnJlc2hfdG9rZW4iOiAiMS8vMTIzNDU2NzhhYmNkZWZnIiwKICAidHlwZSI6ICJhdXRob3JpemVkX3VzZXIiCn0K"

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: recommender-bot-envoy-sidecar-config
  labels:
    app: recommender-bot
data:
  envoy.yaml: |
    static_resources:
      listeners:
        - name: "recommender-bot-http-listener"
          address:
            socket_address: { address: "0.0.0.0", port_value: 8282 }
          filter_chains:
            - filters:
              - name: "envoy.filters.network.http_connection_manager"
                typed_config:
                  "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
                  stat_prefix: "grpc_json"
                  codec_type: "AUTO"
                  route_config:
                    name: "local_route"
                    virtual_hosts:
                      - name: "local_service"
                        domains: [ "*" ]
                        routes:
                          - match: { prefix: "/", grpc: {} }
                            route: { cluster: "recommender-bot", timeout: 60s }
                  http_filters:
                    - name: "envoy.filters.http.grpc_json_transcoder"
                      typed_config:
                        "@type": type.googleapis.com/envoy.extensions.filters.http.grpc_json_transcoder.v3.GrpcJsonTranscoder
                        proto_descriptor: "/data/protos/recommender-bot.protoset.pb"
                        services: [ "bot.RecommenderService" ]
                        print_options:
                          add_whitespace: true
                          always_print_primitive_fields: true
                          always_print_enums_as_ints: false
                          preserve_proto_field_names: false
                        convert_grpc_status: true
                        request_validation_options:
                          reject_unknown_method: true
                          reject_unknown_query_parameters: true
                    - name: "envoy.filters.http.router"
        - name: "recommender-bot-http-auth-listener"
          address:
            socket_address: { address: "0.0.0.0", port_value: 8484 }
          filter_chains:
            - filters:
              - name: "envoy.filters.network.http_connection_manager"
                typed_config:
                  "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
                  stat_prefix: "grpc_json"
                  codec_type: "AUTO"
                  route_config:
                    name: "local_route"
                    virtual_hosts:
                      - name: "local_service"
                        domains: [ "*" ]
                        routes:
                          - match: { prefix: "/", grpc: {} }
                            route: { cluster: "recommender-bot", timeout: 60s }
                  http_filters:
                    - name: "envoy.filters.http.grpc_json_transcoder"
                      typed_config:
                        "@type": type.googleapis.com/envoy.extensions.filters.http.grpc_json_transcoder.v3.GrpcJsonTranscoder
                        proto_descriptor: "/data/protos/recommender-bot.protoset.pb"
                        services: [ "bot.RecommenderService" ]
                        print_options:
                          add_whitespace: true
                          always_print_primitive_fields: true
                          always_print_enums_as_ints: false
                          preserve_proto_field_names: false
                        convert_grpc_status: true
                        request_validation_options:
                          reject_unknown_method: true
                          reject_unknown_query_parameters: true
                    - name: "envoy.filters.http.ext_authz"
                      typed_config:
                        "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
                        http_service:
                          server_uri:
                            uri: "http://authenticator-service:8080"
                            cluster: "ext-auth"
                            timeout: 60s
                          authorization_request:
                            allowed_headers:
                              patterns:
                                - { exact: "Job-Token", ignore_case: true }
                                - { exact: "Project-Id", ignore_case: true }
                        failure_mode_allow: false
                    - name: "envoy.filters.http.router"

      clusters:
        - name: "recommender-bot"
          connect_timeout: "1.25s"
          type: "STATIC"
          lb_policy: "ROUND_ROBIN"
          dns_lookup_family: V4_ONLY
          typed_extension_protocol_options:
            envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
              "@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
              explicit_http_config:
                http2_protocol_options: { }
          load_assignment:
            cluster_name: "recommender-bot"
            endpoints:
              - lb_endpoints:
                  - endpoint:
                      address:
                        socket_address:
                          address: "127.0.0.1"
                          port_value: 8080
        - name: "ext-auth"
          connect_timeout: "1.25s"
          type: "LOGICAL_DNS"
          lb_policy: "ROUND_ROBIN"
          load_assignment:
            cluster_name: "ext-auth"
            endpoints:
              - lb_endpoints:
                  - endpoint:
                      address:
                        socket_address:
                          address: "authenticator-service"
                          port_value: 8080

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: recommender-bot-deployment
  labels:
    app: recommender-bot
spec:
  replicas: 1
  selector:
    matchLabels:
      app: recommender-bot
  template:
    metadata:
      labels:
        app: recommender-bot
    spec:
      initContainers:
        - name: protosets
          image: recommender-bot-service:dev
          imagePullPolicy: Never
          command: [sh, -c]
          args: [cp /app/recommender-bot.protoset.pb /data/protos]
          volumeMounts:
            - name: grpc-protosets
              mountPath: /data/protos
      containers:
        - name: recommender-bot-envoy-sidecar
          image: envoyproxy/envoy-alpine:v1.19-latest
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8282
            - containerPort: 8484
          volumeMounts:
            - name: recommender-bot-envoy-sidecar-config
              mountPath: /etc/envoy
            - name: grpc-protosets
              mountPath: /data/protos
              readOnly: true
        - name: recommender-bot
          image: recommender-bot-service:dev
          imagePullPolicy: Never
          ports:
            - containerPort: 8080
          env:
            - name: RECOMMENDER_BOT_SERVICE_PORT
              value: "8080"
            - name: RECOMMENDER_BOT_GITLAB_TOKEN
              valueFrom:
                secretKeyRef:
                  name: recommender-bot-gitlab-token
                  key: token
            - name: RECOMMENDER_BOT_GRPC_SERVICE_URL
              value: recommender-service:8080
            - name: RECOMMENDER_BOT_PG_CONN_STRING
              valueFrom:
                secretKeyRef:
                  name: recommender-bot-pg-conn-string
                  key: pg-conn
            - name: PUBSUB_EMULATOR_HOST
              value: pubsub:8432
            - name: GOOGLE_APPLICATION_CREDENTIALS
              value: /data/gcp/gcp_credentials.json
            - name: RECOMMENDER_BOT_PUBSUB_PROJECT_ID
              value: project-test
            - name: RECOMMENDER_BOT_PUBSUB_TOPIC_RECOMMENDATIONS
              value: gitlab.merge-request-recommendations-test.1
          volumeMounts:
            - name: gcp-secrets
              mountPath: /data/gcp
              readOnly: true
      volumes:
        - name: grpc-protosets
          emptyDir: {}
        - name: recommender-bot-envoy-sidecar-config
          configMap:
            name: recommender-bot-envoy-sidecar-config
        - name: gcp-secrets
          secret:
            secretName: gcp-credentials
            items:
              - key: gcp_json
                path: gcp_credentials.json

---
apiVersion: v1
kind: Service
metadata:
  name: recommender-bot-service
  labels:
    app: recommender-bot
spec:
  type: NodePort
  ports:
    - name: http-plain
      port: 8282
      targetPort: 8282
    - name: http-auth
      port: 8484
      targetPort: 8484
    - name: grpc
      port: 8080
      targetPort: 8080
  selector:
    app: recommender-bot
