From 0b5d1be37e13c74a6fe8649e15618ac84963ca57 Mon Sep 17 00:00:00 2001 From: Mark Chappell Date: Thu, 16 Sep 2021 12:07:38 +0200 Subject: [PATCH] Add setup_botocore_pip/ setup_ec2_facts/ setup_sshkey/ integration test helpers from amazon.aws --- .../setup_botocore_pip/defaults/main.yml | 2 + .../setup_botocore_pip/handlers/main.yml | 2 + .../setup_botocore_pip/tasks/cleanup.yml | 5 ++ .../targets/setup_botocore_pip/tasks/main.yml | 42 +++++++++++ .../targets/setup_ec2_facts/defaults/main.yml | 3 + .../targets/setup_ec2_facts/tasks/main.yml | 53 ++++++++++++++ .../setup_sshkey/files/ec2-fingerprint.py | 33 +++++++++ .../targets/setup_sshkey/tasks/main.yml | 71 +++++++++++++++++++ 8 files changed, 211 insertions(+) create mode 100644 tests/integration/targets/setup_botocore_pip/defaults/main.yml create mode 100644 tests/integration/targets/setup_botocore_pip/handlers/main.yml create mode 100644 tests/integration/targets/setup_botocore_pip/tasks/cleanup.yml create mode 100644 tests/integration/targets/setup_botocore_pip/tasks/main.yml create mode 100644 tests/integration/targets/setup_ec2_facts/defaults/main.yml create mode 100644 tests/integration/targets/setup_ec2_facts/tasks/main.yml create mode 100644 tests/integration/targets/setup_sshkey/files/ec2-fingerprint.py create mode 100644 tests/integration/targets/setup_sshkey/tasks/main.yml diff --git a/tests/integration/targets/setup_botocore_pip/defaults/main.yml b/tests/integration/targets/setup_botocore_pip/defaults/main.yml new file mode 100644 index 00000000000..5a50b775907 --- /dev/null +++ b/tests/integration/targets/setup_botocore_pip/defaults/main.yml @@ -0,0 +1,2 @@ +default_botocore_version: '1.18.0' +default_boto3_version: '1.15.0' diff --git a/tests/integration/targets/setup_botocore_pip/handlers/main.yml b/tests/integration/targets/setup_botocore_pip/handlers/main.yml new file mode 100644 index 00000000000..2536d1ac773 --- /dev/null +++ b/tests/integration/targets/setup_botocore_pip/handlers/main.yml @@ -0,0 +1,2 @@ +- name: 'Delete temporary pip environment' + include_tasks: cleanup.yml diff --git a/tests/integration/targets/setup_botocore_pip/tasks/cleanup.yml b/tests/integration/targets/setup_botocore_pip/tasks/cleanup.yml new file mode 100644 index 00000000000..25b3ec27efc --- /dev/null +++ b/tests/integration/targets/setup_botocore_pip/tasks/cleanup.yml @@ -0,0 +1,5 @@ +- name: 'Delete temporary pip environment' + file: + path: "{{ botocore_pip_directory }}" + state: absent + no_log: yes diff --git a/tests/integration/targets/setup_botocore_pip/tasks/main.yml b/tests/integration/targets/setup_botocore_pip/tasks/main.yml new file mode 100644 index 00000000000..b183b7d726d --- /dev/null +++ b/tests/integration/targets/setup_botocore_pip/tasks/main.yml @@ -0,0 +1,42 @@ +- name: 'Ensure that we have virtualenv available to us' + pip: + name: virtualenv + +- name: 'Create temporary directory for pip environment' + tempfile: + state: directory + prefix: botocore + suffix: .test + register: botocore_pip_directory + notify: + - 'Delete temporary pip environment' + +- name: 'Record temporary directory' + set_fact: + botocore_pip_directory: "{{ botocore_pip_directory.path }}" + +- set_fact: + botocore_virtualenv: "{{ botocore_pip_directory }}/virtualenv" + botocore_virtualenv_command: "{{ ansible_python_interpreter }} -m virtualenv" + +- set_fact: + botocore_virtualenv_interpreter: "{{ botocore_virtualenv }}/bin/python" + +- pip: + name: + - 'boto3{{ _boto3_comparison }}{{ _boto3_version }}' + - 'botocore{{ _botocore_comparison }}{{ _botocore_version }}' + - 'coverage<5' + virtualenv: "{{ botocore_virtualenv }}" + virtualenv_command: "{{ botocore_virtualenv_command }}" + virtualenv_site_packages: no + vars: + _boto3_version: '{{ boto3_version | default(default_boto3_version) }}' + _botocore_version: '{{ botocore_version | default(default_botocore_version) }}' + _is_default_boto3: '{{ _boto3_version == default_boto3_version }}' + _is_default_botocore: '{{ _botocore_version == default_botocore_version }}' + # Only set the default to >= if the other dep has been updated and the dep has not been set + _default_boto3_comparison: '{% if _is_default_boto3 and not _is_default_botocore %}>={% else %}=={% endif %}' + _default_botocore_comparison: '{% if _is_default_botocore and not _is_default_boto3 %}>={% else %}=={% endif %}' + _boto3_comparison: '{{ boto3_comparison | default(_default_boto3_comparison) }}' + _botocore_comparison: '{{ botocore_comparison | default(_default_botocore_comparison) }}' diff --git a/tests/integration/targets/setup_ec2_facts/defaults/main.yml b/tests/integration/targets/setup_ec2_facts/defaults/main.yml new file mode 100644 index 00000000000..a09e9a53707 --- /dev/null +++ b/tests/integration/targets/setup_ec2_facts/defaults/main.yml @@ -0,0 +1,3 @@ +ec2_ami_name: 'Fedora-Cloud-Base-*.x86_64*' +ec2_ami_owner_id: '125523088429' +ec2_ami_ssh_user: 'fedora' diff --git a/tests/integration/targets/setup_ec2_facts/tasks/main.yml b/tests/integration/targets/setup_ec2_facts/tasks/main.yml new file mode 100644 index 00000000000..f41791073a3 --- /dev/null +++ b/tests/integration/targets/setup_ec2_facts/tasks/main.yml @@ -0,0 +1,53 @@ +--- +# Setup a couple of common facts about the AWS Region +# +# Information about availablity zones +# - ec2_availability_zone_names +# +# An EC2 AMI that can be used for spinning up Instances performs as search +# rather than hardcoding the IDs so we're not limited to specific Regions +# - ec2_ami_id +# +- module_defaults: + group/aws: + aws_access_key: '{{ aws_access_key }}' + aws_secret_key: '{{ aws_secret_key }}' + security_token: '{{ security_token | default(omit) }}' + region: '{{ aws_region }}' + + run_once: True + block: + # ============================================================ + + - name: Get available AZs + aws_az_info: + filters: + region-name: '{{ aws_region }}' + register: _az_info + + - name: Pick an AZ + set_fact: + ec2_availability_zone_names: '{{ _az_info.availability_zones | selectattr("zone_name", "defined") | map(attribute="zone_name") | list }}' + + # ============================================================ + + - name: Get a list of images + ec2_ami_info: + filters: + name: '{{ ec2_ami_name }}' + owner-id: '{{ ec2_ami_owner_id }}' + architecture: x86_64 + virtualization-type: hvm + root-device-type: ebs + register: _images_info + # Very spammy + no_log: True + + - name: Set Fact for latest AMI + vars: + latest_image: '{{ _images_info.images | sort(attribute="creation_date") | reverse | first }}' + set_fact: + ec2_ami_id: '{{ latest_image.image_id }}' + ec2_ami_details: '{{ latest_image }}' + ec2_ami_root_disk: '{{ latest_image.block_device_mappings[0].device_name }}' + ec2_ami_ssh_user: '{{ ec2_ami_ssh_user }}' diff --git a/tests/integration/targets/setup_sshkey/files/ec2-fingerprint.py b/tests/integration/targets/setup_sshkey/files/ec2-fingerprint.py new file mode 100644 index 00000000000..ea2f51b0f4c --- /dev/null +++ b/tests/integration/targets/setup_sshkey/files/ec2-fingerprint.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python +""" +Reads an OpenSSH Public key and spits out the 'AWS' MD5 sum +The equivalent of + +ssh-keygen -f id_rsa.pub -e -m PKCS8 | openssl pkey -pubin -outform DER | openssl md5 -c | cut -f 2 -d ' ' + +(but without needing the OpenSSL CLI) +""" + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +import hashlib +import sys +from Crypto.PublicKey import RSA + +if len(sys.argv) == 0: + ssh_public_key = "id_rsa.pub" +else: + ssh_public_key = sys.argv[1] + +with open(ssh_public_key, 'r') as key_fh: + data = key_fh.read() + +# Convert from SSH format to DER format +public_key = RSA.importKey(data).exportKey('DER') +md5digest = hashlib.md5(public_key).hexdigest() +# Format the md5sum into the normal format +pairs = zip(md5digest[::2], md5digest[1::2]) +md5string = ":".join(["".join(pair) for pair in pairs]) + +print(md5string) diff --git a/tests/integration/targets/setup_sshkey/tasks/main.yml b/tests/integration/targets/setup_sshkey/tasks/main.yml new file mode 100644 index 00000000000..31bd2176e5c --- /dev/null +++ b/tests/integration/targets/setup_sshkey/tasks/main.yml @@ -0,0 +1,71 @@ +# (c) 2014, James Laska + +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . + +- name: create a temp dir + tempfile: + state: directory + register: sshkey_dir + tags: + - prepare + +- name: ensure script is available + copy: + src: ec2-fingerprint.py + dest: '{{ sshkey_dir.path }}/ec2-fingerprint.py' + mode: 0700 + tags: + - prepare + +- name: Set location of SSH keys + set_fact: + sshkey: '{{ sshkey_dir.path }}/key_one' + another_sshkey: '{{ sshkey_dir.path }}/key_two' + sshkey_pub: '{{ sshkey_dir.path }}/key_one.pub' + another_sshkey_pub: '{{ sshkey_dir.path }}/key_two.pub' + +- name: generate sshkey + shell: echo 'y' | ssh-keygen -P '' -f '{{ sshkey }}' + tags: + - prepare + +- name: record fingerprint + shell: '{{ sshkey_dir.path }}/ec2-fingerprint.py {{ sshkey_pub }}' + register: fingerprint + tags: + - prepare + +- name: generate another_sshkey + shell: echo 'y' | ssh-keygen -P '' -f {{ another_sshkey }} + tags: + - prepare + +- name: record another fingerprint + shell: '{{ sshkey_dir.path }}/ec2-fingerprint.py {{ another_sshkey_pub }}' + register: another_fingerprint + tags: + - prepare + +- name: set facts for future roles + set_fact: + # Public SSH keys (OpenSSH format) + key_material: "{{ lookup('file', sshkey_pub) }}" + another_key_material: "{{ lookup('file', another_sshkey_pub) }}" + # AWS 'fingerprint' (md5digest) + fingerprint: '{{ fingerprint.stdout }}' + another_fingerprint: '{{ another_fingerprint.stdout }}' + tags: + - prepare