---

# Fact setting and validations
- name: Set default image variables based on deployment type
  include_vars: "{{ item }}"
  with_first_found:
    - "{{ openshift_deployment_type | default(deployment_type) }}.yml"
    - "default_images.yml"

- name: set ansible_service_broker facts
  set_fact:
    ansible_service_broker_image_prefix: "{{ ansible_service_broker_image_prefix | default(__ansible_service_broker_image_prefix) }}"
    ansible_service_broker_image_tag: "{{ ansible_service_broker_image_tag | default(__ansible_service_broker_image_tag) }}"

    ansible_service_broker_etcd_image_prefix: "{{ ansible_service_broker_etcd_image_prefix | default(__ansible_service_broker_etcd_image_prefix) }}"
    ansible_service_broker_etcd_image_tag: "{{ ansible_service_broker_etcd_image_tag | default(__ansible_service_broker_etcd_image_tag) }}"
    ansible_service_broker_etcd_image_etcd_path: "{{ ansible_service_broker_etcd_image_etcd_path | default(__ansible_service_broker_etcd_image_etcd_path) }}"

    ansible_service_broker_registry_type: "{{ ansible_service_broker_registry_type | default(__ansible_service_broker_registry_type) }}"
    ansible_service_broker_registry_name: "{{ ansible_service_broker_registry_name | default(__ansible_service_broker_registry_name) }}"
    ansible_service_broker_registry_url: "{{ ansible_service_broker_registry_url | default(__ansible_service_broker_registry_url) }}"
    ansible_service_broker_registry_user: "{{ ansible_service_broker_registry_user | default(__ansible_service_broker_registry_user) }}"
    ansible_service_broker_registry_password: "{{ ansible_service_broker_registry_password | default(__ansible_service_broker_registry_password) }}"
    ansible_service_broker_registry_organization: "{{ ansible_service_broker_registry_organization | default(__ansible_service_broker_registry_organization) }}"
    ansible_service_broker_registry_tag: "{{ ansible_service_broker_registry_tag | default(__ansible_service_broker_registry_tag) }}"
    ansible_service_broker_registry_whitelist: "{{ ansible_service_broker_registry_whitelist | default(__ansible_service_broker_registry_whitelist) }}"

- name: set ansible-service-broker image facts using set prefix and tag
  set_fact:
    ansible_service_broker_image: "{{ ansible_service_broker_image_prefix }}ansible-service-broker:{{ ansible_service_broker_image_tag }}"
    ansible_service_broker_etcd_image: "{{ ansible_service_broker_etcd_image_prefix }}etcd:{{ ansible_service_broker_etcd_image_tag }}"

- include: validate_facts.yml

- include: generate_certs.yml

# Deployment of ansible-service-broker starts here
- name: create openshift-ansible-service-broker project
  oc_project:
    name: openshift-ansible-service-broker
    state: present

- name: create ansible-service-broker serviceaccount
  oc_serviceaccount:
    name: asb
    namespace: openshift-ansible-service-broker
    state: present

- name: create ansible-service-broker client serviceaccount
  oc_serviceaccount:
    name: asb-client
    namespace: openshift-ansible-service-broker
    state: present

- name: Create asb-auth cluster role
  oc_clusterrole:
    state: present
    name: asb-auth
    rules:
      - apiGroups: [""]
        resources: ["namespaces"]
        verbs: ["create", "delete"]
      - apiGroups: ["authorization.openshift.io"]
        resources: ["subjectrulesreview"]
        verbs: ["create"]
      - apiGroups: ["authorization.k8s.io"]
        resources: ["subjectaccessreviews"]
        verbs: ["create"]
      - apiGroups: ["authentication.k8s.io"]
        resources: ["tokenreviews"]
        verbs: ["create"]
      - apiGroups: ["image.openshift.io", ""]
        resources: ["images"]
        verbs: ["get", "list"]

- name: Create asb-access cluster role
  oc_clusterrole:
    state: present
    name: asb-access
    rules:
      - nonResourceURLs: ["/ansible-service-broker", "/ansible-service-broker/*"]
        verbs: ["get", "post", "put", "patch", "delete"]

- name: Bind admin cluster-role to asb serviceaccount
  oc_adm_policy_user:
    state: present
    resource_kind: cluster-role
    resource_name: admin
    user: "system:serviceaccount:openshift-ansible-service-broker:asb"

- name: Bind auth cluster role to asb service account
  oc_adm_policy_user:
    state: present
    resource_kind: cluster-role
    resource_name: asb-auth
    user: "system:serviceaccount:openshift-ansible-service-broker:asb"

- name: Bind asb-access role to asb-client service account
  oc_adm_policy_user:
    state: present
    resource_kind: cluster-role
    resource_name: asb-access
    user: "system:serviceaccount:openshift-ansible-service-broker:asb-client"

- name: create asb-client token secret
  oc_obj:
    name: asb-client
    namespace: openshift-ansible-service-broker
    state: present
    kind: Secret
    content:
      path: /tmp/asbclientsecretout
      data:
        apiVersion: v1
        kind: Secret
        metadata:
          name: asb-client
          namespace: openshift-ansible-service-broker
          annotations:
            kubernetes.io/service-account.name: asb-client
        type: kubernetes.io/service-account-token

- name: Create etcd-auth secret
  oc_secret:
    name: etcd-auth-secret
    namespace: openshift-ansible-service-broker
    contents:
      - path: ca.crt
        data: '{{ etcd_ca_cert }}'

- name: Create broker-etcd-auth secret
  oc_secret:
    name: broker-etcd-auth-secret
    namespace: openshift-ansible-service-broker
    contents:
      - path: client.crt
        data: '{{ etcd_client_cert }}'
      - path: client.key
        data: '{{ etcd_client_key }}'

- oc_secret:
    state: list
    namespace: openshift-ansible-service-broker
    name: asb-client
  register: asb_client_secret

- set_fact:
    service_ca_crt: "{{ asb_client_secret.results.results.0.data['service-ca.crt'] }}"

# Using oc_obj because oc_service doesn't seem to allow annotations
# TODO: Extend oc_service to allow annotations
- name: create ansible-service-broker service
  oc_obj:
    name: asb
    namespace: openshift-ansible-service-broker
    state: present
    kind: Service
    content:
      path: /tmp/asbsvcout
      data:
        apiVersion: v1
        kind: Service
        metadata:
          name: asb
          namespace: openshift-ansible-service-broker
          labels:
            app: openshift-ansible-service-broker
            service: asb
          annotations:
            service.alpha.openshift.io/serving-cert-secret-name: asb-tls
        spec:
          ports:
            - name: port-1338
              port: 1338
              targetPort: 1338
              protocol: TCP
          selector:
            app: openshift-ansible-service-broker
            service: asb

- name: create asb-etcd service
  oc_obj:
    name: asb-etcd
    namespace: openshift-ansible-service-broker
    state: present
    kind: Service
    content:
      path: /tmp/asbetcdsvcout
      data:
        apiVersion: v1
        kind: Service
        metadata:
          name: asb-etcd
          labels:
            app: etcd
            service: asb-etcd
          annotations:
            service.alpha.openshift.io/serving-cert-secret-name: etcd-tls
        spec:
          ports:
            - name: port-2379
              port: 2379
              targetPort: 2379
              protocol: TCP
          selector:
            app: etcd
            service: asb-etcd

- name: create route for ansible-service-broker service
  oc_route:
    name: asb-1338
    namespace: openshift-ansible-service-broker
    state: present
    labels:
      app: openshift-ansible-service-broker
      service: asb
    service_name: asb
    port: 1338
    tls_termination: Reencrypt

- name: create persistent volume claim for etcd
  oc_obj:
    name: etcd
    namespace: openshift-ansible-service-broker
    state: present
    kind: PersistentVolumeClaim
    content:
      path: /tmp/pvcout
      data:
        apiVersion: v1
        kind: PersistentVolumeClaim
        metadata:
          name: etcd
          namespace: openshift-ansible-service-broker
        spec:
          accessModes:
            - ReadWriteOnce
          resources:
            requests:
              storage: 1Gi

- name: Create Ansible Service Broker deployment config
  oc_obj:
    name: asb
    namespace: openshift-ansible-service-broker
    state: present
    kind: DeploymentConfig
    content:
      path: /tmp/dcout
      data:
        apiVersion: v1
        kind: DeploymentConfig
        metadata:
          name: asb
          labels:
            app: openshift-ansible-service-broker
            service: asb
        spec:
          replicas: 1
          selector:
            app: openshift-ansible-service-broker
          strategy:
            type: Rolling
          template:
            metadata:
              labels:
                app: openshift-ansible-service-broker
                service: asb
            spec:
              serviceAccount: asb
              containers:
                - image: "{{ ansible_service_broker_image }}"
                  name: asb
                  imagePullPolicy: IfNotPresent
                  volumeMounts:
                    - name: config-volume
                      mountPath: /etc/ansible-service-broker
                    - name: asb-tls
                      mountPath: /etc/tls/private
                    - name: asb-etcd-auth
                      mountPath: /var/run/asb-etcd-auth
                  ports:
                    - containerPort: 1338
                      protocol: TCP
                  env:
                    - name: BROKER_CONFIG
                      value: /etc/ansible-service-broker/config.yaml
                  resources: {}
                  terminationMessagePath: /tmp/termination-log
                  readinessProbe:
                    httpGet:
                      port: 1338
                      path: /healthz
                      scheme: HTTPS
                    initialDelaySeconds: 15
                    timeoutSeconds: 1
                  livenessProbe:
                    httpGet:
                      port: 1338
                      path: /healthz
                      scheme: HTTPS
                    initialDelaySeconds: 15
                    timeoutSeconds: 1
              volumes:
                - name: config-volume
                  configMap:
                    name: broker-config
                    items:
                      - key: broker-config
                        path: config.yaml
                - name: asb-tls
                  secret:
                    secretName: asb-tls
                - name: asb-etcd-auth
                  secret:
                    secretName: broker-etcd-auth-secret

- name: Create asb-etcd deployment config
  oc_obj:
    name: etcd
    namespace: openshift-ansible-service-broker
    state: present
    kind: DeploymentConfig
    content:
      path: /tmp/dcout
      data:
        apiVersion: v1
        kind: DeploymentConfig
        metadata:
          name: asb-etcd
          labels:
            app: etcd
            service: asb-etcd
        spec:
          replicas: 1
          selector:
            app: etcd
          strategy:
            type: Rolling
          template:
            metadata:
              labels:
                app: etcd
                service: asb-etcd
            spec:
              serviceAccount: asb
              containers:
                - image: "{{ ansible_service_broker_etcd_image }}"
                  name: etcd
                  imagePullPolicy: IfNotPresent
                  terminationMessagePath: /tmp/termination-log
                  workingDir: /etcd
                  args:
                    - "{{ ansible_service_broker_etcd_image_etcd_path }}"
                    - "--data-dir=/data"
                    - "--listen-client-urls=https://0.0.0.0:2379"
                    - "--advertise-client-urls=https://0.0.0.0:2379"
                    - "--client-cert-auth"
                    - "--trusted-ca-file=/var/run/etcd-auth-secret/ca.crt"
                    - "--cert-file=/etc/tls/private/tls.crt"
                    - "--key-file=/etc/tls/private/tls.key"
                  ports:
                    - containerPort: 2379
                      protocol: TCP
                  env:
                    - name: ETCDCTL_API
                      value: "3"
                  volumeMounts:
                    - name: etcd
                      mountPath: /data
                    - name: etcd-tls
                      mountPath: /etc/tls/private
                    - name: etcd-auth
                      mountPath: /var/run/etcd-auth-secret
              volumes:
                - name: etcd
                  persistentVolumeClaim:
                    claimName: etcd
                - name: etcd-tls
                  secret:
                    secretName: etcd-tls
                - name: etcd-auth
                  secret:
                    secretName: etcd-auth-secret


# TODO: saw a oc_configmap in the library, but didn't understand how to get it to do the following:
- name: Create config map for ansible-service-broker
  oc_obj:
    name: broker-config
    namespace: openshift-ansible-service-broker
    state: present
    kind: ConfigMap
    content:
      path: /tmp/cmout
      data:
        apiVersion: v1
        kind: ConfigMap
        metadata:
          name: broker-config
          namespace: openshift-ansible-service-broker
          labels:
            app: openshift-ansible-service-broker
        data:
          broker-config: |
            registry:
              - type: {{ ansible_service_broker_registry_type }}
                name: {{ ansible_service_broker_registry_name }}
                url:  {{ ansible_service_broker_registry_url }}
                org:  {{ ansible_service_broker_registry_organization }}
                tag:  {{ ansible_service_broker_registry_tag }}
                white_list: {{  ansible_service_broker_registry_whitelist | to_yaml }}
              - type: local_openshift
                name: localregistry
                namespaces: ['openshift']
                white_list: {{ ansible_service_broker_local_registry_whitelist | to_yaml }}
            dao:
              etcd_host: asb-etcd.openshift-ansible-service-broker.svc
              etcd_port: 2379
              etcd_ca_file: /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt
              etcd_client_cert: /var/run/asb-etcd-auth/client.crt
              etcd_client_key: /var/run/asb-etcd-auth/client.key
            log:
              stdout: true
              level: {{ ansible_service_broker_log_level }}
              color: true
            openshift:
              host: ""
              ca_file: ""
              bearer_token_file: ""
              sandbox_role: {{ ansible_service_broker_sandbox_role }}
              image_pull_policy: {{ ansible_service_broker_image_pull_policy }}
              keep_namespace: {{ ansible_service_broker_keep_namespace | bool | lower }}
              keep_namespace_on_error: {{ ansible_service_broker_keep_namespace_on_error | bool | lower }}
            broker:
              dev_broker: {{ ansible_service_broker_dev_broker | bool | lower }}
              bootstrap_on_startup: {{ ansible_service_broker_bootstrap_on_startup | bool | lower }}
              refresh_interval: {{ ansible_service_broker_refresh_interval }}
              launch_apb_on_bind: {{ ansible_service_broker_launch_apb_on_bind | bool | lower }}
              output_request: {{ ansible_service_broker_output_request | bool | lower }}
              recovery: {{ ansible_service_broker_recovery | bool | lower }}
              ssl_cert_key: /etc/tls/private/tls.key
              ssl_cert: /etc/tls/private/tls.crt
              auto_escalate: {{ ansible_service_broker_auto_escalate }}
              auth:
                - type: basic
                  enabled: false

- oc_secret:
    name: asb-registry-auth
    namespace: openshift-ansible-service-broker
    state: present
    contents:
      - path: username
        data: "{{ ansible_service_broker_registry_user }}"
      - path: password
        data: "{{ ansible_service_broker_registry_password }}"

- name: Create the Broker resource in the catalog
  oc_obj:
    name: ansible-service-broker
    state: present
    kind: ClusterServiceBroker
    content:
      path: /tmp/brokerout
      data:
        apiVersion: servicecatalog.k8s.io/v1beta1
        kind: ClusterServiceBroker
        metadata:
          name: ansible-service-broker
        spec:
          url: https://asb.openshift-ansible-service-broker.svc:1338/ansible-service-broker
          authInfo:
            bearer:
              secretRef:
                name: asb-client
                namespace: openshift-ansible-service-broker
                kind: Secret
          caBundle: "{{ service_ca_crt }}"
