diff --git a/tripleo_ansible/roles/tripleo_ssh_known_hosts/molecule/default/molecule.yml b/tripleo_ansible/roles/tripleo_ssh_known_hosts/molecule/default/molecule.yml index 119406952..8b7f29d3c 100644 --- a/tripleo_ansible/roles/tripleo_ssh_known_hosts/molecule/default/molecule.yml +++ b/tripleo_ansible/roles/tripleo_ssh_known_hosts/molecule/default/molecule.yml @@ -29,18 +29,27 @@ provisioner: inventory: hosts: all: - vars: - ctlplane_ip: 10.0.0.0 - cloud_domain: localdomain - enabled_networks: [] - role_networks: [] children: overcloud: hosts: centos8: ansible_ssh_host_key_rsa_public: AAAATEST + ctlplane_ip: 10.0.0.1 + ctlplane_hostname: centos8.ctlplane.localdomain + internal_api_ip: 10.0.1.1 + internal_api_hostname: centos8.internalapi.localdomain + management_ip: 10.0.0.1 # no management_hostname + canonical_hostname: centos8.localdomain + tripleo_role_networks: [ctlplane, internal_api, management] centos7: - ansible_ssh_host_key_rsa_public: AAAATEST + ansible_ssh_host_key_rsa_public: BBBBTEST + hostname_resolve_network: ctlplane + ctlplane_ip: 10.0.0.2 + ctlplane_hostname: centos7.ctlplane.localdomain + internal_api_ip: 10.0.1.2 + internal_api_hostname: centos7.internalapi.localdomain + canonical_hostname: centos7.localdomain + tripleo_role_networks: [ctlplane, internal_api] log: true env: ANSIBLE_STDOUT_CALLBACK: yaml diff --git a/tripleo_ansible/roles/tripleo_ssh_known_hosts/molecule/default/tests/test_default.py b/tripleo_ansible/roles/tripleo_ssh_known_hosts/molecule/default/tests/test_default.py index 83d5a6e52..c12b2cf67 100644 --- a/tripleo_ansible/roles/tripleo_ssh_known_hosts/molecule/default/tests/test_default.py +++ b/tripleo_ansible/roles/tripleo_ssh_known_hosts/molecule/default/tests/test_default.py @@ -23,7 +23,11 @@ testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all') -def test_host_key_add(host): - hostname = host.ansible.get_variables()['inventory_hostname'] - line = '[10.0.0.0]*,[%s.localdomain]*,[%s]* ssh-rsa AAAATEST' % (hostname, hostname) - assert line in host.file("/etc/ssh/ssh_known_hosts").content_string +def test_ssh_host_keys(host): + expected = [ + '[10.0.0.1]*,[centos8.ctlplane.localdomain]*,[10.0.1.1]*,[centos8.internalapi.localdomain]*,[centos8.localdomain]*,[centos8]* ssh-rsa AAAATEST', + '[10.0.0.2]*,[centos7.ctlplane.localdomain]*,[10.0.1.2]*,[centos7.internalapi.localdomain]*,[centos7.localdomain]*,[centos7]* ssh-rsa BBBBTEST' + ] + known_hosts = host.file("/etc/ssh/ssh_known_hosts").content_string + for line in expected: + assert line in host.file("/etc/ssh/ssh_known_hosts").content_string diff --git a/tripleo_ansible/roles/tripleo_ssh_known_hosts/molecule/no_networks/Dockerfile b/tripleo_ansible/roles/tripleo_ssh_known_hosts/molecule/no_networks/Dockerfile new file mode 100644 index 000000000..e0534b4d1 --- /dev/null +++ b/tripleo_ansible/roles/tripleo_ssh_known_hosts/molecule/no_networks/Dockerfile @@ -0,0 +1,37 @@ +# Molecule managed +# Copyright 2019 Red Hat, Inc. +# All Rights Reserved. +# +# 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. + + +{% if item.registry is defined %} +FROM {{ item.registry.url }}/{{ item.image }} +{% else %} +FROM {{ item.image }} +{% endif %} + +RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates && apt-get clean; \ + elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install sudo python*-devel python*-dnf bash {{ item.pkg_extras | default('') }} && dnf clean all; \ + elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl python-setuptools bash {{ item.pkg_extras | default('') }} && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \ + elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml {{ item.pkg_extras | default('') }} && zypper clean -a; \ + elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates {{ item.pkg_extras | default('') }}; \ + elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates {{ item.pkg_extras | default('') }} && xbps-remove -O; fi + +{% for pkg in item.easy_install | default([]) %} +# install pip for centos where there is no python-pip rpm in default repos +RUN easy_install {{ pkg }} +{% endfor %} + + +CMD ["sh", "-c", "while true; do sleep 10000; done"] diff --git a/tripleo_ansible/roles/tripleo_ssh_known_hosts/molecule/no_networks/molecule.yml b/tripleo_ansible/roles/tripleo_ssh_known_hosts/molecule/no_networks/molecule.yml new file mode 100644 index 000000000..3fac2da35 --- /dev/null +++ b/tripleo_ansible/roles/tripleo_ssh_known_hosts/molecule/no_networks/molecule.yml @@ -0,0 +1,58 @@ +--- +driver: + name: docker + +log: true + +platforms: + - name: centos7 + hostname: centos7 + image: centos:7 + dockerfile: Dockerfile + pkg_extras: python-setuptools + easy_install: + - pip + environment: &env + http_proxy: "{{ lookup('env', 'http_proxy') }}" + https_proxy: "{{ lookup('env', 'https_proxy') }}" + + - name: centos8 + hostname: centos8 + image: centos:8 + dockerfile: Dockerfile + pkg_extras: python*-setuptools + environment: + <<: *env + +provisioner: + name: ansible + inventory: + hosts: + all: + children: + overcloud: + hosts: + centos8: + ansible_ssh_host_key_rsa_public: AAAATEST + centos7: + ansible_ssh_host_key_rsa_public: BBBBTEST + log: true + env: + ANSIBLE_STDOUT_CALLBACK: yaml + +scenario: + test_sequence: + - destroy + - create + - prepare + - converge + - verify + - destroy + +lint: + enabled: false + +verifier: + name: testinfra + lint: + name: flake8 diff --git a/tripleo_ansible/roles/tripleo_ssh_known_hosts/molecule/no_networks/playbook.yml b/tripleo_ansible/roles/tripleo_ssh_known_hosts/molecule/no_networks/playbook.yml new file mode 100644 index 000000000..10bfe721f --- /dev/null +++ b/tripleo_ansible/roles/tripleo_ssh_known_hosts/molecule/no_networks/playbook.yml @@ -0,0 +1,22 @@ +--- +# Copyright 2019 Red Hat, Inc. +# All Rights Reserved. +# +# 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. + + +- name: Converge + hosts: all + pre_tasks: + roles: + - role: "tripleo_ssh_known_hosts" diff --git a/tripleo_ansible/roles/tripleo_ssh_known_hosts/molecule/no_networks/prepare.yml b/tripleo_ansible/roles/tripleo_ssh_known_hosts/molecule/no_networks/prepare.yml new file mode 100644 index 000000000..57929e854 --- /dev/null +++ b/tripleo_ansible/roles/tripleo_ssh_known_hosts/molecule/no_networks/prepare.yml @@ -0,0 +1,26 @@ +--- +# Copyright 2019 Red Hat, Inc. +# All Rights Reserved. +# +# 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. + + +- name: Prepare + hosts: all + roles: + - role: test_deps + tasks: + - name: Install additional dependencies + package: + name: openssh + state: present diff --git a/tripleo_ansible/roles/tripleo_ssh_known_hosts/molecule/no_networks/tests/test_no_networks.py b/tripleo_ansible/roles/tripleo_ssh_known_hosts/molecule/no_networks/tests/test_no_networks.py new file mode 100644 index 000000000..ffb5f0779 --- /dev/null +++ b/tripleo_ansible/roles/tripleo_ssh_known_hosts/molecule/no_networks/tests/test_no_networks.py @@ -0,0 +1,33 @@ +# Copyright 2019 Red Hat, Inc. +# All Rights Reserved. +# +# 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. + + +import os + +import testinfra.utils.ansible_runner + + +testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( + os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all') + + +def test_ssh_host_keys(host): + expected = [ + '[centos8]* ssh-rsa AAAATEST', + '[centos7]* ssh-rsa BBBBTEST' + ] + known_hosts = host.file("/etc/ssh/ssh_known_hosts").content_string + for line in expected: + assert line in host.file("/etc/ssh/ssh_known_hosts").content_string diff --git a/tripleo_ansible/roles/tripleo_ssh_known_hosts/tasks/main.yml b/tripleo_ansible/roles/tripleo_ssh_known_hosts/tasks/main.yml index c7f7f5b24..ee2b496b3 100644 --- a/tripleo_ansible/roles/tripleo_ssh_known_hosts/tasks/main.yml +++ b/tripleo_ansible/roles/tripleo_ssh_known_hosts/tasks/main.yml @@ -47,29 +47,25 @@ run_once: true set_fact: ssh_known_hosts_lines: |- - {% for host in (groups['overcloud'] | intersect(play_hosts)) %} + {% for host in groups['overcloud'] | intersect(play_hosts) %} {% set hostdata = hostvars[host] %} - {% if ('ansible_ssh_host_key_rsa_public' in hostdata) or (ansible_ssh_host_key_rsa_public is defined) %} - {% if (cloud_domain is defined) and (hostdata['ctlplane_ip'] is defined) %} - {% set line = '[' ~ hostdata['ctlplane_ip'] ~ ']*,[' ~ host ~ '.' ~ cloud_domain ~ ']*,[' ~ host ~ ']*' %} - {% set role_networks = hostdata['role_networks'] | default([]) %} - {% if ((enabled_networks is defined and enabled_networks) and ((enabled_networks | length) > 0)) %} - {% if ((role_networks is defined and role_networks) and ((role_networks | length) > 0)) %} - {% set line = line ~ ',' %} - {% for network in enabled_networks %} - {% if network in role_networks %} - {% set line = line ~ '[' ~ hostdata[(networks[network]["name"] ~ '_ip')] ~ ']*,[' ~ host ~ '.' ~ network.lower() ~ ']*,' %} - {% set line = line ~ '[' ~ host ~ '.' ~ network.lower() ~ '.' ~ cloud_domain ~ ']*' %} - {% if not loop.last %} - {% set line = line ~ ',' %} - {% endif %} - {% endif %} - {% endfor %} - {% endif %} + {% if 'ansible_ssh_host_key_rsa_public' in hostdata %} + {% set entries = [] %} + {% set enabled_host_networks = hostdata['tripleo_role_networks']|default([]) %} + {% for network in enabled_host_networks %} + {% if (network ~ '_ip') in hostdata %} + {% set _ = entries.append('[' ~ hostdata[network ~ '_ip'] ~ ']*') %} {% endif %} - {% set line = line ~ ' ssh-rsa ' ~ hostdata['ansible_ssh_host_key_rsa_public'] | default(ansible_ssh_host_key_rsa_public) %} - {{ line }} + {% if (network ~ '_hostname') in hostdata %} + {% set _ = entries.append('[' ~ hostdata[network ~ '_hostname'] ~ ']*') %} + {% endif %} + {% endfor %} + {% if 'canonical_hostname' in hostdata %} + {% set _ = entries.append('[' ~ hostdata['canonical_hostname'] ~ ']*') %} {% endif %} + {% set _ = entries.append('[' ~ host ~ ']*') %} + {% set line = entries|unique|join(',') ~ ' ssh-rsa ' ~ hostdata['ansible_ssh_host_key_rsa_public'] %} + {{ line }} {% endif %} {% endfor %}