Jelajahi Sumber

Merge pull request #4195 from ewolinetz/service_catalog

Creation of service_catalog and broker roles
Scott Dodson 7 tahun lalu
induk
melakukan
b64cfec4eb
29 mengubah file dengan 1267 tambahan dan 0 penghapusan
  1. 12 0
      playbooks/byo/openshift-cluster/service-catalog.yml
  2. 6 0
      playbooks/common/openshift-cluster/config.yml
  3. 8 0
      playbooks/common/openshift-cluster/service_catalog.yml
  4. 6 0
      roles/ansible_service_broker/defaults/main.yml
  5. 15 0
      roles/ansible_service_broker/meta/main.yml
  6. 268 0
      roles/ansible_service_broker/tasks/install.yml
  7. 8 0
      roles/ansible_service_broker/tasks/main.yml
  8. 65 0
      roles/ansible_service_broker/tasks/remove.yml
  9. 15 0
      roles/ansible_service_broker/tasks/validate_facts.yml
  10. 13 0
      roles/ansible_service_broker/vars/default_images.yml
  11. 13 0
      roles/ansible_service_broker/vars/openshift-enterprise.yml
  12. 24 0
      roles/openshift_facts/library/openshift_facts.py
  13. 3 0
      roles/openshift_service_catalog/defaults/main.yml
  14. 161 0
      roles/openshift_service_catalog/files/kubeservicecatalog_roles_bindings.yml
  15. 38 0
      roles/openshift_service_catalog/files/kubesystem_roles_bindings.yml
  16. 17 0
      roles/openshift_service_catalog/meta/main.yml
  17. 70 0
      roles/openshift_service_catalog/tasks/generate_certs.yml
  18. 181 0
      roles/openshift_service_catalog/tasks/install.yml
  19. 8 0
      roles/openshift_service_catalog/tasks/main.yml
  20. 56 0
      roles/openshift_service_catalog/tasks/remove.yml
  21. 22 0
      roles/openshift_service_catalog/tasks/start_api_server.yml
  22. 86 0
      roles/openshift_service_catalog/tasks/wire_aggregator.yml
  23. 80 0
      roles/openshift_service_catalog/templates/api_server.j2
  24. 14 0
      roles/openshift_service_catalog/templates/api_server_route.j2
  25. 13 0
      roles/openshift_service_catalog/templates/api_server_service.j2
  26. 46 0
      roles/openshift_service_catalog/templates/controller_manager.j2
  27. 13 0
      roles/openshift_service_catalog/templates/controller_manager_service.j2
  28. 3 0
      roles/openshift_service_catalog/vars/default_images.yml
  29. 3 0
      roles/openshift_service_catalog/vars/openshift-enterprise.yml

+ 12 - 0
playbooks/byo/openshift-cluster/service-catalog.yml

@@ -0,0 +1,12 @@
+---
+#
+# This playbook is a preview of upcoming changes for installing
+# Hosted logging on.  See inventory/byo/hosts.*.example for the
+# currently supported method.
+#
+- include: initialize_groups.yml
+
+- include: ../../common/openshift-cluster/service_catalog.yml
+  vars:
+    openshift_cluster_id: "{{ cluster_id | default('default') }}"
+    openshift_debug_level: "{{ debug_level | default(2) }}"

+ 6 - 0
playbooks/common/openshift-cluster/config.yml

@@ -45,6 +45,12 @@
   tags:
   - hosted
 
+- include: service_catalog.yml
+  when:
+  - openshift_enable_service_catalog | default(false) | bool
+  tags:
+  - servicecatalog
+
 - name: Re-enable excluder if it was previously enabled
   hosts: oo_masters_to_config:oo_nodes_to_config
   tags:

+ 8 - 0
playbooks/common/openshift-cluster/service_catalog.yml

@@ -0,0 +1,8 @@
+---
+- include: evaluate_groups.yml
+
+- name: Service Catalog
+  hosts: oo_first_master
+  roles:
+  - openshift_service_catalog
+  - ansible_service_broker

+ 6 - 0
roles/ansible_service_broker/defaults/main.yml

@@ -0,0 +1,6 @@
+---
+
+ansible_service_broker_remove: false
+ansible_service_broker_log_level: info
+# Recommended you do not enable this for now
+ansible_service_broker_launch_apb_on_bind: false

+ 15 - 0
roles/ansible_service_broker/meta/main.yml

@@ -0,0 +1,15 @@
+---
+galaxy_info:
+  author: Fabian von Feilitzsch
+  description: OpenShift Ansible Service Broker
+  company: Red Hat, Inc.
+  license: Apache License, Version 2.0
+  min_ansible_version: 2.1
+  platforms:
+  - name: EL
+    versions:
+    - 7
+  categories:
+  - cloud
+dependencies:
+- role: lib_openshift

+ 268 - 0
roles/ansible_service_broker/tasks/install.yml

@@ -0,0 +1,268 @@
+---
+
+# 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_registry_type: "{{ ansible_service_broker_registry_type | default(__ansible_service_broker_registry_type) }}"
+    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) }}"
+
+- 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
+
+
+# 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 service
+  oc_service:
+    name: asb
+    namespace: openshift-ansible-service-broker
+    state: present
+    labels:
+      app: ansible-service-broker
+      service: asb
+    ports:
+      - name: port-1338
+        port: 1338
+    selector:
+      app: ansible-service-broker
+      service: asb
+
+- name: create etcd service
+  oc_service:
+    name: etcd
+    namespace: openshift-ansible-service-broker
+    state: present
+    ports:
+      - name: etcd-advertise
+        port: 2379
+    selector:
+      app: ansible-service-broker
+      service: etcd
+
+- name: create route for ansible-service-broker service
+  oc_route:
+    name: asb-1338
+    namespace: openshift-ansible-service-broker
+    state: present
+    service_name: asb
+    port: 1338
+  register: asb_route_out
+
+- name: get ansible-service-broker route name
+  set_fact:
+    ansible_service_broker_route: "{{ asb_route_out.results.results[0].spec.host }}"
+
+- name: create persistent volume claim for etcd
+  oc_obj:
+    name: etcd
+    namespace: openshift-ansible-service-broker
+    state: present
+    kind: PersistentVolumeClaim
+    content:
+      path: /tmp/dcout
+      data:
+        apiVersion: v1
+        kind: PersistentVolumeClaim
+        metadata:
+          name: etcd
+          namespace: openshift-ansible-service-broker
+        spec:
+          accessModes:
+            - ReadWriteOnce
+          resources:
+            requests:
+              storage: 1Gi
+
+- name: create etcd deployment
+  oc_obj:
+    name: etcd
+    namespace: openshift-ansible-service-broker
+    state: present
+    kind: Deployment
+    content:
+      path: /tmp/dcout
+      data:
+        apiVersion: extensions/v1beta1
+        kind: Deployment
+        metadata:
+          name: etcd
+          namespace: openshift-ansible-service-broker
+          labels:
+            app: ansible-service-broker
+            service: etcd
+        spec:
+          selector:
+            matchLabels:
+              app: ansible-service-broker
+              service: etcd
+          strategy:
+            type: RollingUpdate
+            rollingUpdate:
+              maxSurge: 1
+              maxUnavailable: 1
+          replicas: 1
+          template:
+            metadata:
+              labels:
+                app: ansible-service-broker
+                service: etcd
+            spec:
+              restartPolicy: Always
+              containers:
+                - image: "{{ ansible_service_broker_etcd_image }}"
+                  name: etcd
+                  imagePullPolicy: IfNotPresent
+                  terminationMessagePath: /tmp/termination-log
+                  workingDir: /etcd
+                  args:
+                    - /usr/local/bin/etcd
+                    - --data-dir=/data
+                    - --listen-client-urls="http://0.0.0.0:2379"
+                    - --advertise-client-urls="http://0.0.0.0:2379"
+                  ports:
+                    - containerPort: 2379
+                      protocol: TCP
+                  env:
+                    - name: ETCDCTL_API
+                      value: "3"
+                  volumeMounts:
+                    - mountPath: /data
+                      name: etcd
+              volumes:
+                - name: etcd
+                  persistentVolumeClaim:
+                    claimName: etcd
+
+- name: create ansible-service-broker deployment
+  oc_obj:
+    name: asb
+    namespace: openshift-ansible-service-broker
+    state: present
+    kind: Deployment
+    content:
+      path: /tmp/dcout
+      data:
+        apiVersion: extensions/v1beta1
+        kind: Deployment
+        metadata:
+          name: asb
+          namespace: openshift-ansible-service-broker
+          labels:
+            app: openshift-ansible-service-broker
+            service: asb
+        spec:
+          strategy:
+            type: Recreate
+          replicas: 1
+          template:
+            metadata:
+              labels:
+                app: openshift-ansible-service-broker
+                service: asb
+            spec:
+              serviceAccount: asb
+              restartPolicy: Always
+              containers:
+                - image: "{{ ansible_service_broker_image }}"
+                  name: asb
+                  imagePullPolicy: IfNotPresent
+                  volumeMounts:
+                    - name: config-volume
+                      mountPath: /etc/ansible-service-broker
+                  ports:
+                    - containerPort: 1338
+                      protocol: TCP
+                  env:
+                    - name: BROKER_CONFIG
+                      value: /etc/ansible-service-broker/config.yaml
+                  terminationMessagePath: /tmp/termination-log
+              volumes:
+                - name: config-volume
+                  configMap:
+                    name: broker-config
+                    items:
+                      - key: broker-config
+                        path: config.yaml
+
+
+# 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: ansible-service-broker
+        data:
+          broker-config: |
+            registry:
+              name: "{{ ansible_service_broker_registry_type }}"
+              url:  "{{ ansible_service_broker_registry_url }}"
+              user: "{{ ansible_service_broker_registry_user }}"
+              pass: "{{ ansible_service_broker_registry_password }}"
+              org:  "{{ ansible_service_broker_registry_organization }}"
+            dao:
+              etcd_host: etcd
+              etcd_port: 2379
+            log:
+              logfile: /var/log/ansible-service-broker/asb.log
+              stdout: true
+              level: "{{ ansible_service_broker_log_level }}"
+              color: true
+            openshift: {}
+            broker:
+              devbroker: false
+              launchapbonbind: "{{ ansible_service_broker_launch_apb_on_bind }}"
+
+- name: Create the Broker resource in the catalog
+  oc_obj:
+    name: ansible-service-broker
+    state: present
+    kind: Broker
+    content:
+      path: /tmp/brokerout
+      data:
+        apiVersion: servicecatalog.k8s.io/v1alpha1
+        kind: Broker
+        metadata:
+          name: ansible-service-broker
+        spec:
+          url: http://{{ ansible_service_broker_route }}

+ 8 - 0
roles/ansible_service_broker/tasks/main.yml

@@ -0,0 +1,8 @@
+---
+# do any asserts here
+
+- include: install.yml
+  when: not  ansible_service_broker_remove|default(false) | bool
+
+- include: remove.yml
+  when: ansible_service_broker_remove|default(false) | bool

+ 65 - 0
roles/ansible_service_broker/tasks/remove.yml

@@ -0,0 +1,65 @@
+---
+
+- name: remove openshift-ansible-service-broker project
+  oc_project:
+    name: openshift-ansible-service-broker
+    state: absent
+
+- name: remove ansible-service-broker serviceaccount
+  oc_serviceaccount:
+    name: asb
+    namespace: openshift-ansible-service-broker
+    state: absent
+
+- name: remove ansible-service-broker service
+  oc_service:
+    name: asb
+    namespace: openshift-ansible-service-broker
+    state: absent
+
+- name: remove etcd service
+  oc_service:
+    name: etcd
+    namespace: openshift-ansible-service-broker
+    state: absent
+
+- name: remove route for ansible-service-broker service
+  oc_route:
+    name: asb-1338
+    namespace: openshift-ansible-service-broker
+    state: absent
+
+- name: remove persistent volume claim for etcd
+  oc_pvc:
+    name: etcd
+    namespace: openshift-ansible-service-broker
+    state: absent
+
+- name: remove etcd deployment
+  oc_obj:
+    name: etcd
+    namespace: openshift-ansible-service-broker
+    state: absent
+    kind: Deployment
+
+- name: remove ansible-service-broker deployment
+  oc_obj:
+    name: asb
+    namespace: openshift-ansible-service-broker
+    state: absent
+    kind: Deployment
+
+# TODO: saw a oc_configmap in the library, but didn't understand how to get it to do the following:
+- name: remove config map for ansible-service-broker
+  oc_obj:
+    name: broker-config
+    namespace: openshift-ansible-service-broker
+    state: absent
+    kind: ConfigMap
+
+# TODO: Is this going to work?
+- name: remove broker object from the catalog
+  oc_obj:
+    name: ansible-service-broker
+    state: absent
+    kind: Broker

+ 15 - 0
roles/ansible_service_broker/tasks/validate_facts.yml

@@ -0,0 +1,15 @@
+---
+- name: validate Dockerhub registry settings
+  fail: msg="To use the dockerhub registry, you must provide the ansible_service_broker_registry_user. ansible_service_broker_registry_password, and ansible_service_broker_registry_organization parameters"
+  when:
+    - ansible_service_broker_registry_type == 'dockerhub'
+    - not (ansible_service_broker_registry_user and
+        ansible_service_broker_registry_password and
+        ansible_service_broker_registry_organization)
+
+
+- name: validate RHCC registry settings
+  fail: msg="To use the Red Hat Container Catalog registry, you must provide the ansible_service_broker_registry_url"
+  when:
+    - ansible_service_broker_registry_type == 'rhcc'
+    - not ansible_service_broker_registry_url

+ 13 - 0
roles/ansible_service_broker/vars/default_images.yml

@@ -0,0 +1,13 @@
+---
+
+__ansible_service_broker_image_prefix: ansibleplaybookbundle/
+__ansible_service_broker_image_tag: latest
+
+__ansible_service_broker_etcd_image_prefix: quay.io/coreos/
+__ansible_service_broker_etcd_image_tag: latest
+
+__ansible_service_broker_registry_type: dockerhub
+__ansible_service_broker_registry_url: null
+__ansible_service_broker_registry_user: null
+__ansible_service_broker_registry_password: null
+__ansible_service_broker_registry_organization: null

+ 13 - 0
roles/ansible_service_broker/vars/openshift-enterprise.yml

@@ -0,0 +1,13 @@
+---
+
+__ansible_service_broker_image_prefix: openshift3/
+__ansible_service_broker_image_tag: latest
+
+__ansible_service_broker_etcd_image_prefix: rhel7/
+__ansible_service_broker_etcd_image_tag: latest
+
+__ansible_service_broker_registry_type: rhcc
+__ansible_service_broker_registry_url: "https://registry.access.redhat.com"
+__ansible_service_broker_registry_user: null
+__ansible_service_broker_registry_password: null
+__ansible_service_broker_registry_organization: null

+ 24 - 0
roles/openshift_facts/library/openshift_facts.py

@@ -537,6 +537,7 @@ def set_node_schedulability(facts):
     return facts
 
 
+# pylint: disable=too-many-branches
 def set_selectors(facts):
     """ Set selectors facts if not already present in facts dict
         Args:
@@ -570,6 +571,10 @@ def set_selectors(facts):
         facts['hosted']['logging'] = {}
     if 'selector' not in facts['hosted']['logging'] or facts['hosted']['logging']['selector'] in [None, 'None']:
         facts['hosted']['logging']['selector'] = None
+    if 'etcd' not in facts['hosted']:
+        facts['hosted']['etcd'] = {}
+    if 'selector' not in facts['hosted']['etcd'] or facts['hosted']['etcd']['selector'] in [None, 'None']:
+        facts['hosted']['etcd']['selector'] = None
 
     return facts
 
@@ -2157,6 +2162,25 @@ class OpenShiftFacts(object):
                         create_pvc=False
                     )
                 ),
+                etcd=dict(
+                    storage=dict(
+                        kind=None,
+                        volume=dict(
+                            name='etcd',
+                            size='1Gi'
+                        ),
+                        nfs=dict(
+                            directory='/exports',
+                            options='*(rw,root_squash)'
+                        ),
+                        host=None,
+                        access=dict(
+                            modes=['ReadWriteOnce']
+                        ),
+                        create_pv=True,
+                        create_pvc=False
+                    )
+                ),
                 registry=dict(
                     storage=dict(
                         kind=None,

+ 3 - 0
roles/openshift_service_catalog/defaults/main.yml

@@ -0,0 +1,3 @@
+---
+openshift_service_catalog_remove: false
+openshift_service_catalog_nodeselector: {"openshift-infra": "apiserver"}

+ 161 - 0
roles/openshift_service_catalog/files/kubeservicecatalog_roles_bindings.yml

@@ -0,0 +1,161 @@
+apiVersion: v1
+kind: Template
+metadata:
+  name: service-catalog
+objects:
+
+- kind: ClusterRole
+  apiVersion: v1
+  metadata:
+    name: servicecatalog-serviceclass-viewer
+  rules:
+  - apiGroups:
+    - servicecatalog.k8s.io
+    resources:
+    - serviceclasses
+    verbs:
+    - list
+    - watch
+    - get
+
+- kind: ClusterRoleBinding
+  apiVersion: v1
+  metadata:
+    name: servicecatalog-serviceclass-viewer-binding
+  roleRef:
+    name: servicecatalog-serviceclass-viewer
+  groupNames:
+  - system:authenticated
+
+- kind: ServiceAccount
+  apiVersion: v1
+  metadata:
+    name: service-catalog-controller
+
+- kind: ServiceAccount
+  apiVersion: v1
+  metadata:
+    name: service-catalog-apiserver
+
+- kind: ClusterRole
+  apiVersion: v1
+  metadata:
+    name: sar-creator
+  rules:
+  - apiGroups:
+    - ""
+    resources:
+    - subjectaccessreviews.authorization.k8s.io
+    verbs:
+    - create
+
+- kind: ClusterRoleBinding
+  apiVersion: v1
+  metadata:
+    name: service-catalog-sar-creator-binding
+  roleRef:
+    name: sar-creator
+  userNames:
+    - system:serviceaccount:kube-service-catalog:service-catalog-apiserver
+
+- kind: ClusterRole
+  apiVersion: v1
+  metadata:
+    name: namespace-viewer
+  rules:
+  - apiGroups:
+    - ""
+    resources:
+    - namespaces
+    verbs:
+    - list
+    - watch
+    - get
+
+- kind: ClusterRoleBinding
+  apiVersion: v1
+  metadata:
+    name: service-catalog-namespace-viewer-binding
+  roleRef:
+    name: namespace-viewer
+  userNames:
+    - system:serviceaccount:kube-service-catalog:service-catalog-apiserver
+
+- kind: ClusterRoleBinding
+  apiVersion: v1
+  metadata:
+    name: service-catalog-controller-namespace-viewer-binding
+  roleRef:
+    name: namespace-viewer
+  userNames:
+    - system:serviceaccount:kube-service-catalog:service-catalog-controller
+
+- kind: ClusterRole
+  apiVersion: v1
+  metadata:
+    name: service-catalog-controller
+  rules:
+  - apiGroups:
+    - ""
+    resources:
+    - secrets
+    - podpresets
+    verbs:
+    - create
+    - update
+    - delete
+    - get
+    - list
+    - watch
+  - apiGroups:
+    - servicecatalog.k8s.io
+    resources:
+    - brokers/status
+    - instances/status
+    - bindings/status
+    verbs:
+    - update
+
+- kind: ClusterRoleBinding
+  apiVersion: v1
+  metadata:
+    name: service-catalog-controller-binding
+  roleRef:
+    name: service-catalog-controller
+  userNames:
+    - system:serviceaccount:kube-service-catalog:service-catalog-controller
+
+- kind: Role
+  apiVersion: v1
+  metadata:
+    name: endpoint-accessor
+  rules:
+  - apiGroups:
+    - ""
+    resources:
+    - endpoints
+    verbs:
+    - list
+    - watch
+    - get
+    - create
+    - update
+
+- kind: RoleBinding
+  apiVersion: v1
+  metadata:
+    name: endpoint-accessor-binding
+  roleRef:
+    name: endpoint-accessor
+    namespace: kube-service-catalog
+  userNames:
+    - system:serviceaccount:kube-service-catalog:service-catalog-controller
+
+- kind: ClusterRoleBinding
+  apiVersion: v1
+  metadata:
+    name: system:auth-delegator-binding
+  roleRef:
+    name: system:auth-delegator
+  userNames:
+    - system:serviceaccount:kube-service-catalog:service-catalog-apiserver

+ 38 - 0
roles/openshift_service_catalog/files/kubesystem_roles_bindings.yml

@@ -0,0 +1,38 @@
+apiVersion: v1
+kind: Template
+metadata:
+  name: kube-system-service-catalog
+objects:
+
+- kind: Role
+  apiVersion: v1
+  metadata:
+    name: extension-apiserver-authentication-reader
+    namespace: ${KUBE_SYSTEM_NAMESPACE}
+  rules:
+  - apiGroups:
+    - ""
+    resourceNames:
+    - extension-apiserver-authentication
+    resources:
+    - configmaps
+    verbs:
+    - get
+
+- kind: RoleBinding
+  apiVersion: v1
+  metadata:
+    name: extension-apiserver-authentication-reader-binding
+    namespace: ${KUBE_SYSTEM_NAMESPACE}
+  roleRef:
+    name: extension-apiserver-authentication-reader
+    namespace: kube-system
+  userNames:
+    - system:serviceaccount:kube-service-catalog:service-catalog-apiserver
+
+parameters:
+- description: Do not change this value.
+  displayName: Name of the kube-system namespace
+  name: KUBE_SYSTEM_NAMESPACE
+  required: true
+  value: kube-system

+ 17 - 0
roles/openshift_service_catalog/meta/main.yml

@@ -0,0 +1,17 @@
+---
+galaxy_info:
+  author: OpenShift Red Hat
+  description: OpenShift Service Catalog
+  company: Red Hat, Inc.
+  license: Apache License, Version 2.0
+  min_ansible_version: 2.2
+  platforms:
+  - name: EL
+    versions:
+    - 7
+  categories:
+  - cloud
+dependencies:
+- role: lib_openshift
+- role: openshift_facts
+- role: lib_utils

+ 70 - 0
roles/openshift_service_catalog/tasks/generate_certs.yml

@@ -0,0 +1,70 @@
+---
+- name: Create service catalog cert directory
+  file:
+    path: "{{ openshift.common.config_base }}/service-catalog"
+    state: directory
+    mode: 0755
+  changed_when: False
+  check_mode: no
+
+- set_fact:
+    generated_certs_dir: "{{ openshift.common.config_base }}/service-catalog"
+
+- name: Generate signing cert
+  command: >
+    {{ openshift.common.client_binary }} adm --config=/etc/origin/master/admin.kubeconfig ca create-signer-cert
+    --key={{ generated_certs_dir }}/ca.key --cert={{ generated_certs_dir }}/ca.crt
+    --serial={{ generated_certs_dir }}/apiserver.serial.txt --name=service-catalog-signer
+
+- name: Generating server keys
+  oc_adm_ca_server_cert:
+    cert: "{{ generated_certs_dir }}/apiserver.crt"
+    key: "{{ generated_certs_dir }}/apiserver.key"
+    hostnames: "apiserver.kube-service-catalog.svc,apiserver.kube-service-catalog.svc.cluster.local,apiserver.kube-service-catalog"
+    signer_cert: "{{ generated_certs_dir }}/ca.crt"
+    signer_key: "{{ generated_certs_dir }}/ca.key"
+    signer_serial: "{{ generated_certs_dir }}/apiserver.serial.txt"
+
+- name: Create apiserver-ssl secret
+  oc_secret:
+    state: present
+    name: apiserver-ssl
+    namespace: kube-service-catalog
+    files:
+    - name: tls.crt
+      path: "{{ generated_certs_dir }}/apiserver.crt"
+    - name: tls.key
+      path: "{{ generated_certs_dir }}/apiserver.key"
+
+- slurp:
+    src: "{{ generated_certs_dir }}/ca.crt"
+  register: apiserver_ca
+
+- shell: >
+    oc get apiservices.apiregistration.k8s.io/v1alpha1.servicecatalog.k8s.io -n kube-service-catalog || echo "not found"
+  register: get_apiservices
+  changed_when: no
+
+- name: Create api service
+  oc_obj:
+    state: present
+    name: v1alpha1.servicecatalog.k8s.io
+    kind: apiservices.apiregistration.k8s.io
+    namespace: "kube-service-catalog"
+    content:
+      path: /tmp/apisvcout
+      data:
+        apiVersion: apiregistration.k8s.io/v1beta1
+        kind: APIService
+        metadata:
+          name: v1alpha1.servicecatalog.k8s.io
+        spec:
+          group: servicecatalog.k8s.io
+          version: v1alpha1
+          service:
+            namespace: "kube-service-catalog"
+            name: apiserver
+          caBundle: "{{ apiserver_ca.content }}"
+          groupPriorityMinimum: 20
+          versionPriority: 10
+  when: "'not found' in get_apiservices.stdout"

+ 181 - 0
roles/openshift_service_catalog/tasks/install.yml

@@ -0,0 +1,181 @@
+---
+# do any asserts here
+
+- name: Create temp directory for doing work in
+  command: mktemp -d /tmp/openshift-service-catalog-ansible-XXXXXX
+  register: mktemp
+  changed_when: False
+
+
+- include: wire_aggregator.yml
+
+- 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 service_catalog image facts
+  set_fact:
+    openshift_service_catalog_image_prefix: "{{ openshift_service_catalog_image_prefix | default(__openshift_service_catalog_image_prefix) }}"
+    openshift_service_catalog_image_version: "{{ openshift_service_catalog_image_version | default(__openshift_service_catalog_image_version) }}"
+
+- name: Set Service Catalog namespace
+  oc_project:
+    state: present
+    name: "kube-service-catalog"
+#    node_selector: "{{ openshift_service_catalog_nodeselector | default(null) }}"
+
+- include: generate_certs.yml
+
+- copy:
+    src: kubeservicecatalog_roles_bindings.yml
+    dest: "{{ mktemp.stdout }}/kubeservicecatalog_roles_bindings.yml"
+
+- oc_obj:
+    name: service-catalog
+    kind: template
+    namespace: "kube-service-catalog"
+    files:
+      - "{{ mktemp.stdout }}/kubeservicecatalog_roles_bindings.yml"
+    delete_after: yes
+
+- oc_process:
+    create: True
+    template_name: service-catalog
+    namespace: "kube-service-catalog"
+
+- copy:
+    src: kubesystem_roles_bindings.yml
+    dest: "{{ mktemp.stdout }}/kubesystem_roles_bindings.yml"
+
+- oc_obj:
+    name: kube-system-service-catalog
+    kind: template
+    namespace: kube-system
+    files:
+      - "{{ mktemp.stdout }}/kubesystem_roles_bindings.yml"
+    delete_after: yes
+
+- oc_process:
+    create: True
+    template_name: kube-system-service-catalog
+    namespace: kube-system
+
+- shell: >
+    oc get policybindings/kube-system:default -n kube-system || echo "not found"
+  register: get_kube_system
+  changed_when: no
+
+- command: >
+    oc create policybinding kube-system -n kube-system
+  when: "'not found' in get_kube_system.stdout"
+
+- oc_adm_policy_user:
+    namespace: kube-service-catalog
+    resource_kind: scc
+    resource_name: hostmount-anyuid
+    state: present
+    user: "system:serviceaccount:kube-service-catalog:service-catalog-apiserver"
+
+- name: Set SA cluster-role
+  oc_adm_policy_user:
+    state: present
+    namespace: "kube-service-catalog"
+    resource_kind: cluster-role
+    resource_name: admin
+    user: "system:serviceaccount:kube-service-catalog:default"
+
+## api server
+- template:
+    src: api_server.j2
+    dest: "{{ mktemp.stdout }}/service_catalog_api_server.yml"
+  vars:
+    image: ""
+    namespace: ""
+    cpu_limit: none
+    memory_limit: none
+    cpu_requests: none
+    memory_request: none
+    cors_allowed_origin: localhost
+    node_selector: "{{ openshift_service_catalog_nodeselector | default ({'openshift-infra': 'apiserver'}) }}"
+
+- name: Set Service Catalog API Server daemonset
+  oc_obj:
+    state: present
+    namespace: "kube-service-catalog"
+    kind: daemonset
+    name: apiserver
+    files:
+      - "{{ mktemp.stdout }}/service_catalog_api_server.yml"
+    delete_after: yes
+
+- template:
+    src: api_server_service.j2
+    dest: "{{ mktemp.stdout }}/service_catalog_api_service.yml"
+
+- name: Set Service Catalog API Server service
+  oc_obj:
+    state: present
+    namespace: "kube-service-catalog"
+    kind: service
+    name: apiserver
+    files:
+      - "{{ mktemp.stdout }}/service_catalog_api_service.yml"
+    delete_after: yes
+
+- template:
+    src: api_server_route.j2
+    dest: "{{ mktemp.stdout }}/service_catalog_api_route.yml"
+
+- name: Set Service Catalog API Server route
+  oc_obj:
+    state: present
+    namespace: "kube-service-catalog"
+    kind: route
+    name: apiserver
+    files:
+      - "{{ mktemp.stdout }}/service_catalog_api_route.yml"
+    delete_after: yes
+
+## controller manager
+- template:
+    src: controller_manager.j2
+    dest: "{{ mktemp.stdout }}/controller_manager.yml"
+  vars:
+    image: ""
+    cpu_limit: none
+    memory_limit: none
+    node_selector: "{{ openshift_service_catalog_nodeselector | default ({'openshift-infra': 'apiserver'}) }}"
+
+- name: Set Controller Manager deployment
+  oc_obj:
+    state: present
+    namespace: "kube-service-catalog"
+    kind: daemonset
+    name: controller-manager
+    files:
+      - "{{ mktemp.stdout }}/controller_manager.yml"
+    delete_after: yes
+
+- template:
+    src: controller_manager_service.j2
+    dest: "{{ mktemp.stdout }}/controller_manager_service.yml"
+
+- name: Set Controller Manager service
+  oc_obj:
+    state: present
+    namespace: "kube-service-catalog"
+    kind: service
+    name: controller-manager
+    files:
+      - "{{ mktemp.stdout }}/controller_manager_service.yml"
+    delete_after: yes
+
+- include: start_api_server.yml
+
+- name: Delete temp directory
+  file:
+    name: "{{ mktemp.stdout }}"
+    state: absent
+  changed_when: False

+ 8 - 0
roles/openshift_service_catalog/tasks/main.yml

@@ -0,0 +1,8 @@
+---
+# do any asserts here
+
+- include: install.yml
+  when: not openshift_service_catalog_remove | default(false) | bool
+
+- include: remove.yml
+  when: openshift_service_catalog_remove | default(false) | bool

+ 56 - 0
roles/openshift_service_catalog/tasks/remove.yml

@@ -0,0 +1,56 @@
+---
+- name: Remove Service Catalog APIServer
+  command: >
+    oc delete apiservices.apiregistration.k8s.io/v1alpha1.servicecatalog.k8s.io --ignore-not-found -n kube-service-catalog
+
+- name: Remove Policy Binding
+  command: >
+    oc delete policybindings/kube-system:default -n kube-system --ignore-not-found
+
+# TODO: this module doesn't currently remove this
+#- name: Remove service catalog api service
+#  oc_obj:
+#    state: absent
+#    namespace: "kube-service-catalog"
+#    kind: apiservices.apiregistration.k8s.io
+#    name: v1alpha1.servicecatalog.k8s.io
+
+- name: Remove Service Catalog API Server route
+  oc_obj:
+    state: absent
+    namespace: "kube-service-catalog"
+    kind: route
+    name: apiserver
+
+- name: Remove Service Catalog API Server service
+  oc_obj:
+    state: absent
+    namespace: "kube-service-catalog"
+    kind: service
+    name: apiserver
+
+- name: Remove Service Catalog API Server daemonset
+  oc_obj:
+    state: absent
+    namespace: "kube-service-catalog"
+    kind: daemonset
+    name: apiserver
+
+- name: Remove Controller Manager service
+  oc_obj:
+    state: absent
+    namespace: "kube-service-catalog"
+    kind: service
+    name: controller-manager
+
+- name: Remove Controller Manager deployment
+  oc_obj:
+    state: absent
+    namespace: "kube-service-catalog"
+    kind: deployment
+    name: controller-manager
+
+- name: Remove Service Catalog namespace
+  oc_project:
+    state: absent
+    name: "kube-service-catalog"

+ 22 - 0
roles/openshift_service_catalog/tasks/start_api_server.yml

@@ -0,0 +1,22 @@
+---
+# Label nodes and wait for apiserver and controller to be running (at least one)
+- name: Label {{ openshift.node.nodename }} for APIServer and controller deployment
+  oc_label:
+    name: "{{ openshift.node.nodename }}"
+    kind: node
+    state: add
+    labels: "{{ openshift_service_catalog_nodeselector | default ({'openshift-infra': 'apiserver'}) | oo_dict_to_list_of_dict }}"
+
+# wait to see that the apiserver is available
+- name: wait for api server to be ready
+  command: >
+    curl -k https://apiserver.kube-service-catalog.svc/healthz
+  args:
+    # Disables the following warning:
+    # Consider using get_url or uri module rather than running curl
+    warn: no
+  register: api_health
+  until: api_health.stdout == 'ok'
+  retries: 120
+  delay: 1
+  changed_when: false

+ 86 - 0
roles/openshift_service_catalog/tasks/wire_aggregator.yml

@@ -0,0 +1,86 @@
+---
+# TODO: this currently has a bug where hostnames are required
+- name: Creating Aggregator signer certs
+  command: >
+    oc adm ca create-signer-cert
+    --cert=/etc/origin/master/front-proxy-ca.crt
+    --key=/etc/origin/master/front-proxy-ca.key
+    --serial=/etc/origin/master/ca.serial.txt
+#  oc_adm_ca_server_cert:
+#    cert: /etc/origin/master/front-proxy-ca.crt
+#    key: /etc/origin/master/front-proxy-ca.key
+
+- name: Create api-client config for Aggregator
+  command: >
+    oc adm create-api-client-config
+    --certificate-authority=/etc/origin/master/front-proxy-ca.crt
+    --signer-cert=/etc/origin/master/front-proxy-ca.crt
+    --signer-key=/etc/origin/master/front-proxy-ca.key
+    --user aggregator-front-proxy
+    --client-dir=/etc/origin/master
+    --signer-serial=/etc/origin/master/ca.serial.txt
+
+- name: Update master config
+  yedit:
+    state: present
+    src: /etc/origin/master/master-config.yaml
+    edits:
+    - key: aggregatorConfig.proxyClientInfo.certFile
+      value: aggregator-front-proxy.crt
+    - key: aggregatorConfig.proxyClientInfo.keyFile
+      value: aggregator-front-proxy.key
+    - key: authConfig.requestHeader.clientCA
+      value: front-proxy-ca.crt
+    - key: authConfig.requestHeader.clientCommonNames
+      value: [aggregator-front-proxy]
+    - key: authConfig.requestHeader.usernameHeaders
+      value: [X-Remote-User]
+    - key: authConfig.requestHeader.groupHeaders
+      value: [X-Remote-Group]
+    - key: authConfig.requestHeader.extraHeaderPrefixes
+      value: [X-Remote-Extra-]
+  register: yedit_output
+
+#restart master serially here
+- name: restart master
+  systemd: name={{ openshift.common.service_type }}-master state=restarted
+  when:
+  - yedit_output.changed
+  - openshift.master.ha is not defined or not openshift.master.ha | bool
+
+- name: restart master api
+  systemd: name={{ openshift.common.service_type }}-master-api state=restarted
+  when:
+  - yedit_output.changed
+  - openshift.master.ha is defined and openshift.master.ha | bool
+  - openshift.master.cluster_method == 'native'
+
+- name: restart master controllers
+  systemd: name={{ openshift.common.service_type }}-master-controllers state=restarted
+  when:
+  - yedit_output.changed
+  - openshift.master.ha is defined and openshift.master.ha | bool
+  - openshift.master.cluster_method == 'native'
+
+- name: Verify API Server
+  # Using curl here since the uri module requires python-httplib2 and
+  # wait_for port doesn't provide health information.
+  command: >
+    curl --silent --tlsv1.2
+    {% if openshift.common.version_gte_3_2_or_1_2 | bool %}
+    --cacert {{ openshift.common.config_base }}/master/ca-bundle.crt
+    {% else %}
+    --cacert {{ openshift.common.config_base }}/master/ca.crt
+    {% endif %}
+    {{ openshift.master.api_url }}/healthz/ready
+  args:
+    # Disables the following warning:
+    # Consider using get_url or uri module rather than running curl
+    warn: no
+  register: api_available_output
+  until: api_available_output.stdout == 'ok'
+  retries: 120
+  delay: 1
+  changed_when: false
+  when:
+  - yedit_output.changed

+ 80 - 0
roles/openshift_service_catalog/templates/api_server.j2

@@ -0,0 +1,80 @@
+apiVersion: extensions/v1beta1
+kind: DaemonSet
+metadata:
+  labels:
+    app: apiserver
+  name: apiserver
+spec:
+  selector:
+    matchLabels:
+      app: apiserver
+  updateStrategy:
+    rollingUpdate:
+      maxUnavailable: 1
+    type: RollingUpdate
+  template:
+    metadata:
+      labels:
+        app: apiserver
+    spec:
+      serviceAccountName: service-catalog-apiserver
+      nodeSelector:
+{% for key, value in node_selector.iteritems() %}
+          {{key}}: "{{value}}"
+{% endfor %}
+      containers:
+      - args:
+        - --storage-type
+        - etcd
+        - --secure-port
+        - "6443"
+        - --etcd-servers
+# TODO: come back and get openshift.common.hostname to work
+        - https://{{ openshift.common.ip }}:{{ openshift.master.etcd_port }}
+        - --etcd-cafile
+        - /etc/origin/master/master.etcd-ca.crt
+        - --etcd-certfile
+        - /etc/origin/master/master.etcd-client.crt
+        - --etcd-keyfile
+        - /etc/origin/master/master.etcd-client.key
+        - -v
+        - "10"
+        - --cors-allowed-origins
+        - {{ cors_allowed_origin }}
+        - --admission-control
+        - "KubernetesNamespaceLifecycle"
+        image: {{ openshift_service_catalog_image_prefix }}service-catalog:{{ openshift_service_catalog_image_version }}
+        command: ["/usr/bin/apiserver"]
+        imagePullPolicy: Always
+        name: apiserver
+        ports:
+        - containerPort: 6443
+          protocol: TCP
+        resources: {}
+        terminationMessagePath: /dev/termination-log
+        volumeMounts:
+        - mountPath: /var/run/kubernetes-service-catalog
+          name: apiserver-ssl
+          readOnly: true
+        - mountPath: /etc/origin/master
+          name: etcd-host-cert
+          readOnly: true
+      dnsPolicy: ClusterFirst
+      restartPolicy: Always
+      securityContext: {}
+      terminationGracePeriodSeconds: 30
+      volumes:
+      - name: apiserver-ssl
+        secret:
+          defaultMode: 420
+          secretName: apiserver-ssl
+          items:
+          - key: tls.crt
+            path: apiserver.crt
+          - key: tls.key
+            path: apiserver.key
+      - hostPath:
+          path: /etc/origin/master
+        name: etcd-host-cert
+      - emptyDir: {}
+        name: data-dir

+ 14 - 0
roles/openshift_service_catalog/templates/api_server_route.j2

@@ -0,0 +1,14 @@
+apiVersion: v1
+kind: Route
+metadata:
+  name: apiserver
+spec:
+  port:
+    targetPort: secure
+  tls:
+    termination: passthrough
+  to:
+    kind: Service
+    name: apiserver
+    weight: 100
+  wildcardPolicy: None

+ 13 - 0
roles/openshift_service_catalog/templates/api_server_service.j2

@@ -0,0 +1,13 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: apiserver
+spec:
+  ports:
+  - name: secure
+    port: 443
+    protocol: TCP
+    targetPort: 6443
+  selector:
+    app: apiserver
+  sessionAffinity: None

+ 46 - 0
roles/openshift_service_catalog/templates/controller_manager.j2

@@ -0,0 +1,46 @@
+apiVersion: extensions/v1beta1
+kind: DaemonSet
+metadata:
+  labels:
+    app: controller-manager
+  name: controller-manager
+spec:
+  selector:
+    matchLabels:
+      app: controller-manager
+  strategy:
+    rollingUpdate:
+      maxUnavailable: 1
+    type: RollingUpdate
+  template:
+    metadata:
+      labels:
+        app: controller-manager
+    spec:
+      nodeSelector:
+{% for key, value in node_selector.iteritems() %}
+        {{key}}: "{{value}}"
+{% endfor %}
+      containers:
+      - env:
+        - name: K8S_NAMESPACE
+          valueFrom:
+            fieldRef:
+              fieldPath: metadata.namespace
+        args:
+        - -v
+        - "5"
+        - "--leader-election-namespace=$(K8S_NAMESPACE)"
+        image: {{ openshift_service_catalog_image_prefix }}service-catalog:{{ openshift_service_catalog_image_version }}
+        command: ["/usr/bin/controller-manager"]
+        imagePullPolicy: Always
+        name: controller-manager
+        ports:
+        - containerPort: 8080
+          protocol: TCP
+        resources: {}
+        terminationMessagePath: /dev/termination-log
+      dnsPolicy: ClusterFirst
+      restartPolicy: Always
+      securityContext: {}
+      terminationGracePeriodSeconds: 30

+ 13 - 0
roles/openshift_service_catalog/templates/controller_manager_service.j2

@@ -0,0 +1,13 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: controller-manager
+spec:
+  ports:
+  - port: 6443
+    protocol: TCP
+    targetPort: 6443
+  selector:
+    app: controller-manager
+  sessionAffinity: None
+  type: ClusterIP

+ 3 - 0
roles/openshift_service_catalog/vars/default_images.yml

@@ -0,0 +1,3 @@
+---
+__openshift_service_catalog_image_prefix: "docker.io/openshift/origin-"
+__openshift_service_catalog_image_version: "latest"

+ 3 - 0
roles/openshift_service_catalog/vars/openshift-enterprise.yml

@@ -0,0 +1,3 @@
+---
+__openshift_service_catalog_image_prefix: "registry.access.redhat.com/openshift3/"
+__openshift_service_catalog_image_version: "3.6.0"