diff options
35 files changed, 1286 insertions, 6 deletions
diff --git a/playbooks/byo/openshift-cluster/service-catalog.yml b/playbooks/byo/openshift-cluster/service-catalog.yml new file mode 100644 index 000000000..a9fc18958 --- /dev/null +++ b/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) }}" diff --git a/playbooks/common/openshift-cluster/config.yml b/playbooks/common/openshift-cluster/config.yml index 1482b3a3f..2a75b8dc3 100644 --- a/playbooks/common/openshift-cluster/config.yml +++ b/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: diff --git a/playbooks/common/openshift-cluster/service_catalog.yml b/playbooks/common/openshift-cluster/service_catalog.yml new file mode 100644 index 000000000..c42e8781a --- /dev/null +++ b/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 diff --git a/roles/ansible_service_broker/defaults/main.yml b/roles/ansible_service_broker/defaults/main.yml new file mode 100644 index 000000000..4a7252679 --- /dev/null +++ b/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 diff --git a/roles/ansible_service_broker/meta/main.yml b/roles/ansible_service_broker/meta/main.yml new file mode 100644 index 000000000..ec4aafb79 --- /dev/null +++ b/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 diff --git a/roles/ansible_service_broker/tasks/install.yml b/roles/ansible_service_broker/tasks/install.yml new file mode 100644 index 000000000..b48583fd4 --- /dev/null +++ b/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 }} diff --git a/roles/ansible_service_broker/tasks/main.yml b/roles/ansible_service_broker/tasks/main.yml new file mode 100644 index 000000000..b46ce8233 --- /dev/null +++ b/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 diff --git a/roles/ansible_service_broker/tasks/remove.yml b/roles/ansible_service_broker/tasks/remove.yml new file mode 100644 index 000000000..2519f9f4c --- /dev/null +++ b/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 diff --git a/roles/ansible_service_broker/tasks/validate_facts.yml b/roles/ansible_service_broker/tasks/validate_facts.yml new file mode 100644 index 000000000..604d24e1d --- /dev/null +++ b/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 diff --git a/roles/ansible_service_broker/vars/default_images.yml b/roles/ansible_service_broker/vars/default_images.yml new file mode 100644 index 000000000..b0b3835e3 --- /dev/null +++ b/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 diff --git a/roles/ansible_service_broker/vars/openshift-enterprise.yml b/roles/ansible_service_broker/vars/openshift-enterprise.yml new file mode 100644 index 000000000..a6d999647 --- /dev/null +++ b/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 diff --git a/roles/openshift_facts/library/openshift_facts.py b/roles/openshift_facts/library/openshift_facts.py index 0788ddfb0..663423061 100755 --- a/roles/openshift_facts/library/openshift_facts.py +++ b/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, diff --git a/roles/openshift_logging_elasticsearch/tasks/main.yaml b/roles/openshift_logging_elasticsearch/tasks/main.yaml index 684dbe0a0..d9ac52cb7 100644 --- a/roles/openshift_logging_elasticsearch/tasks/main.yaml +++ b/roles/openshift_logging_elasticsearch/tasks/main.yaml @@ -194,7 +194,9 @@ - port: 9200 targetPort: "restapi" -- name: Creating ES storage template +# storageclasses are used by default but if static then disable +# storageclasses with the storageClassName set to "" in pvc.j2 +- name: Creating ES storage template - static template: src: pvc.j2 dest: "{{ tempdir }}/templates/logging-es-pvc.yml" @@ -203,11 +205,13 @@ size: "{{ openshift_logging_elasticsearch_pvc_size }}" access_modes: "{{ openshift_logging_elasticsearch_pvc_access_modes | list }}" pv_selector: "{{ openshift_logging_elasticsearch_pvc_pv_selector }}" + storage_class_name: "{{ openshift_logging_elasticsearch_pvc_storage_class_name | default('', true) }}" when: - openshift_logging_elasticsearch_storage_type == "pvc" - not openshift_logging_elasticsearch_pvc_dynamic -- name: Creating ES storage template +# Storageclasses are used by default if configured +- name: Creating ES storage template - dynamic template: src: pvc.j2 dest: "{{ tempdir }}/templates/logging-es-pvc.yml" @@ -216,8 +220,6 @@ size: "{{ openshift_logging_elasticsearch_pvc_size }}" access_modes: "{{ openshift_logging_elasticsearch_pvc_access_modes | list }}" pv_selector: "{{ openshift_logging_elasticsearch_pvc_pv_selector }}" - annotations: - volume.beta.kubernetes.io/storage-class: "dynamic" when: - openshift_logging_elasticsearch_storage_type == "pvc" - openshift_logging_elasticsearch_pvc_dynamic diff --git a/roles/openshift_logging_elasticsearch/templates/pvc.j2 b/roles/openshift_logging_elasticsearch/templates/pvc.j2 index f19a3a750..063f9c5ae 100644 --- a/roles/openshift_logging_elasticsearch/templates/pvc.j2 +++ b/roles/openshift_logging_elasticsearch/templates/pvc.j2 @@ -25,3 +25,6 @@ spec: resources: requests: storage: {{size}} +{% if storage_class_name is defined %} + storageClassName: {{ storage_class_name }} +{% endif %} diff --git a/roles/openshift_master/templates/native-cluster/atomic-openshift-master-api.j2 b/roles/openshift_master/templates/native-cluster/atomic-openshift-master-api.j2 index c484d23cc..c05a27559 100644 --- a/roles/openshift_master/templates/native-cluster/atomic-openshift-master-api.j2 +++ b/roles/openshift_master/templates/native-cluster/atomic-openshift-master-api.j2 @@ -1,5 +1,8 @@ OPTIONS=--loglevel={{ openshift.master.debug_level }} --listen={{ 'https' if openshift.master.api_use_ssl else 'http' }}://{{ openshift.master.bind_addr }}:{{ openshift.master.api_port }} --master={{ openshift.master.loopback_api_url }} CONFIG_FILE={{ openshift_master_config_file }} +{% if openshift_push_via_dns | default(false) %} +OPENSHIFT_DEFAULT_REGISTRY=docker-registry.default.svc:5000 +{% endif %} {% if openshift.common.is_containerized | bool %} IMAGE_VERSION={{ openshift_image_tag }} {% endif %} diff --git a/roles/openshift_master/templates/native-cluster/atomic-openshift-master-controllers.j2 b/roles/openshift_master/templates/native-cluster/atomic-openshift-master-controllers.j2 index e0adbbf52..a153fb33d 100644 --- a/roles/openshift_master/templates/native-cluster/atomic-openshift-master-controllers.j2 +++ b/roles/openshift_master/templates/native-cluster/atomic-openshift-master-controllers.j2 @@ -1,5 +1,8 @@ OPTIONS=--loglevel={{ openshift.master.debug_level }} --listen={{ 'https' if openshift.master.api_use_ssl else 'http' }}://{{ openshift.master.bind_addr }}:{{ openshift.master.controllers_port }} CONFIG_FILE={{ openshift_master_config_file }} +{% if openshift_push_via_dns | default(false) %} +OPENSHIFT_DEFAULT_REGISTRY=docker-registry.default.svc:5000 +{% endif %} {% if openshift.common.is_containerized | bool %} IMAGE_VERSION={{ openshift_image_tag }} {% endif %} diff --git a/roles/openshift_metrics/tasks/install_cassandra.yaml b/roles/openshift_metrics/tasks/install_cassandra.yaml index 62b7f52cb..7928a0346 100644 --- a/roles/openshift_metrics/tasks/install_cassandra.yaml +++ b/roles/openshift_metrics/tasks/install_cassandra.yaml @@ -36,6 +36,7 @@ access_modes: "{{ openshift_metrics_cassandra_pvc_access | list }}" size: "{{ openshift_metrics_cassandra_pvc_size }}" pv_selector: "{{ openshift_metrics_cassandra_pv_selector }}" + storage_class_name: "{{ openshift_metrics_cassanda_pvc_storage_class_name | default('', true) }}" with_sequence: count={{ openshift_metrics_cassandra_replicas }} when: - openshift_metrics_cassandra_storage_type != 'emptydir' @@ -50,8 +51,6 @@ obj_name: "{{ openshift_metrics_cassandra_pvc_prefix }}-{{ item }}" labels: metrics-infra: hawkular-cassandra - annotations: - volume.beta.kubernetes.io/storage-class: dynamic access_modes: "{{ openshift_metrics_cassandra_pvc_access | list }}" size: "{{ openshift_metrics_cassandra_pvc_size }}" pv_selector: "{{ openshift_metrics_cassandra_pv_selector }}" diff --git a/roles/openshift_metrics/templates/pvc.j2 b/roles/openshift_metrics/templates/pvc.j2 index 0b801b33f..b4e6a1503 100644 --- a/roles/openshift_metrics/templates/pvc.j2 +++ b/roles/openshift_metrics/templates/pvc.j2 @@ -32,3 +32,6 @@ spec: resources: requests: storage: {{size}} +{% if storage_class_name is defined %} + storageClassName: {{ storage_class_name }} +{% endif %} diff --git a/roles/openshift_service_catalog/defaults/main.yml b/roles/openshift_service_catalog/defaults/main.yml new file mode 100644 index 000000000..01ee2544d --- /dev/null +++ b/roles/openshift_service_catalog/defaults/main.yml @@ -0,0 +1,3 @@ +--- +openshift_service_catalog_remove: false +openshift_service_catalog_nodeselector: {"openshift-infra": "apiserver"} diff --git a/roles/openshift_service_catalog/files/kubeservicecatalog_roles_bindings.yml b/roles/openshift_service_catalog/files/kubeservicecatalog_roles_bindings.yml new file mode 100644 index 000000000..880146ca4 --- /dev/null +++ b/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 diff --git a/roles/openshift_service_catalog/files/kubesystem_roles_bindings.yml b/roles/openshift_service_catalog/files/kubesystem_roles_bindings.yml new file mode 100644 index 000000000..f6ee0955d --- /dev/null +++ b/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 diff --git a/roles/openshift_service_catalog/meta/main.yml b/roles/openshift_service_catalog/meta/main.yml new file mode 100644 index 000000000..1e6b837cd --- /dev/null +++ b/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 diff --git a/roles/openshift_service_catalog/tasks/generate_certs.yml b/roles/openshift_service_catalog/tasks/generate_certs.yml new file mode 100644 index 000000000..cc897b032 --- /dev/null +++ b/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" diff --git a/roles/openshift_service_catalog/tasks/install.yml b/roles/openshift_service_catalog/tasks/install.yml new file mode 100644 index 000000000..c1773b5f6 --- /dev/null +++ b/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 diff --git a/roles/openshift_service_catalog/tasks/main.yml b/roles/openshift_service_catalog/tasks/main.yml new file mode 100644 index 000000000..dc0d6a370 --- /dev/null +++ b/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 diff --git a/roles/openshift_service_catalog/tasks/remove.yml b/roles/openshift_service_catalog/tasks/remove.yml new file mode 100644 index 000000000..2fb1ec440 --- /dev/null +++ b/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" diff --git a/roles/openshift_service_catalog/tasks/start_api_server.yml b/roles/openshift_service_catalog/tasks/start_api_server.yml new file mode 100644 index 000000000..b143292b6 --- /dev/null +++ b/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 diff --git a/roles/openshift_service_catalog/tasks/wire_aggregator.yml b/roles/openshift_service_catalog/tasks/wire_aggregator.yml new file mode 100644 index 000000000..3e5897ba4 --- /dev/null +++ b/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 diff --git a/roles/openshift_service_catalog/templates/api_server.j2 b/roles/openshift_service_catalog/templates/api_server.j2 new file mode 100644 index 000000000..8ae6b6c8d --- /dev/null +++ b/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 diff --git a/roles/openshift_service_catalog/templates/api_server_route.j2 b/roles/openshift_service_catalog/templates/api_server_route.j2 new file mode 100644 index 000000000..3c3da254d --- /dev/null +++ b/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 diff --git a/roles/openshift_service_catalog/templates/api_server_service.j2 b/roles/openshift_service_catalog/templates/api_server_service.j2 new file mode 100644 index 000000000..bae337201 --- /dev/null +++ b/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 diff --git a/roles/openshift_service_catalog/templates/controller_manager.j2 b/roles/openshift_service_catalog/templates/controller_manager.j2 new file mode 100644 index 000000000..33932eeb7 --- /dev/null +++ b/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 diff --git a/roles/openshift_service_catalog/templates/controller_manager_service.j2 b/roles/openshift_service_catalog/templates/controller_manager_service.j2 new file mode 100644 index 000000000..2bac645fc --- /dev/null +++ b/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 diff --git a/roles/openshift_service_catalog/vars/default_images.yml b/roles/openshift_service_catalog/vars/default_images.yml new file mode 100644 index 000000000..6fb9d1b86 --- /dev/null +++ b/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" diff --git a/roles/openshift_service_catalog/vars/openshift-enterprise.yml b/roles/openshift_service_catalog/vars/openshift-enterprise.yml new file mode 100644 index 000000000..8c3f14485 --- /dev/null +++ b/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" |