Add Molecule tests (#7)

* Initial port to molecule

* Get molecule tests to run

* Draw the rest of the owl

* use local dir for storing collection during CI run

* Add dockerfile, install community.kubernetes collection before sanity check

* Add clean step to Makefile

* Get sanity tests working

* Update sanity test to use makefile

* Add ignores for 2.11 so devel passes

* Update description

* Code review

* Add OWNERS file for prow
This commit is contained in:
Fabian von Feilitzsch
2020-08-17 15:41:37 -04:00
committed by GitHub
parent 3db69dea2b
commit ee21083985
33 changed files with 603 additions and 369 deletions

View File

@@ -51,7 +51,7 @@ jobs:
# The docker container has all the pinned dependencies that are required.
# Explicity specify the version of Python we want to test
- name: Run sanity tests
run: ansible-test sanity --docker -v --color --python ${{ matrix.python }}
run: make test-sanity TEST_ARGS='--python ${{ matrix.python }}'
working-directory: ./ansible_collections/community/okd
###

3
.gitignore vendored
View File

@@ -3,6 +3,9 @@
*.log
__pycache__/
# temp collection path
# Can't ignore this directory for now, as the files have to be viewable by git in order to be sanity-checked
# ansible_collections/
# Galaxy artifacts.
*.tar.gz

33
.yamllint Normal file
View File

@@ -0,0 +1,33 @@
---
# Based on ansible-lint config
extends: default
rules:
braces:
max-spaces-inside: 1
level: error
brackets:
max-spaces-inside: 1
level: error
colons:
max-spaces-after: -1
level: error
commas:
max-spaces-after: -1
level: error
comments: disable
comments-indentation: disable
document-start: disable
empty-lines:
max: 3
level: error
hyphens:
level: error
indentation: disable
key-duplicates: enable
line-length: disable
new-line-at-end-of-file: disable
new-lines:
type: unix
trailing-spaces: disable
truthy: disable

18
Makefile Normal file
View File

@@ -0,0 +1,18 @@
# Also needs to be updated in galaxy.yml
VERSION = 0.1.0
clean:
rm -f community-okd-${VERSION}.tar.gz
rm -rf ansible_collections
build: clean
ansible-galaxy collection build
install: build
ansible-galaxy collection install -p ansible_collections community-okd-${VERSION}.tar.gz
test-sanity: install
cd ansible_collections/community/okd && ansible-test sanity -v --docker --color $(TEST_ARGS)
test-integration: install
molecule test

6
OWNERS Normal file
View File

@@ -0,0 +1,6 @@
approvers:
- geerlingguy
- fabianvf
reviewers:
- geerlingguy
- fabianvf

View File

@@ -12,6 +12,8 @@ Click on the name of a plugin or module to view that content's documentation:
- **Inventory Source**:
- [openshift](https://docs.ansible.com/ansible/2.10/collections/community/kubernetes/openshift_inventory.html)
- **Modules**:
- [k8s](https://docs.ansible.com/ansible/latest/modules/k8s_module.html)
## Installation and Usage
@@ -54,14 +56,19 @@ For documentation on how to use individual plugins included in this collection,
If you want to develop new content for this collection or improve what's already here, the easiest way to work on the collection is to clone it into one of the configured [`COLLECTIONS_PATHS`](https://docs.ansible.com/ansible/latest/reference_appendices/config.html#collections-paths), and work on it there.
### Testing with `ansible-test`
The `tests` directory contains configuration for running sanity tests using [`ansible-test`](https://docs.ansible.com/ansible/latest/dev_guide/testing_integration.html).
The `tests` directory contains configuration for running sanity and integration tests using [`ansible-test`](https://docs.ansible.com/ansible/latest/dev_guide/testing_integration.html).
You can run the `ansible-test` sanity tests with the command:
You can run the collection's test suites with the commands:
make test-sanity
ansible-test sanity --docker -v --color
ansible-test integration --docker -v --color
The `molecule` directory contains configuration for running integration tests using [`molecule`](https://molecule.readthedocs.io/).
You can run the `molecule` integration tests with the command:
make test-integration
These commands will create a directory called `ansible_collections` which should not be committed or added to the `.gitignore` (Tracking issue: https://github.com/ansible/ansible/issues/68499)
## Publishing New Versions
@@ -69,7 +76,7 @@ The current process for publishing new versions of the OKD Collection is manual,
1. Ensure you're running Ansible from devel, so the [`build_ignore` key](https://github.com/ansible/ansible/issues/67130) in `galaxy.yml` is used.
1. Run `git clean -x -d -f` in this repository's directory to clean out any extra files which should not be included.
1. Update `galaxy.yml` and this README's `requirements.yml` example with the new `version` for the collection.
1. Update `galaxy.yml`, the `Makefile`, and this README's `requirements.yml` example with the new `version` for the collection.
1. Update the CHANGELOG:
1. Make sure you have [`antsibull-changelog`](https://pypi.org/project/antsibull-changelog/) installed.
1. Make sure there are fragments for all known changes in `changelogs/fragments`.

14
ci/Dockerfile Normal file
View File

@@ -0,0 +1,14 @@
FROM registry.access.redhat.com/ubi8/ubi
RUN yum install -y make python3 python3-devel python3-pip python3-setuptools \
&& pip3 install --upgrade setuptools pip \
&& pip3 install \
openshift \
ansible \
molecule
WORKDIR /src
COPY . /src
USER 1001

View File

@@ -23,7 +23,5 @@ tags:
- openshift
- okd
- cluster
# Also needs to be updated in the Makefile
version: 0.1.0
build_ignore:
- .DS_Store
- '*.tar.gz'

View File

@@ -0,0 +1,59 @@
---
- name: Converge
hosts: localhost
connection: local
gather_facts: no
vars:
ansible_python_interpreter: '{{ virtualenv_interpreter }}'
tasks:
# OpenShift Resources
- name: Create a project
community.okd.k8s:
name: testing
kind: Project
api_version: project.openshift.io/v1
apply: no
register: output
- name: show output
debug:
var: output
- name: Create deployment config
community.okd.k8s:
state: present
inline: &dc
apiVersion: v1
kind: DeploymentConfig
metadata:
name: elastic
labels:
app: galaxy
service: elastic
namespace: testing
spec:
template:
metadata:
labels:
app: galaxy
service: elastic
spec:
containers:
- name: elastic
volumeMounts:
- mountPath: /usr/share/elasticsearch/data
name: elastic-volume
command: ['elasticsearch']
image: 'ansible/galaxy-elasticsearch:2.4.6'
volumes:
- name: elastic-volume
persistentVolumeClaim:
claimName: elastic-volume
replicas: 1
strategy:
type: Rolling
register: output
- name: Show output
debug:
var: output

View File

@@ -0,0 +1,6 @@
---
- name: Destroy
hosts: localhost
connection: local
gather_facts: no
tasks: []

View File

@@ -1,5 +1,5 @@
---
apiVersion: extensions/v1beta1
apiVersion: apps/v1
kind: Deployment
metadata:
labels:

View File

@@ -1,5 +1,5 @@
---
apiVersion: extensions/v1beta1
apiVersion: apps/v1
kind: Deployment
metadata:
labels:

View File

@@ -0,0 +1,38 @@
---
dependency:
name: galaxy
driver:
name: delegated
platforms:
- name: cluster
groups:
- k8s
provisioner:
name: ansible
lint: |
set -e
ansible-lint
inventory:
host_vars:
localhost:
virtualenv: ${MOLECULE_EPHEMERAL_DIRECTORY}/virtualenv
virtualenv_command: '{{ ansible_playbook_python }} -m virtualenv'
virtualenv_interpreter: '{{ virtualenv }}/bin/python'
playbook_namespace: molecule-tests
env:
ANSIBLE_FORCE_COLOR: 'true'
ANSIBLE_COLLECTIONS_PATHS: ${MOLECULE_PROJECT_DIRECTORY}
verifier:
name: ansible
lint: |
set -e
ansible-lint
scenario:
name: default
test_sequence:
- lint
- syntax
- prepare
- converge
- idempotence
- verify

View File

@@ -0,0 +1,17 @@
---
- name: Prepare
hosts: localhost
connection: local
gather_facts: no
tasks:
- pip:
name: virtualenv
- pip:
name:
- openshift>=0.9.2
- coverage
virtualenv: "{{ virtualenv }}"
virtualenv_command: "{{ virtualenv_command }}"
virtualenv_site_packages: no

View File

@@ -1,16 +1,13 @@
---
- block:
- name: Create a namespace
community.kubernetes.k8s:
- name: Create a project
community.okd.k8s:
name: "{{ playbook_namespace }}"
kind: Namespace
- copy:
src: files
dest: "{{ remote_tmp_dir }}"
kind: Project
api_version: project.openshift.io/v1
- name: incredibly simple ConfigMap
community.kubernetes.k8s:
community.okd.k8s:
definition:
apiVersion: v1
kind: ConfigMap
@@ -27,16 +24,16 @@
- k8s_with_validate is successful
- name: extra property does not fail without strict
community.kubernetes.k8s:
src: "{{ remote_tmp_dir }}/files/kuard-extra-property.yml"
community.okd.k8s:
src: "files/kuard-extra-property.yml"
namespace: "{{ playbook_namespace }}"
validate:
fail_on_error: yes
strict: no
- name: extra property fails with strict
community.kubernetes.k8s:
src: "{{ remote_tmp_dir }}/files/kuard-extra-property.yml"
community.okd.k8s:
src: "files/kuard-extra-property.yml"
namespace: "{{ playbook_namespace }}"
validate:
fail_on_error: yes
@@ -50,8 +47,8 @@
- extra_property is failed
- name: invalid type fails at validation stage
community.kubernetes.k8s:
src: "{{ remote_tmp_dir }}/files/kuard-invalid-type.yml"
community.okd.k8s:
src: "files/kuard-invalid-type.yml"
namespace: "{{ playbook_namespace }}"
validate:
fail_on_error: yes
@@ -65,8 +62,8 @@
- invalid_type is failed
- name: invalid type fails with warnings when fail_on_error is False
community.kubernetes.k8s:
src: "{{ remote_tmp_dir }}/files/kuard-invalid-type.yml"
community.okd.k8s:
src: "files/kuard-invalid-type.yml"
namespace: "{{ playbook_namespace }}"
validate:
fail_on_error: no
@@ -80,16 +77,16 @@
- invalid_type_no_fail is failed
- name: setup custom resource definition
community.kubernetes.k8s:
src: "{{ remote_tmp_dir }}/files/setup-crd.yml"
community.okd.k8s:
src: "files/setup-crd.yml"
- name: wait a few seconds
pause:
seconds: 5
- name: add custom resource definition
community.kubernetes.k8s:
src: "{{ remote_tmp_dir }}/files/crd-resource.yml"
community.okd.k8s:
src: "files/crd-resource.yml"
namespace: "{{ playbook_namespace }}"
validate:
fail_on_error: yes
@@ -104,23 +101,23 @@
always:
- name: remove custom resource
community.kubernetes.k8s:
definition: "{{ lookup('file', role_path + '/files/crd-resource.yml') }}"
community.okd.k8s:
definition: "{{ lookup('file', 'files/crd-resource.yml') }}"
namespace: "{{ playbook_namespace }}"
state: absent
ignore_errors: yes
- name: remove custom resource definitions
community.kubernetes.k8s:
definition: "{{ lookup('file', role_path + '/files/setup-crd.yml') }}"
community.okd.k8s:
definition: "{{ lookup('file', 'files/setup-crd.yml') }}"
state: absent
- name: Delete namespace
community.kubernetes.k8s:
community.okd.k8s:
state: absent
definition:
- kind: Namespace
apiVersion: v1
- kind: Project
apiVersion: project.openshift.io/v1
metadata:
name: "{{ playbook_namespace }}"
ignore_errors: yes

View File

@@ -6,7 +6,7 @@
# - kubernetes
# - kubernetes-validate
- community.kubernetes.k8s:
- community.okd.k8s:
definition:
apiVersion: v1
kind: ConfigMap

View File

@@ -0,0 +1,26 @@
---
- name: Verify
hosts: localhost
connection: local
gather_facts: no
vars:
ansible_python_interpreter: '{{ virtualenv_interpreter }}'
tasks:
- pip:
name: kubernetes-validate==1.12.0
virtualenv: "{{ virtualenv }}"
virtualenv_command: "{{ virtualenv_command }}"
virtualenv_site_packages: no
- import_tasks: tasks/validate_installed.yml
- pip:
name: kubernetes-validate
state: absent
virtualenv: "{{ virtualenv }}"
virtualenv_command: "{{ virtualenv_command }}"
virtualenv_site_packages: no
- import_tasks: tasks/validate_not_installed.yml

336
plugins/modules/k8s.py Normal file
View File

@@ -0,0 +1,336 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2018, Chris Houseknecht <@chouseknecht>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
module: k8s
short_description: Manage OpenShift objects
author:
- "Chris Houseknecht (@chouseknecht)"
- "Fabian von Feilitzsch (@fabianvf)"
description:
- Use the OpenShift Python client to perform CRUD operations on K8s objects.
- Pass the object definition from a source file or inline. See examples for reading
files and using Jinja templates or vault-encrypted files.
- Access to the full range of K8s APIs.
- Use the M(k8s_info) module to obtain a list of items about an object of type C(kind)
- Authenticate using either a config file, certificates, password or token.
- Supports check mode.
- Optimized for OKD/OpenShift Kubernetes flavors
extends_documentation_fragment:
- community.kubernetes.k8s_state_options
- community.kubernetes.k8s_name_options
- community.kubernetes.k8s_resource_options
- community.kubernetes.k8s_auth_options
notes:
- If your OpenShift Python library is not 0.9.0 or newer and you are trying to
remove an item from an associative array/dictionary, for example a label or
an annotation, you will need to explicitly set the value of the item to be
removed to `null`. Simply deleting the entry in the dictionary will not
remove it from openshift or kubernetes.
options:
merge_type:
description:
- Whether to override the default patch merge approach with a specific type. By default, the strategic
merge will typically be used.
- For example, Custom Resource Definitions typically aren't updatable by the usual strategic merge. You may
want to use C(merge) if you see "strategic merge patch format is not supported"
- See U(https://kubernetes.io/docs/tasks/run-application/update-api-object-kubectl-patch/#use-a-json-merge-patch-to-update-a-deployment)
- Requires openshift >= 0.6.2
- If more than one merge_type is given, the merge_types will be tried in order
- If openshift >= 0.6.2, this defaults to C(['strategic-merge', 'merge']), which is ideal for using the same parameters
on resource kinds that combine Custom Resources and built-in resources. For openshift < 0.6.2, the default
is simply C(strategic-merge).
- mutually exclusive with C(apply)
choices:
- json
- merge
- strategic-merge
type: list
elements: str
wait:
description:
- Whether to wait for certain resource kinds to end up in the desired state. By default the module exits once Kubernetes has
received the request
- Implemented for C(state=present) for C(Deployment), C(DaemonSet) and C(Pod), and for C(state=absent) for all resource kinds.
- For resource kinds without an implementation, C(wait) returns immediately unless C(wait_condition) is set.
default: no
type: bool
wait_sleep:
description:
- Number of seconds to sleep between checks.
default: 5
type: int
wait_timeout:
description:
- How long in seconds to wait for the resource to end up in the desired state. Ignored if C(wait) is not set.
default: 120
type: int
wait_condition:
description:
- Specifies a custom condition on the status to wait for. Ignored if C(wait) is not set or is set to False.
suboptions:
type:
type: str
description:
- The type of condition to wait for. For example, the C(Pod) resource will set the C(Ready) condition (among others)
- Required if you are specifying a C(wait_condition). If left empty, the C(wait_condition) field will be ignored.
- The possible types for a condition are specific to each resource type in Kubernetes. See the API documentation of the status field
for a given resource to see possible choices.
status:
type: str
description:
- The value of the status field in your desired condition.
- For example, if a C(Deployment) is paused, the C(Progressing) C(type) will have the C(Unknown) status.
choices:
- True
- False
- Unknown
default: "True"
reason:
type: str
description:
- The value of the reason field in your desired condition
- For example, if a C(Deployment) is paused, The C(Progressing) C(type) will have the C(DeploymentPaused) reason.
- The possible reasons in a condition are specific to each resource type in Kubernetes. See the API documentation of the status field
for a given resource to see possible choices.
type: dict
validate:
description:
- how (if at all) to validate the resource definition against the kubernetes schema.
Requires the kubernetes-validate python module
suboptions:
fail_on_error:
description: whether to fail on validation errors.
type: bool
version:
description: version of Kubernetes to validate against. defaults to Kubernetes server version
type: str
strict:
description: whether to fail when passing unexpected properties
default: True
type: bool
type: dict
append_hash:
description:
- Whether to append a hash to a resource name for immutability purposes
- Applies only to ConfigMap and Secret resources
- The parameter will be silently ignored for other resource kinds
- The full definition of an object is needed to generate the hash - this means that deleting an object created with append_hash
will only work if the same object is passed with state=absent (alternatively, just use state=absent with the name including
the generated hash and append_hash=no)
type: bool
apply:
description:
- C(apply) compares the desired resource definition with the previously supplied resource definition,
ignoring properties that are automatically generated
- C(apply) works better with Services than 'force=yes'
- mutually exclusive with C(merge_type)
type: bool
requirements:
- "python >= 2.7"
- "openshift >= 0.6"
- "PyYAML >= 3.11"
'''
EXAMPLES = '''
- name: Create a k8s namespace
community.okd.k8s:
name: testing
api_version: v1
kind: Namespace
state: present
- name: Create a Service object from an inline definition
community.okd.k8s:
state: present
definition:
apiVersion: v1
kind: Service
metadata:
name: web
namespace: testing
labels:
app: galaxy
service: web
spec:
selector:
app: galaxy
service: web
ports:
- protocol: TCP
targetPort: 8000
name: port-8000-tcp
port: 8000
- name: Remove an existing Service object
community.okd.k8s:
state: absent
api_version: v1
kind: Service
namespace: testing
name: web
# Passing the object definition from a file
- name: Create a Deployment by reading the definition from a local file
community.okd.k8s:
state: present
src: /testing/deployment.yml
- name: >-
Read definition file from the Ansible controller file system.
If the definition file has been encrypted with Ansible Vault it will automatically be decrypted.
community.okd.k8s:
state: present
definition: "{{ lookup('file', '/testing/deployment.yml') | from_yaml }}"
- name: Read definition file from the Ansible controller file system after Jinja templating
community.okd.k8s:
state: present
definition: "{{ lookup('template', '/testing/deployment.yml') | from_yaml }}"
- name: fail on validation errors
community.okd.k8s:
state: present
definition: "{{ lookup('template', '/testing/deployment.yml') | from_yaml }}"
validate:
fail_on_error: yes
- name: warn on validation errors, check for unexpected properties
community.okd.k8s:
state: present
definition: "{{ lookup('template', '/testing/deployment.yml') | from_yaml }}"
validate:
fail_on_error: no
strict: yes
'''
RETURN = '''
result:
description:
- The created, patched, or otherwise present object. Will be empty in the case of a deletion.
returned: success
type: complex
contains:
api_version:
description: The versioned schema of this representation of an object.
returned: success
type: str
kind:
description: Represents the REST resource this object represents.
returned: success
type: str
metadata:
description: Standard object metadata. Includes name, namespace, annotations, labels, etc.
returned: success
type: complex
spec:
description: Specific attributes of the object. Will vary based on the I(api_version) and I(kind).
returned: success
type: complex
status:
description: Current status details for the object.
returned: success
type: complex
items:
description: Returned only when multiple yaml documents are passed to src or resource_definition
returned: when resource_definition or src contains list of objects
type: list
duration:
description: elapsed time of task in seconds
returned: when C(wait) is true
type: int
sample: 48
'''
import traceback
from ansible.module_utils._text import to_native
try:
from ansible_collections.community.kubernetes.plugins.module_utils.raw import KubernetesRawModule
HAS_KUBERNETES_COLLECTION = True
except ImportError as e:
HAS_KUBERNETES_COLLECTION = False
k8s_collection_import_exception = e
K8S_COLLECTION_ERROR = traceback.format_exc()
from ansible.module_utils.basic import AnsibleModule as KubernetesRawModule
try:
from openshift.dynamic.exceptions import DynamicApiError, NotFoundError, ForbiddenError
except ImportError:
# Exceptions handled in common
pass
class OKDRawModule(KubernetesRawModule):
def __init__(self):
if not HAS_KUBERNETES_COLLECTION:
self.fail_json(
msg="The community.kubernetes collection must be installed",
exception=K8S_COLLECTION_ERROR,
error=to_native(k8s_collection_import_exception)
)
super(OKDRawModule, self).__init__()
def perform_action(self, resource, definition):
state = self.params.get('state', None)
name = definition['metadata'].get('name')
namespace = definition['metadata'].get('namespace')
if definition['kind'] in ['Project', 'ProjectRequest'] and state != 'absent':
try:
resource.get(name, namespace)
except (NotFoundError, ForbiddenError):
return self.create_project_request(definition)
except DynamicApiError as exc:
self.fail_json(msg='Failed to retrieve requested object: {0}'.format(exc.body),
error=exc.status, status=exc.status, reason=exc.reason)
return super(OKDRawModule, self).perform_action(resource, definition)
def create_project_request(self, definition):
definition['kind'] = 'ProjectRequest'
result = {'changed': False, 'result': {}}
resource = self.find_resource('ProjectRequest', definition['apiVersion'], fail=True)
if not self.check_mode:
try:
k8s_obj = resource.create(definition)
result['result'] = k8s_obj.to_dict()
except DynamicApiError as exc:
self.fail_json(msg="Failed to create object: {0}".format(exc.body),
error=exc.status, status=exc.status, reason=exc.reason)
result['changed'] = True
result['method'] = 'create'
return result
def main():
OKDRawModule().execute_module()
if __name__ == '__main__':
main()

View File

@@ -1,2 +0,0 @@
---
k8s_openshift: true

View File

@@ -1,6 +0,0 @@
---
- name: delete temporary directory
file:
path: "{{ remote_tmp_dir }}"
state: absent
no_log: yes

View File

@@ -1,3 +0,0 @@
# README
The `test_tempfile.py` module added here is only used for the `setup_remote_tmp_dir.yml` temporary directory setup task. It is a clone of the `tempfile.py` community-supported Ansible module, and has to be included with the tests here because it is not available in the `ansible-base` distribution against which this collection is tested.

View File

@@ -1,121 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) 2016, Krzysztof Magosa <krzysztof@magosa.pl>
# Copyright: (c) 2017, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
DOCUMENTATION = '''
---
module: test_tempfile
short_description: Creates temporary files and directories
description:
- The C(test_tempfile) module creates temporary files and directories. C(mktemp) command takes different parameters on various systems, this module helps
to avoid troubles related to that. Files/directories created by module are accessible only by creator. In case you need to make them world-accessible
you need to use M(ansible.builtin.file) module.
- For Windows targets, use the M(ansible.builtin.win_tempfile) module instead.
options:
state:
description:
- Whether to create file or directory.
type: str
choices: [ directory, file ]
default: file
path:
description:
- Location where temporary file or directory should be created.
- If path is not specified, the default system temporary directory will be used.
type: path
prefix:
description:
- Prefix of file/directory name created by module.
type: str
default: ansible.
suffix:
description:
- Suffix of file/directory name created by module.
type: str
default: ""
seealso:
- module: file
- module: win_tempfile
author:
- Krzysztof Magosa (@krzysztof-magosa)
'''
EXAMPLES = """
- name: create temporary build directory
test_tempfile:
state: directory
suffix: build
- name: create temporary file
test_tempfile:
state: file
suffix: temp
register: tempfile_1
- name: use the registered var and the file module to remove the temporary file
file:
path: "{{ tempfile_1.path }}"
state: absent
when: tempfile_1.path is defined
"""
RETURN = '''
path:
description: Path to created file or directory
returned: success
type: str
sample: "/tmp/ansible.bMlvdk"
'''
from os import close
from tempfile import mkstemp, mkdtemp
from traceback import format_exc
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils._text import to_native
def main():
module = AnsibleModule(
argument_spec=dict(
state=dict(type='str', default='file', choices=['file', 'directory']),
path=dict(type='path'),
prefix=dict(type='str', default='ansible.'),
suffix=dict(type='str', default=''),
),
)
try:
if module.params['state'] == 'file':
handle, path = mkstemp(
prefix=module.params['prefix'],
suffix=module.params['suffix'],
dir=module.params['path'],
)
close(handle)
elif module.params['state'] == 'directory':
path = mkdtemp(
prefix=module.params['prefix'],
suffix=module.params['suffix'],
dir=module.params['path'],
)
module.exit_json(changed=True, path=path)
except Exception as e:
module.fail_json(msg=to_native(e), exception=format_exc())
if __name__ == '__main__':
main()

View File

@@ -1,2 +0,0 @@
---
dependencies: []

View File

@@ -1,50 +0,0 @@
---
- include_tasks: setup_remote_tmp_dir.yml
- set_fact:
virtualenv: "{{ remote_tmp_dir }}/virtualenv"
virtualenv_command: "{{ ansible_python_interpreter }} -m virtualenv"
- set_fact:
virtualenv_interpreter: "{{ virtualenv }}/bin/python"
- pip:
name: virtualenv
# Test graceful failure for older versions of openshift
- pip:
name:
- openshift==0.6.0
- kubernetes==6.0.0
- coverage
virtualenv: "{{ virtualenv }}"
virtualenv_command: "{{ virtualenv_command }}"
virtualenv_site_packages: no
- include_tasks: older_openshift_fail.yml
vars:
ansible_python_interpreter: "{{ virtualenv_interpreter }}"
playbook_namespace: ansible-test-k8s-older-openshift
- file:
path: "{{ virtualenv }}"
state: absent
no_log: yes
# Test openshift
- debug:
var: k8s_openshift
- pip:
name:
- kubernetes-validate==1.12.0
- openshift>=0.9.2
- coverage
virtualenv: "{{ virtualenv }}"
virtualenv_command: "{{ virtualenv_command }}"
virtualenv_site_packages: no
- include: openshift.yml
when: k8s_openshift | bool

View File

@@ -1,71 +0,0 @@
---
# TODO: Not available in ansible-base
# - python_requirements_info:
# dependencies:
# - openshift==0.6.0
# - kubernetes==6.0.0
# append_hash
- name: use append_hash with ConfigMap
community.kubernetes.k8s:
definition:
metadata:
name: config-map-test
namespace: "{{ playbook_namespace }}"
apiVersion: v1
kind: ConfigMap
data:
hello: world
append_hash: yes
ignore_errors: yes
register: k8s_append_hash
- name: assert that append_hash fails gracefully
assert:
that:
- k8s_append_hash is failed
- "'Failed to import the required Python library (openshift >= 0.7.2)' in k8s_append_hash.msg"
- "'. This is required for append_hash.' in k8s_append_hash.msg"
# validate
- name: attempt to use validate with older openshift
community.kubernetes.k8s:
definition:
metadata:
name: config-map-test
namespace: "{{ playbook_namespace }}"
apiVersion: v1
kind: ConfigMap
data:
hello: world
validate:
fail_on_error: yes
ignore_errors: yes
register: k8s_validate
- name: assert that validate fails gracefully
assert:
that:
- k8s_validate is failed
- "k8s_validate.msg == 'openshift >= 0.8.0 is required for validate'"
# apply
- name: attempt to use apply with older openshift
community.kubernetes.k8s:
definition:
metadata:
name: config-map-test
namespace: "{{ playbook_namespace }}"
apiVersion: v1
kind: ConfigMap
data:
hello: world
apply: yes
ignore_errors: yes
register: k8s_apply
- name: assert that apply fails gracefully
assert:
that:
- k8s_apply is failed
- "k8s_apply.msg.startswith('Failed to import the required Python library (openshift >= 0.9.2)')"

View File

@@ -1,62 +0,0 @@
---
# OpenShift Resources
- name: Create a project
community.kubernetes.k8s:
name: testing
kind: Project
api_version: v1
apply: no
register: output
- name: show output
debug:
var: output
- name: Create deployment config
community.kubernetes.k8s:
state: present
inline: &dc
apiVersion: v1
kind: DeploymentConfig
metadata:
name: elastic
labels:
app: galaxy
service: elastic
namespace: testing
spec:
template:
metadata:
labels:
app: galaxy
service: elastic
spec:
containers:
- name: elastic
volumeMounts:
- mountPath: /usr/share/elasticsearch/data
name: elastic-volume
command: ['elasticsearch']
image: 'ansible/galaxy-elasticsearch:2.4.6'
volumes:
- name: elastic-volume
persistentVolumeClaim:
claimName: elastic-volume
replicas: 1
strategy:
type: Rolling
register: output
- name: Show output
debug:
var: output
- name: Create deployment config again
community.kubernetes.k8s:
state: present
inline: *dc
register: output
- name: DC creation should be idempotent
assert:
that: not output.changed

View File

@@ -1,12 +0,0 @@
---
- name: create temporary directory
test_tempfile:
state: directory
suffix: .test
register: remote_tmp_dir
notify:
- delete temporary directory
- name: record temporary directory
set_fact:
remote_tmp_dir: "{{ remote_tmp_dir.path }}"

View File

@@ -0,0 +1,2 @@
plugins/modules/k8s.py validate-modules:parameter-type-not-in-doc
plugins/modules/k8s.py validate-modules:return-syntax-error

View File

@@ -0,0 +1,2 @@
plugins/modules/k8s.py validate-modules:parameter-type-not-in-doc
plugins/modules/k8s.py validate-modules:return-syntax-error

View File

@@ -0,0 +1 @@
plugins/modules/k8s.py validate-modules:parameter-type-not-in-doc