diff options
-rw-r--r-- | ansible/library/rancher1_api.py | 598 | ||||
-rw-r--r-- | ansible/roles/rancher/defaults/main.yml | 27 | ||||
-rw-r--r-- | ansible/roles/rancher/tasks/rancher_server.yml | 54 | ||||
-rw-r--r-- | build/data_lists/onap_3.0.2-docker_images.list | 220 |
4 files changed, 899 insertions, 0 deletions
diff --git a/ansible/library/rancher1_api.py b/ansible/library/rancher1_api.py new file mode 100644 index 00000000..5d74da1e --- /dev/null +++ b/ansible/library/rancher1_api.py @@ -0,0 +1,598 @@ +#!/usr/bin/python + +from ansible.module_utils.basic import AnsibleModule + +import requests +import json +import functools +import time + +DOCUMENTATION = """ +--- +module: rancher1_api +short_description: Client library for rancher API +description: + - This module modifies a rancher 1.6 using it's API (v1). + - It supports some rancher features by the virtue of a 'mode'. + - 'modes' hide from you some necessary cruft and expose you to the only + important and interestig variables wich must be set. The mode mechanism + makes this module more easy to use and you don't have to create an + unnecessary boilerplate for the API. + - Only a few modes are/will be implemented so far - as they are/will be + needed. In the future the 'raw' mode can be added to enable you to craft + your own API requests, but that would be on the same level of a user + experience as running curl commands, and because the rancher 1.6 is already + obsoleted by the project, it would be a wasted effort. +options: + rancher: + description: + - The domain name or the IP address and the port of the rancher + where API is exposed. + - For example: http://10.0.0.1:8080 + required: true + aliases: + - server + - rancher_server + - rancher_api + - api + account_key: + description: + - The public and secret part of the API key-pair separated by colon. + - You can find all your keys in web UI. + - For example: + B1716C4133D3825051CB:3P2eb3QhokFKYUiXRNZLxvGNSRYgh6LHjuMicCHQ + required: false + mode: + description: + - A recognized mode how to deal with some concrete configuration task + in rancher API to ease the usage. + - The implemented modes so far are: + 'settings': + Many options under <api_server>/v1/settings API url and some can + be seen also under advanced options in the web UI. + 'access_control': + It setups user and password for the account (defaults to 'admin') + and it enables the local authentication - so the web UI and API + will require username/password (UI) or apikey (API). + required: true + aliases: + - rancher_mode + - api_mode + choices: + - settings + - access_control + data: + description: + - Dictionary with key/value pairs. The actual names and meaning of pairs + depends on the used mode. + - settings mode: + option - Option/path in JSON API (url). + value - A new value to replace the current one. + - access_control mode: + account_id - The unique ID of the account - the default rancher admin + has '1a1'. Better way would be to just create arbitrary username and + set credentials for that, but due to time constraints, the route with + an ID is simpler. The designated '1a1' could be hardcoded and hidden + but if the user will want to use some other account (there are many), + then it can be just changed to some other ID. + password - A new password in a plaintext. + required: true + timeout: + description: + - How long in seconds to wait for a response before raising error + required: false + default: 10.0 +""" + +default_timeout = 10.0 + + +class ModeError(Exception): + pass + + +def _decorate_rancher_api_request(request_method): + + @functools.wraps(request_method) + def wrap_request(*args, **kwargs): + + response = request_method(*args, **kwargs) + authorized = True + + if response.status_code == 401: + authorized = False + elif response.status_code != requests.codes.ok: + response.raise_for_status() + + try: + json_data = response.json() + except Exception: + json_data = None + + return json_data, authorized + + return wrap_request + + +@_decorate_rancher_api_request +def get_rancher_api_value(url, headers=None, timeout=default_timeout, + username=None, password=None): + + if username and password: + return requests.get(url, headers=headers, + timeout=timeout, + allow_redirects=False, + auth=(username, password)) + else: + return requests.get(url, headers=headers, + timeout=timeout, + allow_redirects=False) + + +@_decorate_rancher_api_request +def set_rancher_api_value(url, payload, headers=None, timeout=default_timeout, + username=None, password=None, method='PUT'): + + if method == 'PUT': + request_set_method = requests.put + elif method == 'POST': + request_set_method = requests.post + else: + raise ModeError('ERROR: Wrong request method: %s' % str(method)) + + if username and password: + return request_set_method(url, headers=headers, + timeout=timeout, + allow_redirects=False, + data=json.dumps(payload), + auth=(username, password)) + else: + return request_set_method(url, headers=headers, + timeout=timeout, + allow_redirects=False, + data=json.dumps(payload)) + + +def create_rancher_api_url(server, mode, option): + request_url = server.strip('/') + '/v1/' + + if mode == 'raw': + request_url += option.strip('/') + elif mode == 'settings': + request_url += 'settings/' + option.strip('/') + elif mode == 'access_control': + request_url += option.strip('/') + + return request_url + + +def get_keypair(keypair): + if keypair: + keypair = keypair.split(':') + if len(keypair) == 2: + return keypair[0], keypair[1] + + return None, None + + +def mode_access_control(api_url, data=None, headers=None, + timeout=default_timeout, access_key=None, + secret_key=None, dry_run=False): + + # returns true if local auth was enabled or false if passwd changed + def is_admin_enabled(json_data, password): + try: + if json_data['type'] == "localAuthConfig" and \ + json_data['accessMode'] == "unrestricted" and \ + json_data['username'] == "admin" and \ + json_data['password'] == password and \ + json_data['enabled']: + return True + except Exception: + pass + + try: + if json_data['type'] == "error" and \ + json_data['code'] == "IncorrectPassword": + return False + except Exception: + pass + + # this should never happen + raise ModeError('ERROR: Unknown status of the local authentication') + + def create_localauth_payload(password): + payload = { + "enabled": True, + "accessMode": "unrestricted", + "username": "admin", + "password": password + } + + return payload + + def get_admin_password_id(): + # assemble request URL + request_url = api_url + 'accounts/' + data['account_id'].strip('/') \ + + '/credentials' + + # API get current value + try: + json_response, authorized = \ + get_rancher_api_value(request_url, + username=access_key, + password=secret_key, + headers=headers, + timeout=timeout) + except requests.HTTPError as e: + raise ModeError(str(e)) + except requests.Timeout as e: + raise ModeError(str(e)) + + if not authorized or not json_response: + raise ModeError('ERROR: BAD RESPONSE (GET) - no json value in ' + + 'the response') + + try: + for item in json_response['data']: + if item['type'] == 'password' and \ + item['accountId'] == data['account_id']: + return item['id'] + except Exception: + pass + + return None + + def remove_password(password_id, action): + if action == 'deactivate': + action_status = 'deactivating' + elif action == 'remove': + action_status = 'removing' + + request_url = api_url + 'passwords/' + password_id + \ + '/?action=' + action + + try: + json_response, authorized = \ + set_rancher_api_value(request_url, + {}, + username=access_key, + password=secret_key, + headers=headers, + method='POST', + timeout=timeout) + except requests.HTTPError as e: + raise ModeError(str(e)) + except requests.Timeout as e: + raise ModeError(str(e)) + + if not authorized or not json_response: + raise ModeError('ERROR: BAD RESPONSE (POST) - no json value in ' + + 'the response') + + if json_response['state'] != action_status: + raise ModeError("ERROR: Failed to '%s' the password: %s" % + (action, password_id)) + + # check if data contains all required fields + try: + if not isinstance(data['account_id'], str) or data['account_id'] == '': + raise ModeError("ERROR: 'account_id' must contain an id of the " + + "affected account") + except KeyError: + raise ModeError("ERROR: Mode 'access_control' requires the field: " + + "'account_id': %s" % str(data)) + try: + if not isinstance(data['password'], str) or data['password'] == '': + raise ModeError("ERROR: 'password' must contain some password") + except KeyError: + raise ModeError("ERROR: Mode 'access_control' requires the field: " + + "'password': %s" % str(data)) + + # assemble request URL + request_url = api_url + 'localauthconfigs' + + # API get current value + try: + json_response, authorized = \ + get_rancher_api_value(request_url, + username=access_key, + password=secret_key, + headers=headers, + timeout=timeout) + except requests.HTTPError as e: + raise ModeError(str(e)) + except requests.Timeout as e: + raise ModeError(str(e)) + + if not authorized or not json_response: + raise ModeError('ERROR: BAD RESPONSE (GET) - no json value in the ' + + 'response') + + # we will check if local auth is enabled or not + enabled = False + try: + for item in json_response['data']: + if item['type'] == 'localAuthConfig' and \ + item['accessMode'] == 'unrestricted' and \ + item['enabled']: + enabled = True + break + except Exception: + enabled = False + + if dry_run: + # we will not set anything and only signal potential change + if enabled: + changed = False + else: + changed = True + else: + # we will try to enable again with the same password + localauth_payload = create_localauth_payload(data['password']) + try: + json_response, authorized = \ + set_rancher_api_value(request_url, + localauth_payload, + username=access_key, + password=secret_key, + headers=headers, + method='POST', + timeout=timeout) + except requests.HTTPError as e: + raise ModeError(str(e)) + except requests.Timeout as e: + raise ModeError(str(e)) + + # here we ignore authorized status - we will try to reset password + if not json_response: + raise ModeError('ERROR: BAD RESPONSE (POST) - no json value in ' + + 'the response') + + # we check if the admin was already set or not... + if enabled and is_admin_enabled(json_response, data['password']): + # it was enabled before and password is the same - no change + changed = False + elif is_admin_enabled(json_response, data['password']): + # we enabled it for the first time + changed = True + # ...and reset password if needed (unauthorized access) + else: + # local auth is enabled but the password differs + # we must reset the admin's password + password_id = get_admin_password_id() + + if password_id is None: + raise ModeError("ERROR: admin's password is set, but we " + + "cannot identify it") + + # One of the way to reset the password is to remove it first + # TODO - refactor this + remove_password(password_id, 'deactivate') + time.sleep(2) + remove_password(password_id, 'remove') + time.sleep(1) + + try: + json_response, authorized = \ + set_rancher_api_value(request_url, + localauth_payload, + username=access_key, + password=secret_key, + headers=headers, + method='POST', + timeout=timeout) + except requests.HTTPError as e: + raise ModeError(str(e)) + except requests.Timeout as e: + raise ModeError(str(e)) + + # finally we signal the change + changed = True + + if changed: + msg = "Local authentication is enabled, admin has assigned password" + else: + msg = "Local authentication was already enabled, admin's password " \ + + "is unchanged" + + return changed, msg + + +def mode_settings(api_url, data=None, headers=None, timeout=default_timeout, + access_key=None, secret_key=None, dry_run=False): + + def is_valid_rancher_api_option(json_data): + + try: + api_activeValue = json_data['activeValue'] + api_source = json_data['source'] + except Exception: + return False + + if api_activeValue is None and api_source is None: + return False + + return True + + def create_rancher_api_payload(json_data, new_value): + + payload = {} + differs = False + + try: + api_id = json_data['id'] + api_activeValue = json_data['activeValue'] + api_name = json_data['name'] + api_source = json_data['source'] + except Exception: + raise ValueError + + payload.update({"activeValue": api_activeValue, + "id": api_id, + "name": api_name, + "source": api_source, + "value": new_value}) + + if api_activeValue != new_value: + differs = True + + return differs, payload + + # check if data contains all required fields + try: + if not isinstance(data['option'], str) or data['option'] == '': + raise ModeError("ERROR: 'option' must contain a name of the " + + "option") + except KeyError: + raise ModeError("ERROR: Mode 'settings' requires the field: 'option': " + + "%s" % str(data)) + try: + if not isinstance(data['value'], str) or data['value'] == '': + raise ModeError("ERROR: 'value' must contain a value") + except KeyError: + raise ModeError("ERROR: Mode 'settings' requires the field: 'value': " + + "%s" % str(data)) + + # assemble request URL + request_url = api_url + 'settings/' + data['option'].strip('/') + + # API get current value + try: + json_response, authorized = \ + get_rancher_api_value(request_url, + username=access_key, + password=secret_key, + headers=headers, + timeout=timeout) + except requests.HTTPError as e: + raise ModeError(str(e)) + except requests.Timeout as e: + raise ModeError(str(e)) + + if not authorized or not json_response: + raise ModeError('ERROR: BAD RESPONSE (GET) - no json value in the ' + + 'response') + + if is_valid_rancher_api_option(json_response): + valid = True + try: + differs, payload = create_rancher_api_payload(json_response, + data['value']) + except ValueError: + raise ModeError('ERROR: INVALID JSON - missing json values in ' + + 'the response') + else: + valid = False + + if valid and differs and dry_run: + # ansible dry-run mode + changed = True + elif valid and differs: + # API set new value + try: + json_response, authorized = \ + set_rancher_api_value(request_url, + payload, + username=access_key, + password=secret_key, + headers=headers, + timeout=timeout) + except requests.HTTPError as e: + raise ModeError(str(e)) + except requests.Timeout as e: + raise ModeError(str(e)) + + if not authorized or not json_response: + raise ModeError('ERROR: BAD RESPONSE (PUT) - no json value in ' + + 'the response') + else: + changed = True + else: + changed = False + + if changed: + msg = "Option '%s' is now set to the new value: %s" \ + % (data['option'], data['value']) + else: + msg = "Option '%s' is unchanged." % (data['option']) + + return changed, msg + + +def mode_handler(server, rancher_mode, data=None, timeout=default_timeout, + account_key=None, dry_run=False): + + changed = False + msg = 'UNKNOWN: UNAPPLICABLE MODE' + + # check API key-pair + if account_key: + access_key, secret_key = get_keypair(account_key) + if not (access_key and secret_key): + raise ModeError('ERROR: INVALID API KEY-PAIR') + + # all requests share these headers + http_headers = {'Content-Type': 'application/json', + 'Accept': 'application/json'} + + # assemble API url + api_url = server.strip('/') + '/v1/' + + if rancher_mode == 'settings': + changed, msg = mode_settings(api_url, data=data, + headers=http_headers, + timeout=timeout, + access_key=access_key, + secret_key=secret_key, + dry_run=dry_run) + elif rancher_mode == 'access_control': + changed, msg = mode_access_control(api_url, data=data, + headers=http_headers, + timeout=timeout, + access_key=access_key, + secret_key=secret_key, + dry_run=dry_run) + + return changed, msg + + +def main(): + module = AnsibleModule( + argument_spec=dict( + rancher=dict(type='str', required=True, + aliases=['server', + 'rancher_api', + 'rancher_server', + 'api']), + account_key=dict(type='str', required=False), + mode=dict(required=True, + choices=['settings', 'access_control'], + aliases=['api_mode']), + data=dict(type='dict', required=True), + timeout=dict(type='float', default=default_timeout), + ), + supports_check_mode=True + ) + + rancher_server = module.params['rancher'] + rancher_account_key = module.params['account_key'] + rancher_mode = module.params['mode'] + rancher_data = module.params['data'] + rancher_timeout = module.params['timeout'] + + try: + changed, msg = mode_handler(rancher_server, + rancher_mode, + data=rancher_data, + account_key=rancher_account_key, + timeout=rancher_timeout, + dry_run=module.check_mode) + except ModeError as e: + module.fail_json(msg=str(e)) + + module.exit_json(changed=changed, msg=msg) + + +if __name__ == '__main__': + main() diff --git a/ansible/roles/rancher/defaults/main.yml b/ansible/roles/rancher/defaults/main.yml index 6ab52e64..6d354e6e 100644 --- a/ansible/roles/rancher/defaults/main.yml +++ b/ansible/roles/rancher/defaults/main.yml @@ -4,3 +4,30 @@ rancher_remove_other_env: true rancher_redeploy_k8s_env: true rancher_cluster_health_state: healthy rancher_cluster_health_check_retries: 30 +rancher: + # The following variables can be set via the UI under advanced/settings. + # All of these affect tables in the cattle db and are uninteresting + # to the user (they serve the internal logic of the cattle), but + # they can eat a lot of space when a deployment is busy or faulty. + # + # Audit-Log is the only user-facing option here and it is represented + # in the UI. + # + # Auto-purge deleted entries from most tables after this long (seconds) + main_tables_purge_after_seconds: 28800 # 8 hours + # Auto-purge Event entries after this long (seconds) + events_purge_after_seconds: 28800 # 8 hours + # Auto-purge Service Log entries after this long (seconds) + service_log_purge_after_seconds: 86400 # 1 day + # Auto-purge Audit Log entries after this long (seconds) + audit_log_purge_after_seconds: 2592000 # 30 days + + # By default we don't enable local authentication (mainly due to + # to the fact that rancher_k8s_environment.py would have to be + # rewritten completely) + # But if you don't need to run rancher_kubernetes playbook more + # than once (you should not have to under the terms of a regular + # installation), then you can safely enable it. + auth_enabled: false + # Set this password for the rancher admin account: + admin_password: "admin" diff --git a/ansible/roles/rancher/tasks/rancher_server.yml b/ansible/roles/rancher/tasks/rancher_server.yml index e1eb5a5d..4cda3722 100644 --- a/ansible/roles/rancher/tasks/rancher_server.yml +++ b/ansible/roles/rancher/tasks/rancher_server.yml @@ -32,6 +32,14 @@ delay: 5 until: env.data is defined +# There is a lack of idempotency in the previous task and so there are new api +# key-pairs created with each run. +# +# ToDo: fix idempotency of rancher role +# +# Anyway as rke will be default k8s orchestrator in Dublin, it's supposed to be +# low prio topic. The following tasks dealing with the API are ignoring this problem +# and they simply use the new created API key-pair, which is set as a fact here: - name: Set apikey values set_fact: k8s_env_id: "{{ env.data.environment.id }}" @@ -39,3 +47,49 @@ key_private: "{{ env.data.apikey.private }}" rancher_agent_image: "{{ env.data.registration_tokens.image }}" rancher_agent_reg_url: "{{ env.data.registration_tokens.reg_url }}" + +# By default disabled - when enabled this playbook cannot be run more than once. +- name: Setup rancher admin password and enable authentication + rancher1_api: + server: "{{ rancher_server_url }}" + account_key: "{{ key_public }}:{{ key_private }}" + mode: access_control + data: + account_id: 1a1 # default rancher admin account + password: "{{ rancher.admin_password }}" + when: "rancher.auth_enabled is defined and rancher.auth_enabled" + +- name: Configure the size of the rancher cattle db and logs + block: + - name: Main tables + rancher1_api: + server: "{{ rancher_server_url }}" + account_key: "{{ key_public }}:{{ key_private }}" + mode: settings + data: + option: main_tables.purge.after.seconds + value: "{{ rancher.main_tables_purge_after_seconds }}" + - name: Events + rancher1_api: + server: "{{ rancher_server_url }}" + account_key: "{{ key_public }}:{{ key_private }}" + mode: settings + data: + option: events.purge.after.seconds + value: "{{ rancher.events_purge_after_seconds }}" + - name: Service log + rancher1_api: + server: "{{ rancher_server_url }}" + account_key: "{{ key_public }}:{{ key_private }}" + mode: settings + data: + option: service_log.purge.after.seconds + value: "{{ rancher.service_log_purge_after_seconds }}" + - name: Audit log + rancher1_api: + server: "{{ rancher_server_url }}" + account_key: "{{ key_public }}:{{ key_private }}" + mode: settings + data: + option: audit_log.purge.after.seconds + value: "{{ rancher.audit_log_purge_after_seconds }}" diff --git a/build/data_lists/onap_3.0.2-docker_images.list b/build/data_lists/onap_3.0.2-docker_images.list new file mode 100644 index 00000000..e652a12b --- /dev/null +++ b/build/data_lists/onap_3.0.2-docker_images.list @@ -0,0 +1,220 @@ +alpine:3.6 +cassandra:2.1 +crunchydata/crunchy-pgpool:centos7-10.4-2.0.0 +crunchydata/crunchy-postgres:centos7-10.3-1.8.2 +crunchydata/crunchy-postgres:centos7-10.4-2.0.0 +docker.elastic.co/beats/filebeat:5.5.0 +docker.elastic.co/elasticsearch/elasticsearch:5.5.0 +docker.elastic.co/elasticsearch/elasticsearch:6.1.2 +docker.elastic.co/elasticsearch/elasticsearch:6.3.1 +docker.elastic.co/elasticsearch/elasticsearch-oss:6.1.3 +docker.elastic.co/kibana/kibana:5.5.0 +docker.elastic.co/kibana/kibana:6.3.1 +docker.elastic.co/logstash/logstash:5.4.3 +docker.io/aaionap/haproxy:1.2.4 +docker.io/busybox +docker.io/cdposs/zookeeper:3.4.9 +docker.io/consul:1.0.6 +docker.io/library/busybox:latest +docker.io/nginx:1.13-alpine +docker.io/ninech/netbox:v2.3.5 +docker.io/oomk8s/consul:1.0.0 +docker.io/postgres:10.2-alpine +docker.io/taskrabbit/elasticsearch-dump +gcr.io/google_samples/k8szk:v3 +gcr.io/google-samples/xtrabackup:1.0 +library/mariadb:10 +nexus3.onap.org:10001/adfinissygroup/k8s-mariadb-galera-centos:v002 +nexus3.onap.org:10001/busybox +nexus3.onap.org:10001/library/consul:1.0.6 +nexus3.onap.org:10001/library/tomcat:8.5 +nexus3.onap.org:10001/library/vault:0.10.0 +nexus3.onap.org:10001/mariadb:10.1.11 +nexus3.onap.org:10001/mariadb:10.2.14 +nexus3.onap.org:10001/onap/aaf/aaf_cass:2.1.8 +nexus3.onap.org:10001/onap/aaf/aaf_cm:2.1.8 +nexus3.onap.org:10001/onap/aaf/aaf_config:2.1.8 +nexus3.onap.org:10001/onap/aaf/aaf_fs:2.1.8 +nexus3.onap.org:10001/onap/aaf/aaf_gui:2.1.8 +nexus3.onap.org:10001/onap/aaf/aaf_hello:2.1.8 +nexus3.onap.org:10001/onap/aaf/aaf_locate:2.1.8 +nexus3.onap.org:10001/onap/aaf/aaf_oauth:2.1.8 +nexus3.onap.org:10001/onap/aaf/aaf_service:2.1.8 +nexus3.onap.org:10001/onap/aaf/distcenter:3.0.0 +nexus3.onap.org:10001/onap/aaf/sms:3.0.1 +nexus3.onap.org:10001/onap/aaf/smsquorumclient:3.0.1 +nexus3.onap.org:10001/onap/aaf/testcaservice:3.0.0 +nexus3.onap.org:10001/onap/aai/esr-gui:1.2.1 +nexus3.onap.org:10001/onap/aai/esr-server:1.2.1 +nexus3.onap.org:10001/onap/aai-graphadmin:1.0.4 +nexus3.onap.org:10001/onap/aai-resources:1.3.5 +nexus3.onap.org:10001/onap/aai-traversal:1.3.4 +nexus3.onap.org:10001/onap/admportal-sdnc-image:1.4.4 +nexus3.onap.org:10001/onap/appc-cdt-image:1.4.4 +nexus3.onap.org:10001/onap/appc-image:1.4.4 +nexus3.onap.org:10001/onap/babel:1.3.3 +nexus3.onap.org:10001/onap/ccsdk-ansible-server-image:0.3.3 +nexus3.onap.org:10001/onap/ccsdk-apps-ms-neng:0.3.3 +nexus3.onap.org:10001/onap/ccsdk-controllerblueprints:0.3.3 +nexus3.onap.org:10001/onap/ccsdk-dgbuilder-image:0.3.3 +nexus3.onap.org:10001/onap/champ:1.3.1 +nexus3.onap.org:10001/onap/clamp:3.0.4 +nexus3.onap.org:10001/onap/clamp-dashboard-kibana:3.0.4 +nexus3.onap.org:10001/onap/clamp-dashboard-logstash:3.0.4 +nexus3.onap.org:10001/onap/cli:2.0.4 +nexus3.onap.org:10001/onap/data-router:1.3.3 +nexus3.onap.org:10001/onap/dcae-be:1.3.0 +nexus3.onap.org:10001/onap/dcae-dt:1.2.0 +nexus3.onap.org:10001/onap/dcae-fe:1.3.0 +nexus3.onap.org:10001/onap/dcae-tools:1.3.0 +nexus3.onap.org:10001/onap/dcae-tosca-app:1.3.0 +nexus3.onap.org:10001/onap/dmaap/buscontroller:1.0.23 +nexus3.onap.org:10001/onap/dmaap/datarouter-node:1.0.9 +nexus3.onap.org:10001/onap/dmaap/datarouter-prov:1.0.9 +nexus3.onap.org:10001/onap/dmaap/dmaap-mr:1.1.8 +nexus3.onap.org:10001/onap/dmaap/kafka01101:0.0.1 +nexus3.onap.org:10001/onap/externalapi/nbi:3.0.2 +nexus3.onap.org:10001/onap/gizmo:1.3.2 +nexus3.onap.org:10001/onap/holmes/engine-management:1.2.2 +nexus3.onap.org:10001/onap/holmes/rule-management:1.2.3 +nexus3.onap.org:10001/onap/model-loader:1.3.2 +nexus3.onap.org:10001/onap/msb/msb_apigateway:1.2.1 +nexus3.onap.org:10001/onap/msb/msb_discovery:1.2.1 +nexus3.onap.org:10001/onap/multicloud/azure:1.2.1 +nexus3.onap.org:10001/onap/multicloud/framework:1.2.1 +nexus3.onap.org:10001/onap/multicloud/openstack-ocata:1.2.3 +nexus3.onap.org:10001/onap/multicloud/openstack-pike:1.2.3 +nexus3.onap.org:10001/onap/multicloud/openstack-windriver:1.2.3 +nexus3.onap.org:10001/onap/multicloud/vio:1.2.1 +nexus3.onap.org:10001/onap/music/cassandra_3_11:3.0.24 +nexus3.onap.org:10001/onap/music/cassandra_job:3.0.24 +nexus3.onap.org:10001/onap/music/cassandra_music:3.0.0 +nexus3.onap.org:10001/onap/music/music:3.0.24 +nexus3.onap.org:10001/onap/network-discovery:1.4.2 +nexus3.onap.org:10001/onap/oom/kube2msb:1.1.0 +nexus3.onap.org:10001/onap/optf-cmso-dbinit:1.0.1 +nexus3.onap.org:10001/onap/optf-cmso-service:1.0.1 +nexus3.onap.org:10001/onap/optf-has:1.2.5 +nexus3.onap.org:10001/onap/optf-osdf:1.2.4 +nexus3.onap.org:10001/onap/org.onap.dcaegen2.collectors.datafile.datafile-app-server:1.0.5 +nexus3.onap.org:10001/onap/org.onap.dcaegen2.collectors.hv-ves.hv-collector-main:1.0.2 +nexus3.onap.org:10001/onap/org.onap.dcaegen2.collectors.snmptrap:1.4.0 +nexus3.onap.org:10001/onap/org.onap.dcaegen2.collectors.ves.vescollector:1.3.2 +nexus3.onap.org:10001/onap/org.onap.dcaegen2.deployments.cm-container:1.4.2 +nexus3.onap.org:10001/onap/org.onap.dcaegen2.deployments.healthcheck-container:1.1.2 +nexus3.onap.org:10001/onap/org.onap.dcaegen2.deployments.k8s-bootstrap-container:1.4.5 +nexus3.onap.org:10001/onap/org.onap.dcaegen2.deployments.redis-cluster-container:1.0.0 +nexus3.onap.org:10001/onap/org.onap.dcaegen2.deployments.tca-cdap-container:1.1.0 +nexus3.onap.org:10001/onap/org.onap.dcaegen2.platform.configbinding.app-app:2.2.3 +nexus3.onap.org:10001/onap/org.onap.dcaegen2.platform.deployment-handler:3.0.3 +nexus3.onap.org:10001/onap/org.onap.dcaegen2.platform.inventory-api:3.0.4 +nexus3.onap.org:10001/onap/org.onap.dcaegen2.platform.policy-handler:4.4.0 +nexus3.onap.org:10001/onap/org.onap.dcaegen2.platform.servicechange-handler:1.1.5 +nexus3.onap.org:10001/onap/org.onap.dcaegen2.services.prh.prh-app-server:1.1.1 +nexus3.onap.org:10001/onap/policy-apex-pdp:2.0.4 +nexus3.onap.org:10001/onap/policy-distribution:2.0.5 +nexus3.onap.org:10001/onap/policy-drools:1.3.6 +nexus3.onap.org:10001/onap/policy-pe:1.3.6 +nexus3.onap.org:10001/onap/pomba-aai-context-builder:1.3.2 +nexus3.onap.org:10001/onap/pomba-context-aggregator:1.3.4 +nexus3.onap.org:10001/onap/pomba-network-discovery-context-builder:1.3.1 +nexus3.onap.org:10001/onap/pomba-sdc-context-builder:1.3.2 +nexus3.onap.org:10001/onap/portal-app:2.3.1 +nexus3.onap.org:10001/onap/portal-db:2.3.1 +nexus3.onap.org:10001/onap/portal-sdk:2.3.1 +nexus3.onap.org:10001/onap/portal-wms:2.3.1 +nexus3.onap.org:10001/onap/sdc-backend:1.3.6 +nexus3.onap.org:10001/onap/sdc-backend-init:1.3.6 +nexus3.onap.org:10001/onap/sdc-cassandra:1.3.6 +nexus3.onap.org:10001/onap/sdc-cassandra-init:1.3.6 +nexus3.onap.org:10001/onap/sdc-elasticsearch:1.3.6 +nexus3.onap.org:10001/onap/sdc-frontend:1.3.6 +nexus3.onap.org:10001/onap/sdc-init-elasticsearch:1.3.6 +nexus3.onap.org:10001/onap/sdc-kibana:1.3.6 +nexus3.onap.org:10001/onap/sdc-onboard-backend:1.3.6 +nexus3.onap.org:10001/onap/sdc-onboard-cassandra-init:1.3.6 +nexus3.onap.org:10001/onap/sdnc-ansible-server-image:1.4.4 +nexus3.onap.org:10001/onap/sdnc-dmaap-listener-image:1.4.4 +nexus3.onap.org:10001/onap/sdnc-image:1.4.4 +nexus3.onap.org:10001/onap/sdnc-ueb-listener-image:1.4.4 +nexus3.onap.org:10001/onap/search-data-service:1.3.2 +nexus3.onap.org:10001/onap/service-decomposition:1.4.2 +nexus3.onap.org:10001/onap/sniroemulator:1.0.0 +nexus3.onap.org:10001/onap/so/api-handler-infra:1.3.6 +nexus3.onap.org:10001/onap/so/bpmn-infra:1.3.6 +nexus3.onap.org:10001/onap/so/catalog-db-adapter:1.3.6 +nexus3.onap.org:10001/onap/so/openstack-adapter:1.3.6 +nexus3.onap.org:10001/onap/so/request-db-adapter:1.3.6 +nexus3.onap.org:10001/onap/so/sdc-controller:1.3.6 +nexus3.onap.org:10001/onap/so/sdnc-adapter:1.3.6 +nexus3.onap.org:10001/onap/so/so-monitoring:1.3.6 +nexus3.onap.org:10001/onap/so/vfc-adapter:1.3.6 +nexus3.onap.org:10001/onap/sparky-be:1.3.2 +nexus3.onap.org:10001/onap/spike:1.3.1 +nexus3.onap.org:10001/onap/testsuite:1.3.3 +nexus3.onap.org:10001/onap/usecase-ui:1.2.2 +nexus3.onap.org:10001/onap/usecase-ui-server:1.2.1 +nexus3.onap.org:10001/onap/validation:1.3.1 +nexus3.onap.org:10001/onap/vfc/catalog:1.2.1 +nexus3.onap.org:10001/onap/vfc/db:1.2.1 +nexus3.onap.org:10001/onap/vfc/emsdriver:1.2.1 +nexus3.onap.org:10001/onap/vfc/gvnfmdriver:1.2.1 +nexus3.onap.org:10001/onap/vfc/jujudriver:1.2.1 +nexus3.onap.org:10001/onap/vfc/multivimproxy:1.2.1 +nexus3.onap.org:10001/onap/vfc/nfvo/svnfm/huawei:1.2.1 +nexus3.onap.org:10001/onap/vfc/nfvo/svnfm/nokia:1.1.0 +nexus3.onap.org:10001/onap/vfc/nfvo/svnfm/nokiav2:1.3.0 +nexus3.onap.org:10001/onap/vfc/nslcm:1.2.1 +nexus3.onap.org:10001/onap/vfc/resmanagement:1.2.1 +nexus3.onap.org:10001/onap/vfc/vnflcm:1.2.1 +nexus3.onap.org:10001/onap/vfc/vnfmgr:1.2.1 +nexus3.onap.org:10001/onap/vfc/vnfres:1.2.1 +nexus3.onap.org:10001/onap/vfc/wfengine-activiti:1.2.0 +nexus3.onap.org:10001/onap/vfc/wfengine-mgrservice:1.2.0 +nexus3.onap.org:10001/onap/vfc/ztesdncdriver:1.2.0 +nexus3.onap.org:10001/onap/vfc/ztevnfmdriver:1.2.1 +nexus3.onap.org:10001/onap/vid:3.2.3 +nexus3.onap.org:10001/onap/vnfsdk/refrepo:1.2.0 +nexus3.onap.org:10001/onap/workflow-backend:1.3.2 +nexus3.onap.org:10001/onap/workflow-frontend:1.3.2 +nexus3.onap.org:10001/onap/workflow-init:1.3.2 +nexus3.onap.org:10001/sonatype/nexus:2.14.8-01 +nexus3.onap.org:10001/zookeeper:3.4 +oomk8s/mariadb-client-init:3.0.0 +oomk8s/readiness-check:2.0.0 +oomk8s/readiness-check:2.0.0 +oomk8s/readiness-check:2.0.1 +oomk8s/ubuntu-init:1.0.0 +registry.hub.docker.com/library/busybox:latest +registry.hub.docker.com/library/consul:0.9.3 +registry.hub.docker.com/library/mongo:3 +registry.hub.docker.com/library/mysql:5.7 +registry.hub.docker.com/oomk8s/ubuntu-init:2.0.0 +gcr.io/kubernetes-helm/tiller:v2.9.1 +nexus3.onap.org:10001/onap/org.onap.dcaegen2.deployments.tls-init-container:1.0.0 +library/postgres:9.5.2 +rancher/agent:v1.2.11 +rancher/dns:v0.17.4 +rancher/etc-host-updater:v0.0.3 +rancher/etcd:v2.3.7-17 +rancher/healthcheck:v0.3.8 +rancher/heapster-amd64:v1.5.2 +rancher/heapster-grafana-amd64:v4.4.3 +rancher/heapster-influxdb-amd64:v1.3.3 +rancher/k8s-dns-dnsmasq-nanny-amd64:1.14.10 +rancher/k8s-dns-kube-dns-amd64:1.14.10 +rancher/k8s-dns-sidecar-amd64:1.14.10 +rancher/k8s:v1.11.5-rancher1-1 +rancher/kubectld:v0.8.8 +rancher/kubernetes-agent:v0.6.9 +rancher/kubernetes-auth:v0.0.8 +rancher/kubernetes-dashboard-amd64:v1.8.3 +rancher/lb-service-haproxy:v0.9.6 +rancher/lb-service-rancher:v0.9.6 +rancher/metadata:v0.10.4 +rancher/net:holder +rancher/net:v0.13.17 +rancher/network-manager:v0.7.22 +rancher/pause-amd64:3.0 +rancher/server:v1.6.22 +rancher/tiller:v2.9.1
\ No newline at end of file |