# Proxy service
apiVersion: apps/v1
kind: Deployment
metadata:
  name: proxy-server
  namespace: <NAMESPACE>
  labels:
    app: proxy-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: proxy-server
  template:
    metadata:
      labels:
        app: proxy-server
        csm: <NAME>
    spec:
      containers:
      - name: proxy-server
        image: <AUTHORIZATION_PROXY_SERVER_IMAGE>
        imagePullPolicy: Always
        args:
          - "--redis-host=redis.<NAMESPACE>.svc.cluster.local:6379"
          - "--tenant-service=tenant-service.<NAMESPACE>.svc.cluster.local:50051"
          - "--role-service=role-service.<NAMESPACE>.svc.cluster.local:50051"
          - "--storage-service=storage-service.<NAMESPACE>.svc.cluster.local:50051"
        ports:
        - containerPort: 8080
        volumeMounts:
        - name: config-volume
          mountPath: /etc/karavi-authorization/config
        - name: storage-volume
          mountPath: /etc/karavi-authorization/storage
        - name: csm-config-params
          mountPath: /etc/karavi-authorization/csm-config-params
      - name: opa
        image: <AUTHORIZATION_OPA_IMAGE>
        imagePullPolicy: IfNotPresent
        args:
        - "run"
        - "--ignore=."
        - "--server"
        - "--log-level=debug"
        ports:
        - name: http
          containerPort: 8181
      - name: kube-mgmt
        image: <AUTHORIZATION_OPA_KUBEMGMT_IMAGE>
        imagePullPolicy: IfNotPresent
        args:
        - "--policies=authorization"
        - "--enable-data"
      volumes:
      - name: config-volume
        secret:
          secretName: karavi-config-secret
      - name: storage-volume
        secret:
          secretName: karavi-storage-secret
      - name: csm-config-params
        configMap:
          name: csm-config-params
---
apiVersion: v1
kind: Service
metadata:
  name: proxy-server
  namespace: <NAMESPACE>
spec:
  selector:
    app: proxy-server
  ports:
  - name: http
    protocol: TCP
    port: 8080
    targetPort: 8080
---
# Tenant Service
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tenant-service
  namespace: <NAMESPACE>
  labels:
    app: tenant-service
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tenant-service
  template:
    metadata:
      labels:
        app: tenant-service
        csm: <NAME>
    spec:
      containers:
      - name: tenant-service
        image: <AUTHORIZATION_TENANT_SERVICE_IMAGE>
        imagePullPolicy: Always
        args:
          - "--redis-host=redis.<NAMESPACE>.svc.cluster.local:6379"
        ports:
        - containerPort: 50051
          name: grpc
        volumeMounts:
        - name: config-volume
          mountPath: /etc/karavi-authorization/config
        - name: csm-config-params
          mountPath: /etc/karavi-authorization/csm-config-params
      volumes:
      - name: config-volume
        secret:
          secretName: karavi-config-secret
      - name: csm-config-params
        configMap:
          name: csm-config-params
---
apiVersion: v1
kind: Service
metadata:
  name: tenant-service
  namespace: <NAMESPACE>
spec:
  selector:
    app: tenant-service
  ports:
  - port: 50051
    targetPort: 50051
    name: grpc
---
# Role Service
apiVersion: v1
kind: ServiceAccount
metadata:
  name: role-service
  namespace: <NAMESPACE>
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: role-service
rules:
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["get", "patch"]
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: role-service
subjects:
  - kind: ServiceAccount
    name: role-service
    namespace: <NAMESPACE>
roleRef:
  kind: ClusterRole
  name: role-service
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: role-service
  namespace: <NAMESPACE>
  labels:
    app: role-service
spec:
  replicas: 1
  selector:
    matchLabels:
      app: role-service
  template:
    metadata:
      labels:
        csm: <NAME>
        app: role-service
    spec:
      serviceAccountName: role-service
      containers:
      - name: role-service
        image: <AUTHORIZATION_ROLE_SERVICE_IMAGE>
        imagePullPolicy: Always
        ports:
        - containerPort: 50051
          name: grpc
        env:
          - name: NAMESPACE
            value: <NAMESPACE>
        volumeMounts:
        - name: csm-config-params
          mountPath: /etc/karavi-authorization/csm-config-params
      volumes:
      - name: csm-config-params
        configMap:
          name: csm-config-params
---
apiVersion: v1
kind: Service
metadata:
  name: role-service
  namespace: <NAMESPACE>
spec:
  selector:
    app: role-service
  ports:
  - port: 50051
    targetPort: 50051
    name: grpc
---
# Storage service
apiVersion: v1
kind: ServiceAccount
metadata:
  name: storage-service
  namespace: <NAMESPACE>
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: storage-service
rules:
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get", "patch", "post"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: storage-service
subjects:
  - kind: ServiceAccount
    name: storage-service
    namespace: <NAMESPACE>
roleRef:
  kind: ClusterRole
  name: storage-service
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: storage-service
  namespace: <NAMESPACE>
  labels:
    app: storage-service
spec:
  replicas: 1
  selector:
    matchLabels:
      app: storage-service
  template:
    metadata:
      labels:
        csm: <NAME>
        app: storage-service
    spec:
      serviceAccountName: storage-service
      containers:
      - name: storage-service
        image: <AUTHORIZATION_STORAGE_SERVICE_IMAGE>
        imagePullPolicy: Always
        ports:
        - containerPort: 50051
          name: grpc
        env:
          - name: NAMESPACE
            value: authorization
        volumeMounts:
        - name: storage-volume
          mountPath: /etc/karavi-authorization/storage
        - name: config-volume
          mountPath: /etc/karavi-authorization/config
        - name: csm-config-params
          mountPath: /etc/karavi-authorization/csm-config-params
      volumes:
      - name: storage-volume
        secret:
          secretName: karavi-storage-secret
      - name: config-volume
        secret:
          secretName: karavi-config-secret
      - name: csm-config-params
        configMap:
          name: csm-config-params
---
apiVersion: v1
kind: Service
metadata:
  name: storage-service
  namespace: <NAMESPACE>
spec:
  selector:
    app: storage-service
  ports:
  - port: 50051
    targetPort: 50051
    name: grpc
---
# Redis
apiVersion: apps/v1 
kind: Deployment
metadata:
  name: redis-primary
  namespace: <NAMESPACE>
  labels:
    app: redis
spec:
  selector:
    matchLabels:
      app: redis
      role: primary
      tier: backend
  replicas: 1
  template:
    metadata:
      labels:
        csm: <NAME>
        app: redis
        role: primary
        tier: backend
    spec:
      containers:
      - name: primary
        image: <AUTHORIZATION_REDIS_IMAGE>
        imagePullPolicy: IfNotPresent
        args: ["--appendonly", "yes", "--appendfsync", "always"]
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        ports:
        - containerPort: 6379
        volumeMounts:
          - name: redis-primary-volume
            mountPath: /data
      volumes:
        - name: redis-primary-volume
          persistentVolumeClaim:
            claimName: redis-primary-pv-claim
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: redis-primary-pv-claim
  namespace: <NAMESPACE>
  labels:
    app: redis-primary
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: <REDIS_STORAGE_CLASS>
  resources:
    requests:
      storage: 8Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-commander
  namespace: <NAMESPACE>
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis-commander
  template:
    metadata:
      labels:
        csm: <NAME>
        app: redis-commander
        tier: backend
    spec:
      containers:
      - name: redis-commander
        image: <AUTHORIZATION_REDIS_COMMANDER_IMAGE>
        imagePullPolicy: IfNotPresent
        env:
        - name: REDIS_HOSTS
          value: "rbac:redis.<NAMESPACE>.svc.cluster.local:6379"
        - name: K8S_SIGTERM
          value: "1"
        ports:
        - name: redis-commander
          containerPort: 8081
        livenessProbe:
          httpGet:
            path: /favicon.png
            port: 8081
          initialDelaySeconds: 10
          timeoutSeconds: 5
        resources:
          limits:
            cpu: "500m"
            memory: "512M"
        securityContext:
          runAsNonRoot: true
          readOnlyRootFilesystem: false
          allowPrivilegeEscalation: false
          capabilities:
            drop:
              - ALL
---
apiVersion: v1
kind: Service
metadata:
  name: redis
  namespace: <NAMESPACE>
spec:
  selector:
    app: redis
  ports:
  - protocol: TCP
    port: 6379
    targetPort: 6379
---
apiVersion: v1
kind: Service
metadata:
  name: redis-commander
  namespace: <NAMESPACE>
spec:
  selector:
    app: redis-commander
  ports:
  - protocol: TCP
    port: 8081
    targetPort: 8081
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: auth-resource-reader
rules:
  - apiGroups: [""]
    resources: ["secrets", "configmaps", "pods"]
    verbs: ["get", "watch", "list", "patch", "create", "update", "delete"]
  - apiGroups: ["coordination.k8s.io"]
    resources: ["leases"]
    resourceNames: ["ingress-controller-leader"]
    verbs: ["get", "update"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: system:serviceaccounts:authorization
subjects:
  - kind: Group
    name: system:serviceaccounts:authorization
    namespace: <NAMESPACE>
roleRef:
  kind: ClusterRole
  name: auth-resource-reader
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: view
---
# Grant OPA/kube-mgmt read-only access to resources. This lets kube-mgmt
# list configmaps to be loaded into OPA as policies.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: opa-viewer
roleRef:
  kind: ClusterRole
  name: view
  apiGroup: rbac.authorization.k8s.io
subjects:
- kind: Group
  name: system:serviceaccounts:authorization
  apiGroup: rbac.authorization.k8s.io
---
# Define role for OPA/kube-mgmt to update configmaps with policy status.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: <NAMESPACE>
  name: configmap-modifier
rules:
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["update", "patch"]
---
# Grant OPA/kube-mgmt role defined above.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: <NAMESPACE>
  name: opa-configmap-modifier
roleRef:
  kind: Role
  name: configmap-modifier
  apiGroup: rbac.authorization.k8s.io
subjects:
- kind: Group
  name: system:serviceaccounts:authorization
  apiGroup: rbac.authorization.k8s.io