|
@@ -46,86 +46,8 @@
|
|
|
# (this last one is because roxctl creates a cluster record but leaves its status at null until services check in)
|
|
|
|
|
|
# step 1: we could have lots of fun (authentication in place)
|
|
|
-- block:
|
|
|
-
|
|
|
- - name: init bundle check
|
|
|
- uri:
|
|
|
- method: GET
|
|
|
- return_content: true
|
|
|
- validate_certs: false
|
|
|
- url: "https://{{ api_ep }}/v1/cluster-init/init-bundles"
|
|
|
- headers:
|
|
|
- Authorization: Bearer {{ api_token }}
|
|
|
- Accept: application/json
|
|
|
- register: init_bundle_response
|
|
|
-
|
|
|
- - name: assume init bundle isn't there
|
|
|
- set_fact:
|
|
|
- init_bundle_present: false
|
|
|
-
|
|
|
- - name: unless found
|
|
|
- set_fact:
|
|
|
- init_bundle_present: true
|
|
|
- when:
|
|
|
- - init_bundle_response.json['items'] | length > 0
|
|
|
- - (init_bundle_response.json['items'] | items2dict(key_name='name', value_name='expiresAt'))[clusters[cluster].name] is defined
|
|
|
-
|
|
|
- - name: generate init bundle
|
|
|
- uri:
|
|
|
- method: POST
|
|
|
- return_content: true
|
|
|
- validate_certs: false
|
|
|
- url: "https://{{ api_ep }}/v1/cluster-init/init-bundles"
|
|
|
- headers:
|
|
|
- Authorization: Bearer {{ api_token }}
|
|
|
- Accept: application/json
|
|
|
- Content-Type: application/json
|
|
|
- body: '{"name":"{{ clusters[cluster].name | string }}"}'
|
|
|
- register: init_bundle_content
|
|
|
- when:
|
|
|
- - not init_bundle_present
|
|
|
-
|
|
|
- - name: store init bundle - operator
|
|
|
- copy:
|
|
|
- dest: "{{ ansible_facts['user_dir'] }}/{{ cluster }}-init-bundle.yaml"
|
|
|
- content: "{{ init_bundle_content.json.kubectlBundle | b64decode }}"
|
|
|
- owner: "{{ ansible_user }}"
|
|
|
- group: "{{ ansible_user }}"
|
|
|
- mode: 0600
|
|
|
- when:
|
|
|
- - not init_bundle_present
|
|
|
- - clusters[cluster].method == 'operator'
|
|
|
-
|
|
|
- - name: store init bundle - helm
|
|
|
- copy:
|
|
|
- dest: "{{ ansible_facts['user_dir'] }}/{{ cluster }}-helm-bundle.yaml"
|
|
|
- content: "{{ init_bundle_content.json.helmValuesBundle | b64decode }}"
|
|
|
- owner: "{{ ansible_user }}"
|
|
|
- group: "{{ ansible_user }}"
|
|
|
- mode: 0600
|
|
|
- when:
|
|
|
- - not init_bundle_present
|
|
|
- - clusters[cluster].method == 'helm'
|
|
|
-
|
|
|
- - name: make sure namespace is there
|
|
|
- kubernetes.core.k8s:
|
|
|
- kubeconfig: "{{ ansible_facts['user_dir'] }}/kubeconfig-{{ cluster }}"
|
|
|
- validate_certs: no
|
|
|
- api_version: v1
|
|
|
- kind: Namespace
|
|
|
- name: "{{ clusters[cluster].namespace }}"
|
|
|
- namespace: ""
|
|
|
- state: present
|
|
|
-
|
|
|
- - name: create init bundle
|
|
|
- kubernetes.core.k8s:
|
|
|
- kubeconfig: "{{ ansible_facts['user_dir'] }}/kubeconfig-{{ cluster }}"
|
|
|
- validate_certs: no
|
|
|
- src: "{{ ansible_facts['user_dir'] }}/{{ cluster }}-init-bundle.yaml"
|
|
|
- namespace: "{{ clusters[cluster].namespace }}"
|
|
|
- when:
|
|
|
- - clusters[cluster].method == 'operator'
|
|
|
-
|
|
|
+- include_tasks:
|
|
|
+ file: init-bundles.yml
|
|
|
when:
|
|
|
- clusters[cluster].method in ['operator', 'helm']
|
|
|
- not cluster_found
|
|
@@ -133,177 +55,9 @@
|
|
|
# no init bundles for method 'roxctl'
|
|
|
|
|
|
# step 2: there's so much we can do (not really, just make sure artifacts are either present or created)
|
|
|
-
|
|
|
-# operator has its securedcluster resource
|
|
|
-- block:
|
|
|
- - name: securedcluster cr check
|
|
|
- k8s_info:
|
|
|
- kubeconfig: "{{ ansible_facts['user_dir'] }}/kubeconfig-{{ cluster }}"
|
|
|
- validate_certs: no
|
|
|
- api_version: platform.stackrox.io/v1alpha1
|
|
|
- kind: SecuredCluster
|
|
|
- namespace: "{{ clusters[cluster].namespace }}"
|
|
|
- name: "{{ clusters[cluster].name }}"
|
|
|
- register: secured_cr
|
|
|
-
|
|
|
- - name: create cr resource
|
|
|
- kubernetes.core.k8s:
|
|
|
- kubeconfig: "{{ ansible_facts['user_dir'] }}/kubeconfig-{{ cluster }}"
|
|
|
- validate_certs: no
|
|
|
- template: templates/securedcluster-cr.yml
|
|
|
- when: secured_cr.resources | length == 0
|
|
|
-
|
|
|
- when:
|
|
|
- - clusters[cluster].method == 'operator'
|
|
|
- - not cluster_found
|
|
|
-
|
|
|
-# roxctl doesn't really leave any specific signature, so check for sensor.sh
|
|
|
-- block:
|
|
|
- - name: sensor.sh check
|
|
|
- stat:
|
|
|
- path: "{{ ansible_facts['user_dir'] }}/{{ cluster }}-secured/sensor.sh"
|
|
|
- register: sensor_script_present
|
|
|
-
|
|
|
- - name: check for deployments anyway as well
|
|
|
- k8s_info:
|
|
|
- kubeconfig: "{{ ansible_facts['user_dir'] }}/kubeconfig-{{ cluster }}"
|
|
|
- validate_certs: no
|
|
|
- api_version: apps/v1
|
|
|
- kind: deployment
|
|
|
- namespace: "{{ clusters[cluster].namespace }}"
|
|
|
- label_selectors:
|
|
|
- - app.kubernetes.io/instance=stackrox-secured-cluster-services
|
|
|
- register: sensor_deployments_present
|
|
|
-
|
|
|
- - name: create sensor.sh resources
|
|
|
- ansible.builtin.command:
|
|
|
- argv:
|
|
|
- - /usr/local/bin/roxctl
|
|
|
- - -e
|
|
|
- - "{{ api_ep }}"
|
|
|
- - --token-file={{ ansible_facts['user_dir'] }}/api-token
|
|
|
- - sensor
|
|
|
- - generate
|
|
|
- - openshift
|
|
|
- - --openshift-version=4
|
|
|
- - --admission-controller-scan-inline=true
|
|
|
- - --admission-controller-timeout=10
|
|
|
- - --admission-controller-listen-on-events
|
|
|
- - --admission-controller-listen-on-creates
|
|
|
- - --admission-controller-listen-on-updates
|
|
|
- - --central={{ api_ep }}
|
|
|
- - --collection-method=kernel-module
|
|
|
- - --slim-collector=true
|
|
|
- - --name={{ clusters[cluster].name }}
|
|
|
- - --output-dir=./{{ clusters[cluster].name }}-secured
|
|
|
- chdir: "{{ ansible_facts['user_dir'] }}"
|
|
|
- when: not sensor_script_present.stat.exists
|
|
|
-
|
|
|
- - name: apply sensor.sh resources
|
|
|
- ansible.builtin.command:
|
|
|
- argv:
|
|
|
- - /usr/bin/env
|
|
|
- - REGISTRY_USERNAME={{ pull_user }}
|
|
|
- - REGISTRY_PASSWORD={{ pull_pass }}
|
|
|
- - KUBECONFIG={{ ansible_facts['user_dir'] }}/kubeconfig-{{ cluster }}
|
|
|
- - "{{ ansible_facts['user_dir'] }}/{{ clusters[cluster].name }}-secured/sensor.sh"
|
|
|
- chdir: "{{ ansible_facts['user_dir'] }}"
|
|
|
- when: sensor_deployments_present.resources | length < 2
|
|
|
-
|
|
|
- when:
|
|
|
- - clusters[cluster].method == 'roxctl'
|
|
|
- - not cluster_found
|
|
|
-
|
|
|
-# helm uses some undecipherable configmaps, so we need to use the binary
|
|
|
-- block:
|
|
|
- - name: helm chart check
|
|
|
- ansible.builtin.command:
|
|
|
- argv:
|
|
|
- - /usr/bin/env
|
|
|
- - KUBECONFIG={{ ansible_facts['user_dir'] }}/kubeconfig-{{ cluster }}
|
|
|
- - /usr/local/bin/helm
|
|
|
- - -n
|
|
|
- - stackrox
|
|
|
- - list
|
|
|
- - -o
|
|
|
- - json
|
|
|
- - --filter
|
|
|
- - stackrox.*services
|
|
|
- chdir: "{{ ansible_facts['user_dir'] }}"
|
|
|
- register: helm_chart_status
|
|
|
-
|
|
|
- - name: assert chart isn't there
|
|
|
- set_fact:
|
|
|
- helm_chart_present: false
|
|
|
-
|
|
|
- - name: unless proven otherwise
|
|
|
- set_fact:
|
|
|
- helm_chart_present: true
|
|
|
- when:
|
|
|
- - helm_chart_status.stdout | from_json | list | length > 0
|
|
|
- - (helm_chart_status.stdout | from_json | list)[0].status == "deployed"
|
|
|
-
|
|
|
- - name: create helm vars
|
|
|
- template:
|
|
|
- src: templates/helm-vars.yml
|
|
|
- dest: "{{ ansible_facts['user_dir'] }}/{{ clusters[cluster].name }}-helm-vars.yaml"
|
|
|
- mode: 0600
|
|
|
- owner: "{{ ansible_user }}"
|
|
|
- group: "{{ ansible_user }}"
|
|
|
- when:
|
|
|
- - not helm_chart_present
|
|
|
-
|
|
|
- - name: check the repo
|
|
|
- ansible.builtin.command:
|
|
|
- argv:
|
|
|
- - /usr/bin/env
|
|
|
- - KUBECONFIG={{ ansible_facts['user_dir'] }}/kubeconfig-{{ cluster }}
|
|
|
- - /usr/local/bin/helm
|
|
|
- - repo
|
|
|
- - list
|
|
|
- - -o
|
|
|
- - json
|
|
|
- chdir: "{{ ansible_facts['user_dir'] }}"
|
|
|
- ignore_errors: yes
|
|
|
- register: repo_is_there
|
|
|
-
|
|
|
- - debug: var=repo_is_there
|
|
|
-
|
|
|
- - name: add the repo
|
|
|
- ansible.builtin.command:
|
|
|
- argv:
|
|
|
- - /usr/bin/env
|
|
|
- - KUBECONFIG={{ ansible_facts['user_dir'] }}/kubeconfig-{{ cluster }}
|
|
|
- - /usr/local/bin/helm
|
|
|
- - repo
|
|
|
- - add
|
|
|
- - rhacs
|
|
|
- - https://mirror.openshift.com/pub/rhacs/charts/
|
|
|
- chdir: "{{ ansible_facts['user_dir'] }}"
|
|
|
- when: repo_is_there.failed or (repo_is_there.stdout | from_json | list | length) == 0
|
|
|
-
|
|
|
- - name: apply helm chart
|
|
|
- ansible.builtin.command:
|
|
|
- argv:
|
|
|
- - /usr/bin/env
|
|
|
- - KUBECONFIG={{ ansible_facts['user_dir'] }}/kubeconfig-{{ cluster }}
|
|
|
- - /usr/local/bin/helm
|
|
|
- - install
|
|
|
- - -n
|
|
|
- - stackrox
|
|
|
- - --create-namespace
|
|
|
- - stackrox-secured-cluster-services
|
|
|
- - rhacs/secured-cluster-services
|
|
|
- - -f
|
|
|
- - "{{ ansible_facts['user_dir'] }}/{{ clusters[cluster].name }}-helm-bundle.yaml"
|
|
|
- - -f
|
|
|
- - "{{ ansible_facts['user_dir'] }}/{{ clusters[cluster].name }}-helm-vars.yaml"
|
|
|
- chdir: "{{ ansible_facts['user_dir'] }}"
|
|
|
- when:
|
|
|
- - not helm_chart_present
|
|
|
-
|
|
|
+- include_tasks:
|
|
|
+ file: "{{ clusters[cluster].method }}.yml"
|
|
|
when:
|
|
|
- - clusters[cluster].method == 'helm'
|
|
|
- not cluster_found
|
|
|
|
|
|
# step 3: there is just you and me (wait for pods to pop up)
|
|
@@ -406,5 +160,20 @@
|
|
|
- pending_pods.resources[0].metadata.labels.app == 'collector'
|
|
|
|
|
|
# step 5: don't you know the time has arrived (just recheck the cluster in central - it should be healthy)
|
|
|
-
|
|
|
+- name: check that the cluster is marked as discovered
|
|
|
+ uri:
|
|
|
+ method: GET
|
|
|
+ return_content: true
|
|
|
+ validate_certs: false
|
|
|
+ url: "https://{{ api_ep }}/v1/clusters"
|
|
|
+ headers:
|
|
|
+ Authorization: Bearer {{ api_token }}
|
|
|
+ Accept: application/json
|
|
|
+ register: cluster_query_fin
|
|
|
+ until:
|
|
|
+ - cluster_query_fin.json.clusters | length > 0
|
|
|
+ - (cluster_query_fin.json.clusters | items2dict(key_name='name', value_name='status'))[clusters[cluster].name] is defined
|
|
|
+ - ((cluster_query_fin.json.clusters | items2dict(key_name='name', value_name='status'))[clusters[cluster].name]).sensorVersion is defined
|
|
|
+ retries: 30
|
|
|
+ delay: 5
|
|
|
...
|