Skip to content
This repository has been archived by the owner on Apr 17, 2023. It is now read-only.

Commit

Permalink
add molecule
Browse files Browse the repository at this point in the history
  • Loading branch information
Florian Utz committed Feb 24, 2018
1 parent f211f3d commit a0f5e4a
Show file tree
Hide file tree
Showing 12 changed files with 284 additions and 0 deletions.
13 changes: 13 additions & 0 deletions .yamllint
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
extends: default

rules:
braces:
max-spaces-inside: 1
level: error
brackets:
max-spaces-inside: 1
level: error
line-length: disable
# NOTE(retr0h): Templates no longer fail this lint rule.
# Uncomment if running old Molecule templates.
# truthy: disable
64 changes: 64 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Makefile for Ubuntu1604-CIS
.PHONY: help
help:
@echo
@echo This Makefile is used to test this role. Typical use:
@echo
@echo ' make test'
@echo ' make clean'
@echo ' make compare'
@echo
@echo
@echo To use the isolated environment from this directory:
@echo
@echo ' make venv'
@echo ' . bin/activate'
@echo
@echo Molecule has built-in help
@echo
@echo ' molecule'
@echo
@echo "Run just the role 'molecule converge'"
@echo "Login to the VM 'molecule login'"
@echo
@echo To run an audit using 'molecule verify' see tests/test_default.yml
@echo To compare audit results between setups with docker vs vagrant run 'make compare'

# virtualenv allows isolation of python libraries
.PHONY: venv
venv: bin/python

bin/python:
## System's python 2.7 needs only 2 things:
# pip is the package manager for python
pip -V || sudo easy_install pip
# virtualenv allows isolation of python libraries
virtualenv --version || sudo easy_install virtualenv

# Now with those two we can isolate our test setup.
virtualenv .
bin/pip install -r requirements.txt
virtualenv --relocatable .

# cleanup virtualenv and molecule leftovers
clean:
rm -rf .molecule bin lib include lib64 share
rm -f .Python pip-selfcheck.json

.PHONY: lint
lint: bin/python
( . bin/activate && find . -name "*.yml" |grep -v .molecule |xargs bin/yamllint )

.PHONY: test
test: bin/python
( . bin/activate && bin/molecule test )

.PHONY: compare
compare:
rm -rf .molecule
cp vagrant.yml molecule.yml
molecule test
rm -rf .molecule
cp docker.yml molecule.yml
molecule test
diff tests/vagrant.txt tests/docker.txt
13 changes: 13 additions & 0 deletions molecule/default/Dockerfile.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Molecule managed

{% 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 upgrade -y && apt-get install -y python sudo bash ca-certificates && apt-get clean; \
elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python2-dnf bash && dnf clean all; \
elif [ $(command -v yum) ]; then yum makecache fast && yum update -y && yum install -y python sudo yum-plugin-ovl bash && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \
elif [ $(command -v zypper) ]; then zypper refresh && zypper update -y && zypper install -y python sudo bash python-xml && zypper clean -a; \
elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates; fi
16 changes: 16 additions & 0 deletions molecule/default/INSTALL.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
*******
Install
*******

Requirements
============

* Docker Engine
* docker-py

Install
=======

.. code-block:: bash
$ sudo pip install docker-py
69 changes: 69 additions & 0 deletions molecule/default/create.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
- name: Create
hosts: localhost
connection: local
gather_facts: false
no_log: "{{ not lookup('env', 'MOLECULE_DEBUG') | bool }}"
vars:
molecule_file: "{{ lookup('env', 'MOLECULE_FILE') }}"
molecule_ephemeral_directory: "{{ lookup('env', 'MOLECULE_EPHEMERAL_DIRECTORY') }}"
molecule_scenario_directory: "{{ lookup('env', 'MOLECULE_SCENARIO_DIRECTORY') }}"
molecule_yml: "{{ lookup('file', molecule_file) | molecule_from_yaml }}"
tasks:
- name: Create Dockerfiles from image names
template:
src: "{{ molecule_scenario_directory }}/Dockerfile.j2"
dest: "{{ molecule_ephemeral_directory }}/Dockerfile_{{ item.image | regex_replace('[^a-zA-Z0-9_]', '_') }}"
with_items: "{{ molecule_yml.platforms }}"
register: platforms

- name: Discover local Docker images
docker_image_facts:
name: "molecule_local/{{ item.item.name }}"
with_items: "{{ platforms.results }}"
register: docker_images

- name: Build an Ansible compatible image
docker_image:
path: "{{ molecule_ephemeral_directory }}"
name: "molecule_local/{{ item.item.image }}"
dockerfile: "{{ item.item.dockerfile | default(item.invocation.module_args.dest) }}"
force: "{{ item.item.force | default(true) }}"
with_items: "{{ platforms.results }}"
when: platforms.changed or docker_images.results | map(attribute='images') | select('equalto', []) | list | count >= 0

- name: Create docker network(s)
docker_network:
name: "{{ item }}"
state: present
with_items: "{{ molecule_yml.platforms | molecule_get_docker_networks }}"

- name: Create molecule instance(s)
docker_container:
name: "{{ item.name }}"
hostname: "{{ item.name }}"
image: "molecule_local/{{ item.image }}"
state: started
recreate: false
log_driver: json-file
command: "{{ item.command | default('bash -c \"while true; do sleep 10000; done\"') }}"
privileged: "{{ item.privileged | default(omit) }}"
volumes: "{{ item.volumes | default(omit) }}"
capabilities: "{{ item.capabilities | default(omit) }}"
exposed_ports: "{{ item.exposed_ports | default(omit) }}"
published_ports: "{{ item.published_ports | default(omit) }}"
ulimits: "{{ item.ulimits | default(omit) }}"
networks: "{{ item.networks | default(omit) }}"
dns_servers: "{{ item.dns_servers | default(omit) }}"
register: server
with_items: "{{ molecule_yml.platforms }}"
async: 7200
poll: 0

- name: Wait for instance(s) creation to complete
async_status:
jid: "{{ item.ansible_job_id }}"
register: docker_jobs
until: docker_jobs.finished
retries: 300
with_items: "{{ server.results }}"
33 changes: 33 additions & 0 deletions molecule/default/destroy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
- name: Destroy
hosts: localhost
connection: local
gather_facts: false
no_log: "{{ not lookup('env', 'MOLECULE_DEBUG') | bool }}"
vars:
molecule_file: "{{ lookup('env', 'MOLECULE_FILE') }}"
molecule_yml: "{{ lookup('file', molecule_file) | molecule_from_yaml }}"
tasks:
- name: Destroy molecule instance(s)
docker_container:
name: "{{ item.name }}"
state: absent
force_kill: "{{ item.force_kill | default(true) }}"
register: server
with_items: "{{ molecule_yml.platforms }}"
async: 7200
poll: 0

- name: Wait for instance(s) deletion to complete
async_status:
jid: "{{ item.ansible_job_id }}"
register: docker_jobs
until: docker_jobs.finished
retries: 300
with_items: "{{ server.results }}"

- name: Delete docker network(s)
docker_network:
name: "{{ item }}"
state: absent
with_items: "{{ molecule_yml.platforms | molecule_get_docker_networks }}"
23 changes: 23 additions & 0 deletions molecule/default/molecule.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
dependency:
name: galaxy
driver:
name: docker
lint:
name: yamllint
platforms:
- name: instance
image: solita/ubuntu-systemd:latest
privileged: True
command: /sbin/init
provisioner:
name: ansible
lint:
name: ansible-lint
enabled: false
scenario:
name: default
verifier:
name: testinfra
lint:
name: flake8
31 changes: 31 additions & 0 deletions molecule/default/playbook.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
- name: Converge
hosts: all
vars:
ubuntu1604cis_skip_for_travis: true
ubuntu1604_selinux_disable: true
pre_tasks:
- name: install packages for testing under docker
apt:
name: "{{ item }}"
state: present
with_items:
- openssh-server
- name: pretask2
file:
name: /boot/grub
state: directory
changed_when: False
- name: pretask3
file:
name: /boot/grub/grub.cfg
state: touch
changed_when: False
- name: pretask3
file:
name: /etc/default/grub
state: touch
changed_when: False

roles:
- role: Ubuntu1604-CIS
5 changes: 5 additions & 0 deletions molecule/default/prepare.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
- name: Prepare
hosts: all
gather_facts: false
tasks: []
14 changes: 14 additions & 0 deletions molecule/default/tests/test_default.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import os

import testinfra.utils.ansible_runner

testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner(
os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all')


def test_hosts_file(host):
f = host.file('/etc/hosts')

assert f.exists
assert f.user == 'root'
assert f.group == 'root'
Binary file added molecule/default/tests/test_default.pyc
Binary file not shown.
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
molecule==2.9.0
yamllint==1.11.0
docker-py=1.10.6

0 comments on commit a0f5e4a

Please sign in to comment.