# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: pod-broker-gateway
spec:
  selector:
    # updated with patch to match target ingressgateway
    istio: ingressgateway
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      # Hosts should be added using kustomize patch.
      hosts:
        - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: pod-broker
spec:
  hosts:
    - "*"
  gateways:
    - pod-broker-gateway
  http:
    - match:
        - uri:
            prefix: /broker/
      rewrite:
        uri: /
      route:
        - destination:
            host: pod-broker
            port:
              number: 8080
      # When using the istio sidecar, 503 UC errors are common due to per-app TCP connection timeout settings.
      # https://karlstoney.com/2019/05/31/istio-503s-ucs-and-tcp-fun-times/
      # https://github.com/istio/istio/issues/9113
      #
      retries:
        attempts: 1
        perTryTimeout: 2s
        retryOn: gateway-error,connect-failure,refused-stream
    - match:
        - uri:
            prefix: /reservation-broker/
      rewrite:
        uri: /
      route:
        - destination:
            host: pod-broker
            port:
              number: 8082
      retries:
        attempts: 1
        perTryTimeout: 2s
        retryOn: gateway-error,connect-failure,refused-stream
    - match:
        - uri:
            prefix: /publish/
      rewrite:
        uri: /
      route:
        - destination:
            host: pod-broker
            port:
              number: 8081
    - match:
        - uri:
            prefix: /
      route:
        - destination:
            host: pod-broker
            port:
              number: 80
      # When using the istio sidecar, 503 UC errors are common due to per-app TCP connection timeout settings.
      # https://karlstoney.com/2019/05/31/istio-503s-ucs-and-tcp-fun-times/
      # https://github.com/istio/istio/issues/9113
      #
      retries:
        attempts: 1
        perTryTimeout: 2s
        retryOn: gateway-error,connect-failure,refused-stream
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: pod-broker-config
data:
  POD_BROKER_PARAM_Theme: "dark"
  POD_BROKER_PARAM_Title: "App Launcher"
  POD_BROKER_PARAM_Domain: "broker.endpoints.my-project-id.cloud.goog"
  POD_BROKER_PARAM_AuthHeader: "x-goog-authenticated-user-email"
  POD_BROKER_PARAM_AuthonrizedUserRepoPattern: "gcr.io/.*"
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: pod-broker
  labels:
    app: pod-broker
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: pod-broker
  labels:
    app: pod-broker
subjects:
  - kind: ServiceAccount
    name: pod-broker
    namespace: pod-broker-system
roleRef:
  kind: ClusterRole
  name: pod-broker
  apiGroup: rbac.authorization.k8s.io
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: pod-broker
  namespace: pod-broker-system
  labels:
    app: pod-broker
rules:
  - apiGroups:
      - "*"
    resources:
      - "*"
    verbs:
      - "*"
  - nonResourceURLs:
      - "*"
    verbs:
      - "*"
---
apiVersion: v1
kind: Service
metadata:
  name: pod-broker
spec:
  selector:
    app: pod-broker
  ports:
    - port: 8080
      name: http-broker
      targetPort: 8080
    - port: 8081
      name: http-publish
      targetPort: 8081
    - port: 8082
      name: http-rbroker
      targetPort: 8082
    - port: 80
      name: http-web
      targetPort: 80
  sessionAffinity: ClientIP
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: pod-broker
spec:
  selector:
    matchLabels:
      app: pod-broker
  serviceName: pod-broker
  replicas: 1
  volumeClaimTemplates: []
  template:
    metadata:
      labels:
        app: pod-broker
    spec:
      serviceAccountName: pod-broker
      terminationGracePeriodSeconds: 5
      volumes:
        ###
        # temp volume for building statefulset manifests
        ###
        - name: build-statefulsets
          emptyDir: {}
        ###
        # temp volume for building deployment type manifests
        ###
        - name: build-deployments
          emptyDir: {}
        ###
        # temp volume for building deployment type user manifests
        ###
        - name: build-deployments-user
          emptyDir: {}
        ###
        # temp volume for building user namespace manifests
        ###
        - name: buildns
          emptyDir: {}
        ###
        # temp volume for storing app configs and manifest bundles.
        ###
        - name: buildsrc
          emptyDir: {}
        ###
        # temp volume for storing cached user configs
        ###
        - name: userconfig
          emptyDir: {}
        ###
        # App publishing job template
        ###
        - name: app-publish-job-template
          configMap:
            name: app-publish-job-template

      containers:
        ###
        # pod-broker
        ###
        - name: pod-broker
          image: gcr.io/cloud-solutions-images/kube-pod-broker-controller:latest
          command: ["/usr/local/bin/pod-broker"]
          workingDir: "/var/run/build"
          # Pull default pod broker config from ConfigMap
          # Contains keys in the form of POD_BROKER_PARAM_ValueName=Value
          envFrom:
            - configMapRef:
                name: pod-broker-config
                optional: false
          env:
            - name: COOKIE_SECRET
              valueFrom:
                secretKeyRef:
                  name: pod-broker
                  key: COOKIE_SECRET
            - name: OAUTH_CLIENT_ID
              valueFrom:
                secretKeyRef:
                  name: oauth-client-id
                  key: CLIENT_ID
          volumeMounts:
            - name: build-statefulsets
              mountPath: /var/run/build
            - name: buildns
              mountPath: /var/run/buildns
            - name: buildsrc
              mountPath: /var/run/buildsrc
            - name: userconfig
              mountPath: /var/run/userconfig
          readinessProbe:
            tcpSocket:
              port: 8080
        ###
        # reservation-broker
        ###
        - name: reservation-broker
          image: gcr.io/cloud-solutions-images/kube-pod-broker-controller:latest
          command: ["/usr/local/bin/reservation-broker"]
          workingDir: "/var/run/build"
          # Pull default pod broker config from ConfigMap
          # Contains keys in the form of POD_BROKER_PARAM_ValueName=Value
          envFrom:
            - configMapRef:
                name: pod-broker-config
                optional: false
          env:
            - name: COOKIE_SECRET
              valueFrom:
                secretKeyRef:
                  name: pod-broker
                  key: COOKIE_SECRET
            - name: OAUTH_CLIENT_ID
              valueFrom:
                secretKeyRef:
                  name: oauth-client-id
                  key: CLIENT_ID
          volumeMounts:
            - name: build-deployments
              mountPath: /var/run/build
            - name: build-deployments-user
              mountPath: /var/run/buildusr
            - name: buildsrc
              mountPath: /var/run/buildsrc
          readinessProbe:
            tcpSocket:
              port: 8082
        ###
        # App config finder sidecar
        ###
        - name: app-finder
          image: gcr.io/cloud-solutions-images/kube-pod-broker-controller:latest
          command: ["/usr/local/bin/app-finder"]
          workingDir: "/var/run/buildsrc"
          env:
            - name: NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          volumeMounts:
            - name: build-statefulsets
              mountPath: /var/run/build
            - name: buildsrc
              mountPath: /var/run/buildsrc
            - name: userconfig
              mountPath: /var/run/userconfig

        ###
        # Image finding sidecar
        ###
        - name: image-list
          image: gcr.io/cloud-solutions-images/kube-pod-broker-controller:latest
          workingDir: /var/run/build
          command: ["/usr/local/bin/image-finder"]
          env:
            - name: NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          volumeMounts:
            - name: build-statefulsets
              mountPath: /var/run/build
            - name: userconfig
              mountPath: /var/run/userconfig

        ###
        # App publisher sidecar
        ###
        - name: app-publisher
          image: gcr.io/cloud-solutions-images/kube-pod-broker-controller:latest
          workingDir: /run/app-publisher
          command: ["/usr/local/bin/app-publisher"]
          # Pull default pod broker config from ConfigMap
          # Contains keys in the form of POD_BROKER_PARAM_ValueName=Value
          envFrom:
            - configMapRef:
                name: pod-broker-config
                optional: false
          env:
            - name: NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          volumeMounts:
            - name: buildsrc
              mountPath: /run/buildsrc
            - name: app-publish-job-template
              mountPath: /run/app-publisher/template
          readinessProbe:
            tcpSocket:
              port: 8080

        ###
        # pod-broker web
        ###
        - name: web
          image: gcr.io/cloud-solutions-images/kube-pod-broker-web:latest
          command: ["nginx", "-g", "daemon off;"]
          workingDir: "/usr/share/nginx/html"
          readinessProbe:
            httpGet:
              port: 80
