Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,55 @@ Updating the generated client requires the following tools:
1) Incorporate new changes to update scripts
- scripts/constants.py, scripts/pom.xml, scripts/preprocess_spec.py, update-client.sh are the most important
1) Run tox -e update_client

## Ansible Modules

This repo is home to the tools used to generate the K8s modules for Ansible.

### Using the modules

The modules are currently in pre-release. For convenience there is an Ansible role available at [ansible/ansible-kubernetes-modules](https://github.com/ansible/ansible-kubernetes-modules), which if referenced in a playbook, will provide full access to the latest.

#### Requirements

- Ansible installed [from source](http://docs.ansible.com/ansible/intro_installation.html#running-from-source)
- OpenShift Rest Client installed on the host where the modules will execute

#### Installation and use

Using the Galaxy client, download and install the role as follows:

```
$ ansible-galaxy install ansible.ansible-kubernetes-modules
```

Include the role in your playbook, and the modules will be available, allowing tasks from any other play or role to reference them. Here's an example:

```
- hosts: localhost
connection: local
gather_facts: no
roles:
- role: ansible.ansible-kubernetes-modules
- role: hello-world
```

The `hello-world` role deploys an application to a locally running OpenShift instance by executing tasks with the modules. It's able to access them because `ansible.ansible-kubernetes-modules` is referenced.

You'll find the modules in the [library](https://github.com/ansible/ansible-kubernetes-modules/tree/master/library) folder of the role. Each contains documented parameters, and the returned data structure. Not every module contains examples, only those where we have added [test data](./openshift/ansiblegen/examples).

If you find a bug, or have a suggestion, related to the modules, please [file an issue here](https://github.com/openshift/openshift-restclient-python/issues)

### Generating the modules

After installing the OpenShift client, the modules can be generated by running the following:

```
$ openshift-ansible-gen modules --output-path /path/to/modules/dir
```

If `--output-path` is not provided, modules will be written to `./_modules`.

### Common module

Individual modules are generated using the OpenShift Rest Client. However, there is a shared or utility module in the [Ansible repo](https://github.com/ansible/ansible) called, *k8s_common.py*, which imports the client, and performs most of the work. This is currently in a pre-release state as well, and is only available in the `devel` branch of Ansible. For this reason, you'll need to run Ansible from source. For assistnace, see [Running from source](http://docs.ansible.com/ansible/intro_installation.html#running-from-source).
4 changes: 4 additions & 0 deletions openshift/ansiblegen/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
'level': 'INFO',
'propagate': False
},
'openshift.helper.ansible': {
'level': 'ERROR',
'propogate': False
}
},
'root': {
'handlers': ['console'],
Expand Down
4 changes: 2 additions & 2 deletions openshift/ansiblegen/docstrings.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def __init__(self, model, api_version):
self.model = model
self.api_version = api_version
try:
self.helper = AnsibleModuleHelper(self.api_version, self.model)
self.helper = AnsibleModuleHelper(self.api_version, self.model, debug=True)
except OpenShiftException:
raise

Expand Down Expand Up @@ -105,7 +105,7 @@ def add_option(pname, pdict, descr=None):
obj = self.helper.model()
for path in param_dict['property_path']:
kind = obj.swagger_types[path]
if kind in ('str', 'bool', 'int') or \
if kind in ('str', 'bool', 'int', 'IntstrIntOrString') or \
kind.startswith('dict(') or \
kind.startswith('list['):
docs = inspect.getdoc(getattr(type(obj), path))
Expand Down
9 changes: 4 additions & 5 deletions openshift/ansiblegen/examples/v1_route.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,15 @@
tls_termination: edge
tls_key: |-
-----BEGIN PRIVATE KEY-----
asjdflajd0fjasldjflsjflkjlkjfaljsdfljasljflasjfljsdf
sdlfjalsdjfljasdfljsljfljsfljdf
key_file_contents
-----END PRIVATE KEY-----
tls_certificate: |-
-----BEGIN CERTIFICATE-----
kdlslfsfljetuoeiursljflsdjffljsfsf90909wrjf94lsjdf99KK
certificate contents
-----END CERTIFICATE-----
tls_ca_certificate: |-
-----BEGIN CERTIFICATE-----
asdfajflasfjfsljlrjlrjlsjfoijlsornkvksflsbgoehfflf54444
ca_certificate_contents
-----END CERTIFICATE-----
name: Create route

Expand All @@ -32,7 +31,7 @@
spec_to_name: other-service-name
tls_destination_ca_certificate: |-
-----BEGIN CERTIFICATE-----
destination cetricate_contents
destination_cetricate_contents
-----END CERTIFICATE-----
name: Patch route

Expand Down
16 changes: 11 additions & 5 deletions openshift/helper/ansible.py
Original file line number Diff line number Diff line change
Expand Up @@ -565,11 +565,12 @@ def __transform_properties(self, properties, prefix='', path=None, alternate_pre
:param alternate_prefix: a more minimal version of prefix
:return: dict
"""
primitive_types = ('int', 'str', 'bool', 'list', 'dict', 'IntstrIntOrString')
args = {}

if path is None:
path = []

args = {}

def add_meta(prop_name, prop_prefix, prop_alt_prefix):
""" Adds metadata properties to the argspec """
if prop_alt_prefix != prop_prefix:
Expand All @@ -583,6 +584,7 @@ def add_meta(prop_name, prop_prefix, prop_alt_prefix):
args[prop_prefix + prop_name]['property_path'] = prop_paths

for prop, prop_attributes in properties.items():
logger.debug("Prop: {0} attributes: {1}".format(prop, str(prop_attributes)))
if prop in ('api_version', 'status', 'kind', 'items') and not prefix:
# Don't expose these properties
continue
Expand Down Expand Up @@ -619,8 +621,7 @@ def add_meta(prop_name, prop_prefix, prop_alt_prefix):
'required': True,
}
add_meta('name', meta_prefix, meta_alt_prefix)
elif prop_attributes['class'].__name__ not in ('int', 'str', 'bool', 'list', 'dict') and \
not prop.endswith('params'):
elif prop_attributes['class'].__name__ not in primitive_types and not prop.endswith('params'):
# Adds nested properties recursively

label = prop
Expand Down Expand Up @@ -660,9 +661,14 @@ def add_meta(prop_name, prop_prefix, prop_alt_prefix):
arg_alt_prefix = alternate_prefix + '_' if alternate_prefix else ''
paths = copy.copy(path)
paths.append(prop)

property_type = prop_attributes['class'].__name__
if property_type == 'IntstrIntOrString':
property_type = 'str'

args[arg_prefix + prop] = {
'required': False,
'type': prop_attributes['class'].__name__,
'type': property_type,
'property_path': paths
}

Expand Down