diff --git a/README.md b/README.md index 3d7784c6..56da250e 100644 --- a/README.md +++ b/README.md @@ -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). diff --git a/openshift/ansiblegen/cli.py b/openshift/ansiblegen/cli.py index 89257665..387c2cb6 100644 --- a/openshift/ansiblegen/cli.py +++ b/openshift/ansiblegen/cli.py @@ -33,6 +33,10 @@ 'level': 'INFO', 'propagate': False }, + 'openshift.helper.ansible': { + 'level': 'ERROR', + 'propogate': False + } }, 'root': { 'handlers': ['console'], diff --git a/openshift/ansiblegen/docstrings.py b/openshift/ansiblegen/docstrings.py index a37acbea..409572ca 100644 --- a/openshift/ansiblegen/docstrings.py +++ b/openshift/ansiblegen/docstrings.py @@ -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 @@ -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)) diff --git a/openshift/ansiblegen/examples/v1_route.yml b/openshift/ansiblegen/examples/v1_route.yml index ef2c6da2..c79fc1ad 100644 --- a/openshift/ansiblegen/examples/v1_route.yml +++ b/openshift/ansiblegen/examples/v1_route.yml @@ -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 @@ -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 diff --git a/openshift/helper/ansible.py b/openshift/helper/ansible.py index 06ae7d63..64cf594e 100644 --- a/openshift/helper/ansible.py +++ b/openshift/helper/ansible.py @@ -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: @@ -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 @@ -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 @@ -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 }