From 65eb7e43faf38698b22b90ad3c743d1fecdc0961 Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Tue, 17 Jan 2017 11:42:23 -0500 Subject: use pod to generate keystores (#14) --- roles/openshift_metrics/files/import_jks_certs.sh | 118 ++++++++++++++++++++ roles/openshift_metrics/meta/main.yaml | 28 ++--- .../tasks/generate_hawkular_certificates.yaml | 97 ++--------------- .../openshift_metrics/tasks/import_jks_certs.yaml | 120 +++++++++++++++++++++ roles/openshift_metrics/tasks/install_metrics.yaml | 8 +- roles/openshift_metrics/tasks/oc_apply.yaml | 7 +- .../openshift_metrics/tasks/setup_certificate.yaml | 21 +--- roles/openshift_metrics/tasks/stop_metrics.yaml | 1 - roles/openshift_metrics/templates/jks_pod.j2 | 38 +++++++ 9 files changed, 309 insertions(+), 129 deletions(-) create mode 100755 roles/openshift_metrics/files/import_jks_certs.sh create mode 100644 roles/openshift_metrics/tasks/import_jks_certs.yaml create mode 100644 roles/openshift_metrics/templates/jks_pod.j2 (limited to 'roles/openshift_metrics') diff --git a/roles/openshift_metrics/files/import_jks_certs.sh b/roles/openshift_metrics/files/import_jks_certs.sh new file mode 100755 index 000000000..bb046df87 --- /dev/null +++ b/roles/openshift_metrics/files/import_jks_certs.sh @@ -0,0 +1,118 @@ +#!/bin/bash +# +# Copyright 2014-2015 Red Hat, Inc. and/or its affiliates +# and other contributors as indicated by the @author tags. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +set -ex + +function import_certs() { + dir=$CERT_DIR + hawkular_metrics_keystore_password=$(echo $METRICS_KEYSTORE_PASSWD | base64 -d) + hawkular_cassandra_keystore_password=$(echo $CASSANDRA_KEYSTORE_PASSWD | base64 -d) + hawkular_metrics_truststore_password=$(echo $METRICS_TRUSTSTORE_PASSWD | base64 -d) + hawkular_cassandra_truststore_password=$(echo $CASSANDRA_TRUSTSTORE_PASSWD | base64 -d) + hawkular_jgroups_password=$(echo $JGROUPS_PASSWD | base64 -d) + + cassandra_alias=`keytool -noprompt -list -keystore $dir/hawkular-cassandra.truststore -storepass ${hawkular_cassandra_truststore_password} | sed -n '7~2s/,.*$//p'` + hawkular_alias=`keytool -noprompt -list -keystore $dir/hawkular-metrics.truststore -storepass ${hawkular_metrics_truststore_password} | sed -n '7~2s/,.*$//p'` + + if [ ! -f $dir/hawkular-metrics.keystore ]; then + echo "Creating the Hawkular Metrics keystore from the PEM file" + keytool -importkeystore -v \ + -srckeystore $dir/hawkular-metrics.pkcs12 \ + -destkeystore $dir/hawkular-metrics.keystore \ + -srcstoretype PKCS12 \ + -deststoretype JKS \ + -srcstorepass $hawkular_metrics_keystore_password \ + -deststorepass $hawkular_metrics_keystore_password + fi + + if [ ! -f $dir/hawkular-cassandra.keystore ]; then + echo "Creating the Hawkular Cassandra keystore from the PEM file" + keytool -importkeystore -v \ + -srckeystore $dir/hawkular-cassandra.pkcs12 \ + -destkeystore $dir/hawkular-cassandra.keystore \ + -srcstoretype PKCS12 \ + -deststoretype JKS \ + -srcstorepass $hawkular_cassandra_keystore_password \ + -deststorepass $hawkular_cassandra_keystore_password + fi + + if [[ ! ${cassandra_alias[*]} =~ hawkular-metrics ]]; then + echo "Importing the Hawkular Certificate into the Cassandra Truststore" + keytool -noprompt -import -v -trustcacerts -alias hawkular-metrics \ + -file $dir/hawkular-metrics.crt \ + -keystore $dir/hawkular-cassandra.truststore \ + -trustcacerts \ + -storepass $hawkular_cassandra_truststore_password + fi + + if [[ ! ${hawkular_alias[*]} =~ hawkular-cassandra ]]; then + echo "Importing the Cassandra Certificate into the Hawkular Truststore" + keytool -noprompt -import -v -trustcacerts -alias hawkular-cassandra \ + -file $dir/hawkular-cassandra.crt \ + -keystore $dir/hawkular-metrics.truststore \ + -trustcacerts \ + -storepass $hawkular_metrics_truststore_password + fi + + if [[ ! ${cassandra_alias[*]} =~ hawkular-cassandra ]]; then + echo "Importing the Hawkular Cassandra Certificate into the Cassandra Truststore" + keytool -noprompt -import -v -trustcacerts -alias hawkular-cassandra \ + -file $dir/hawkular-cassandra.crt \ + -keystore $dir/hawkular-cassandra.truststore \ + -trustcacerts \ + -storepass $hawkular_cassandra_truststore_password + fi + + cert_alias_names=(ca metricca cassandraca) + + for cert_alias in ${cert_alias_names[*]}; do + if [[ ! ${cassandra_alias[*]} =~ "$cert_alias" ]]; then + echo "Importing the CA Certificate with alias $cert_alias into the Cassandra Truststore" + keytool -noprompt -import -v -trustcacerts -alias $cert_alias \ + -file ${dir}/ca.crt \ + -keystore $dir/hawkular-cassandra.truststore \ + -trustcacerts \ + -storepass $hawkular_cassandra_truststore_password + fi + done + + for cert_alias in ${cert_alias_names[*]}; do + if [[ ! ${hawkular_alias[*]} =~ "$cert_alias" ]]; then + echo "Importing the CA Certificate with alias $cert_alias into the Hawkular Metrics Truststore" + keytool -noprompt -import -v -trustcacerts -alias $cert_alias \ + -file ${dir}/ca.crt \ + -keystore $dir/hawkular-metrics.truststore \ + -trustcacerts \ + -storepass $hawkular_metrics_truststore_password + fi + done + + if [ ! -f $dir/hawkular-jgroups.keystore ]; then + echo "Generating the jgroups keystore" + keytool -genseckey -alias hawkular -keypass ${hawkular_jgroups_password} \ + -storepass ${hawkular_jgroups_password} \ + -keyalg Blowfish \ + -keysize 56 \ + -keystore $dir/hawkular-jgroups.keystore \ + -storetype JCEKS + fi +} + +import_certs + +exit 0 diff --git a/roles/openshift_metrics/meta/main.yaml b/roles/openshift_metrics/meta/main.yaml index 567584079..68e94992e 100644 --- a/roles/openshift_metrics/meta/main.yaml +++ b/roles/openshift_metrics/meta/main.yaml @@ -1,18 +1,18 @@ --- galaxy_info: - author: OpenShift Development - description: Deploy OpenShift metrics integration for the cluster - company: Red Hat, Inc. - license: license (Apache) - min_ansible_version: 2.2 - platforms: - - name: EL - versions: - - 7 - - name: Fedora - versions: - - all - categories: - - openshift + author: OpenShift Development + description: Deploy OpenShift metrics integration for the cluster + company: Red Hat, Inc. + license: license (Apache) + min_ansible_version: 2.2 + platforms: + - name: EL + versions: + - 7 + - name: Fedora + versions: + - all + categories: + - openshift dependencies: - { role: openshift_facts } diff --git a/roles/openshift_metrics/tasks/generate_hawkular_certificates.yaml b/roles/openshift_metrics/tasks/generate_hawkular_certificates.yaml index 489856c27..9cf4afee0 100644 --- a/roles/openshift_metrics/tasks/generate_hawkular_certificates.yaml +++ b/roles/openshift_metrics/tasks/generate_hawkular_certificates.yaml @@ -13,93 +13,16 @@ hostnames: hawkular-cassandra changed_when: no -- slurp: src={{ openshift_metrics_certs_dir|quote }}/hawkular-cassandra-truststore.pwd +- slurp: src={{ openshift_metrics_certs_dir }}/hawkular-cassandra-truststore.pwd register: cassandra_truststore_password -- name: check existing aliases on the hawkular-cassandra truststore - shell: > - keytool -noprompt -list - -keystore {{ openshift_metrics_certs_dir|quote }}/hawkular-cassandra.truststore - -storepass {{cassandra_truststore_password.content | b64decode }} - | sed -n '7~2s/,.*$//p' - register: hawkular_cassandra_truststore_aliases - changed_when: false - -- slurp: src={{ openshift_metrics_certs_dir|quote }}/hawkular-metrics-truststore.pwd +- slurp: src={{ openshift_metrics_certs_dir }}/hawkular-metrics-truststore.pwd register: hawkular_truststore_password -- name: check existing aliases on the hawkular-metrics truststore - shell: > - keytool -noprompt -list - -keystore {{ openshift_metrics_certs_dir|quote }}/hawkular-metrics.truststore - -storepass {{ hawkular_truststore_password.content | b64decode }} - | sed -n '7~2s/,.*$//p' - register: hawkular_metrics_truststore_aliases - changed_when: false - -- name: import the hawkular metrics cert into the cassandra truststore - command: > - keytool -noprompt -import -v -trustcacerts - -alias hawkular-metrics - -file '{{ openshift_metrics_certs_dir }}/hawkular-metrics.crt' - -keystore '{{ openshift_metrics_certs_dir }}/hawkular-cassandra.truststore' - -storepass {{cassandra_truststore_password.content | b64decode }} - when: > - 'hawkular-metrics' not in - hawkular_cassandra_truststore_aliases.stdout_lines - -- name: import the hawkular cassandra cert into the hawkular metrics truststore - command: > - keytool -noprompt -import -v -trustcacerts - -alias hawkular-cassandra - -file '{{ openshift_metrics_certs_dir }}/hawkular-cassandra.crt' - -keystore '{{ openshift_metrics_certs_dir }}/hawkular-metrics.truststore' - -storepass {{ hawkular_truststore_password.content | b64decode }} - when: > - 'hawkular-cassandra' not in - hawkular_metrics_truststore_aliases.stdout_lines - -- name: import the hawkular cassandra cert into the cassandra truststore - command: > - keytool -noprompt -import -v -trustcacerts - -alias hawkular-cassandra - -file '{{ openshift_metrics_certs_dir }}/hawkular-cassandra.crt' - -keystore '{{ openshift_metrics_certs_dir }}/hawkular-cassandra.truststore' - -storepass {{cassandra_truststore_password.content | b64decode }} - when: > - 'hawkular-cassandra' not in - hawkular_cassandra_truststore_aliases.stdout_lines - -- name: import the ca certificate into the cassandra truststore - command: > - keytool -noprompt -import -v -trustcacerts - -alias '{{ item }}' - -file '{{ openshift_metrics_certs_dir }}/ca.crt' - -keystore '{{ openshift_metrics_certs_dir }}/hawkular-cassandra.truststore' - -storepass {{cassandra_truststore_password.content | b64decode }} - with_items: - - ca - - metricca - - cassandraca - when: item not in hawkular_cassandra_truststore_aliases.stdout_lines - -- name: import the ca certificate into the hawkular metrics truststore - command: > - keytool -noprompt -import -v -trustcacerts - -alias '{{ item }}' - -file '{{ openshift_metrics_certs_dir }}/ca.crt' - -keystore '{{ openshift_metrics_certs_dir }}/hawkular-metrics.truststore' - -storepass {{ hawkular_truststore_password.content | b64decode }} - with_items: - - ca - - metricca - - cassandraca - when: item not in hawkular_metrics_truststore_aliases.stdout_lines - - name: generate password for hawkular metrics and jgroups - shell: > - tr -dc _A-Z-a-z-0-9 < /dev/urandom | head -c15 - > '{{ openshift_metrics_certs_dir }}/{{ item }}.pwd' + copy: + dest: '{{ openshift_metrics_certs_dir }}/{{ item }}.pwd' + content: "{{ 15 | oo_random_word }}" with_items: - hawkular-metrics - hawkular-jgroups-keystore @@ -113,15 +36,7 @@ when: > not '{{ openshift_metrics_certs_dir }}/hawkular-metrics.htpasswd'|exists -- name: generate the jgroups keystore - shell: > - p=$(< '{{ openshift_metrics_certs_dir }}/hawkular-jgroups-keystore.pwd' ) - && - keytool -genseckey -alias hawkular - -keypass "$p" -storepass "$p" -keyalg Blowfish -keysize 56 -storetype JCEKS - -keystore '{{ openshift_metrics_certs_dir }}/hawkular-jgroups.keystore' - when: > - not '{{ openshift_metrics_certs_dir }}/hawkular-jgroups.keystore'|exists +- include: import_jks_certs.yaml - name: read files for the hawkular-metrics secret shell: > diff --git a/roles/openshift_metrics/tasks/import_jks_certs.yaml b/roles/openshift_metrics/tasks/import_jks_certs.yaml new file mode 100644 index 000000000..f6bf6c1a6 --- /dev/null +++ b/roles/openshift_metrics/tasks/import_jks_certs.yaml @@ -0,0 +1,120 @@ +--- +- name: Check for jks-generator service account + command: > + {{ openshift.common.client_binary }} + --config={{ mktemp.stdout }}/admin.kubeconfig + -n {{openshift_metrics_project}} + get serviceaccount/jks-generator --no-headers + register: serviceaccount_result + ignore_errors: yes + when: not ansible_check_mode + changed_when: no + +- name: Create jks-generator service account + command: > + {{ openshift.common.client_binary }} + --config={{ mktemp.stdout }}/admin.kubeconfig + -n {{openshift_metrics_project}} + create serviceaccount jks-generator + when: not ansible_check_mode and "not found" in serviceaccount_result.stderr + +- name: Check for hostmount-anyuid scc entry + command: > + {{ openshift.common.client_binary }} + --config={{ mktemp.stdout }}/admin.kubeconfig + get scc hostmount-anyuid + -o jsonpath='{.users}' + register: scc_result + when: not ansible_check_mode + changed_when: no + +- name: Add to hostmount-anyuid scc + command: > + {{ openshift.common.admin_binary }} + --config={{ mktemp.stdout }}/admin.kubeconfig + -n {{openshift_metrics_project}} + policy add-scc-to-user hostmount-anyuid + -z jks-generator + when: + - not ansible_check_mode + - scc_result.stdout.find("system:serviceaccount:{{openshift_metrics_project}}:jks-generator") == -1 + +- name: Copy JKS generation script + copy: + src: import_jks_certs.sh + dest: "{{openshift_metrics_certs_dir}}/import_jks_certs.sh" + check_mode: no + +- slurp: src={{ openshift_metrics_certs_dir }}/hawkular-metrics-keystore.pwd + register: metrics_keystore_password + +- slurp: src={{ openshift_metrics_certs_dir }}/hawkular-cassandra-keystore.pwd + register: cassandra_keystore_password + +- slurp: src={{ openshift_metrics_certs_dir }}/hawkular-jgroups-keystore.pwd + register: jgroups_keystore_password + +- name: Generate JKS pod template + template: + src: jks_pod.j2 + dest: "{{mktemp.stdout}}/jks_pod.yaml" + vars: + metrics_keystore_passwd: "{{metrics_keystore_password.content}}" + cassandra_keystore_passwd: "{{cassandra_keystore_password.content}}" + metrics_truststore_passwd: "{{hawkular_truststore_password.content}}" + cassandra_truststore_passwd: "{{cassandra_truststore_password.content}}" + jgroups_passwd: "{{jgroups_keystore_password.content}}" + check_mode: no + changed_when: no + +- stat: path="{{openshift_metrics_certs_dir}}/hawkular-metrics.keystore" + register: metrics_keystore + check_mode: no + +- stat: path="{{openshift_metrics_certs_dir}}/hawkular-cassandra.keystore" + register: cassandra_keystore + check_mode: no + +- stat: path="{{openshift_metrics_certs_dir}}/hawkular-cassandra.truststore" + register: cassandra_truststore + check_mode: no + +- stat: path="{{openshift_metrics_certs_dir}}/hawkular-metrics.truststore" + register: metrics_truststore + check_mode: no + +- stat: path="{{openshift_metrics_certs_dir}}/hawkular-jgroups.keystore" + register: jgroups_keystore + check_mode: no + +- name: create JKS pod + command: > + {{ openshift.common.client_binary }} + --config={{ mktemp.stdout }}/admin.kubeconfig + -n {{openshift_metrics_project}} + create -f {{mktemp.stdout}}/jks_pod.yaml + -o name + register: podoutput + check_mode: no + when: not metrics_keystore.stat.exists or + not metrics_truststore.stat.exists or + not cassandra_keystore.stat.exists or + not cassandra_truststore.stat.exists or + not jgroups_keystore.stat.exists + +- command: > + {{ openshift.common.client_binary }} + --config={{ mktemp.stdout }}/admin.kubeconfig + -n {{openshift_metrics_project}} + get {{podoutput.stdout}} + -o jsonpath='{.status.phase}' + register: result + until: result.stdout.find("Succeeded") != -1 + retries: 5 + delay: 10 + changed_when: no + when: not metrics_keystore.stat.exists or + not metrics_truststore.stat.exists or + not cassandra_keystore.stat.exists or + not cassandra_truststore.stat.exists or + not jgroups_keystore.stat.exists diff --git a/roles/openshift_metrics/tasks/install_metrics.yaml b/roles/openshift_metrics/tasks/install_metrics.yaml index 67d22cbc3..bab37dbfb 100644 --- a/roles/openshift_metrics/tasks/install_metrics.yaml +++ b/roles/openshift_metrics/tasks/install_metrics.yaml @@ -23,10 +23,10 @@ - name: Create objects include: oc_apply.yaml vars: - kubeconfig: "{{ mktemp.stdout }}/admin.kubeconfig" - namespace: "{{ openshift_metrics_project }}" - file_name: "{{ item }}" - file_content: "{{ lookup('file',item) | from_yaml }}" + kubeconfig: "{{ mktemp.stdout }}/admin.kubeconfig" + namespace: "{{ openshift_metrics_project }}" + file_name: "{{ item }}" + file_content: "{{ lookup('file',item) | from_yaml }}" with_fileglob: - "{{ mktemp.stdout }}/templates/*.yaml" diff --git a/roles/openshift_metrics/tasks/oc_apply.yaml b/roles/openshift_metrics/tasks/oc_apply.yaml index c9154f206..dd67703b4 100644 --- a/roles/openshift_metrics/tasks/oc_apply.yaml +++ b/roles/openshift_metrics/tasks/oc_apply.yaml @@ -1,12 +1,13 @@ --- - name: Checking generation of {{file_content.kind}} {{file_content.metadata.name}} command: > - {{ openshift.common.client_binary }} + {{ openshift.common.client_binary }} --config={{ kubeconfig }} get {{file_content.kind}} {{file_content.metadata.name}} - -o jsonpath='{.metadata.resourceVersion}' + -o jsonpath='{.metadata.resourceVersion}' -n {{namespace}} register: generation_init + failed_when: false changed_when: no - name: Applying {{file_name}} @@ -22,7 +23,7 @@ command: > {{ openshift.common.client_binary }} --config={{ kubeconfig }} get {{file_content.kind}} {{file_content.metadata.name}} - -o jsonpath='{.metadata.resourceVersion}' + -o jsonpath='{.metadata.resourceVersion}' -n {{namespace}} register: version_changed vars: diff --git a/roles/openshift_metrics/tasks/setup_certificate.yaml b/roles/openshift_metrics/tasks/setup_certificate.yaml index c185d3f88..5ca8f4462 100644 --- a/roles/openshift_metrics/tasks/setup_certificate.yaml +++ b/roles/openshift_metrics/tasks/setup_certificate.yaml @@ -26,11 +26,11 @@ - name: generate random password for the {{ component }} keystore copy: - content: "{{ 15 | oo_random_word }}" - dest: '{{ openshift_metrics_certs_dir | quote }}/{{ component|quote }}-keystore.pwd' + content: "{{ 15 | oo_random_word }}" + dest: '{{ openshift_metrics_certs_dir }}/{{ component }}-keystore.pwd' when: > not '{{ openshift_metrics_certs_dir }}/{{ component }}-keystore.pwd'|exists - + - slurp: src={{ openshift_metrics_certs_dir | quote }}/{{ component|quote }}-keystore.pwd register: keystore_password @@ -43,21 +43,10 @@ -password 'pass:{{keystore_password.content | b64decode }}' when: not '{{ openshift_metrics_certs_dir }}/{{ component }}.pkcs12'|exists -- name: create the {{ component }} keystore from the pkcs12 file - command: > - keytool -v -importkeystore - -srckeystore '{{ openshift_metrics_certs_dir | quote }}/{{ component | quote }}.pkcs12' - -srcstoretype PKCS12 - -destkeystore '{{ openshift_metrics_certs_dir | quote }}/{{ component | quote}}.keystore' - -deststoretype JKS - -deststorepass '{{keystore_password.content | b64decode }}' - -srcstorepass '{{keystore_password.content | b64decode }}' - when: not '{{ openshift_metrics_certs_dir }}/{{ component }}.keystore'|exists - - name: generate random password for the {{ component }} truststore copy: - content: "{{ 15 | oo_random_word }}" - dest: '{{ openshift_metrics_certs_dir | quote }}/{{ component|quote }}-truststore.pwd' + content: "{{ 15 | oo_random_word }}" + dest: '{{ openshift_metrics_certs_dir | quote }}/{{ component|quote }}-truststore.pwd' when: > not '{{ openshift_metrics_certs_dir | quote }}/{{ component| quote }}-truststore.pwd'|exists diff --git a/roles/openshift_metrics/tasks/stop_metrics.yaml b/roles/openshift_metrics/tasks/stop_metrics.yaml index 524d4227b..bae181e3e 100644 --- a/roles/openshift_metrics/tasks/stop_metrics.yaml +++ b/roles/openshift_metrics/tasks/stop_metrics.yaml @@ -53,4 +53,3 @@ loop_control: loop_var: object when: metrics_cassandra_rc is defined - diff --git a/roles/openshift_metrics/templates/jks_pod.j2 b/roles/openshift_metrics/templates/jks_pod.j2 new file mode 100644 index 000000000..e86fe38a4 --- /dev/null +++ b/roles/openshift_metrics/templates/jks_pod.j2 @@ -0,0 +1,38 @@ +apiVersion: v1 +kind: Pod +metadata: + labels: + metrics-infra: support + generateName: jks-cert-gen- +spec: + containers: + - name: jks-cert-gen + image: {{openshift_metrics_image_prefix}}metrics-deployer:{{openshift_metrics_image_version}} + imagePullPolicy: Always + command: ["sh", "{{openshift_metrics_certs_dir}}/import_jks_certs.sh"] + securityContext: + runAsUser: 0 + volumeMounts: + - mountPath: {{openshift_metrics_certs_dir}} + name: certmount + env: + - name: CERT_DIR + value: {{openshift_metrics_certs_dir}} + - name: METRICS_KEYSTORE_PASSWD + value: {{metrics_keystore_passwd}} + - name: CASSANDRA_KEYSTORE_PASSWD + value: {{cassandra_keystore_passwd}} + - name: METRICS_TRUSTSTORE_PASSWD + value: {{metrics_truststore_passwd}} + - name: CASSANDRA_TRUSTSTORE_PASSWD + value: {{cassandra_truststore_passwd}} + - name: hawkular_cassandra_alias + value: {{cassandra_keystore_passwd}} + - name: JGROUPS_PASSWD + value: {{jgroups_passwd}} + restartPolicy: Never + serviceAccount: jks-generator + volumes: + - hostPath: + path: "{{openshift_metrics_certs_dir}}" + name: certmount -- cgit v1.2.1