From afa16ae150eef3c98c354c4ccc3cf872127c1c10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20Jens=C3=A5s?= Date: Mon, 5 Nov 2018 13:56:19 +0100 Subject: [PATCH] Create clouds.yaml for the undercloud Add the cloud to clouds.yaml for the undercloud so that it is available for post deploy script's. The clouds.yaml is created both in the stack users home directory ~/.config/openstack/clouds.yaml and globally for the system in /etc/openstack/clouds.yaml. Update standalone post configuration to use the same code to create and update clouds.yaml on standalone. clouds.yaml is used when setting up client's in other post scripts instead of passing all the options to each script. Partial-Bug: #1801927 Change-Id: I6402fa561745bacf184b1ad2ada44bf8f7c75324 --- extraconfig/post_deploy/clouds_yaml.py | 88 +++++++++++++++++++ extraconfig/post_deploy/standalone_post.sh | 26 ------ extraconfig/post_deploy/standalone_post.yaml | 53 ++++++++--- .../undercloud_ctlplane_network.py | 12 +-- extraconfig/post_deploy/undercloud_post.py | 17 +--- extraconfig/post_deploy/undercloud_post.yaml | 77 ++++++++++------ 6 files changed, 188 insertions(+), 85 deletions(-) create mode 100644 extraconfig/post_deploy/clouds_yaml.py delete mode 100755 extraconfig/post_deploy/standalone_post.sh diff --git a/extraconfig/post_deploy/clouds_yaml.py b/extraconfig/post_deploy/clouds_yaml.py new file mode 100644 index 0000000000..308fec9459 --- /dev/null +++ b/extraconfig/post_deploy/clouds_yaml.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python +import os +import yaml + + +AUTH_URL = os.environ['auth_url'] +ADMIN_PASSWORD = os.environ['admin_password'] +CLOUD_NAME = os.environ['cloud_name'] +HOME_DIR = os.environ['home_dir'] +IDENTITY_API_VERSION = os.environ['identity_api_version'] +PROJECT_NAME = os.environ['project_name'] +PROJECT_DOMAIN_NAME = os.environ['project_domain_name'] +REGION_NAME = os.environ['region_name'] +USER_NAME = os.environ['user_name'] +USER_DOMAIN_NAME = os.environ['user_domain_name'] + +CONFIG_DIR = os.path.join(HOME_DIR, '.config') +OS_DIR = os.path.join(CONFIG_DIR, 'openstack') +USER_CLOUDS_YAML = os.path.join(OS_DIR, 'clouds.yaml') +GLOBAL_OS_DIR = os.path.join('/etc', 'openstack') +GLOBAL_CLOUDS_YAML = os.path.join(GLOBAL_OS_DIR, 'clouds.yaml') + +CLOUD = {CLOUD_NAME: {'auth': {'auth_url': AUTH_URL, + 'project_name': PROJECT_NAME, + 'project_domain_name': PROJECT_DOMAIN_NAME, + 'username': USER_NAME, + 'user_domain_name': USER_DOMAIN_NAME, + 'password': ADMIN_PASSWORD}, + 'region_name': REGION_NAME, + 'identity_api_version': IDENTITY_API_VERSION} + } + + +def _create_clouds_yaml(clouds_yaml): + with open(clouds_yaml, 'w') as f: + yaml.dump({'clouds': {}}, f, default_flow_style=False) + os.chmod(clouds_yaml, 0o600) + + +def _read_clouds_yaml(clouds_yaml): + with open(clouds_yaml, 'r') as f: + clouds = yaml.safe_load(f) + if 'clouds' not in clouds: + clouds.update({'clouds': {}}) + + return clouds + + +def _write_clouds_yaml(clouds_yaml, clouds): + with open(clouds_yaml, 'w') as f: + yaml.dump(clouds, f, default_flow_style=False) + + +try: + # Get the uid and gid for the homedir + user_id = os.stat(HOME_DIR).st_uid + group_id = os.stat(HOME_DIR).st_gid + + if not os.path.isdir(CONFIG_DIR): + os.makedirs(CONFIG_DIR) + os.chown(CONFIG_DIR, user_id, group_id) + + if not os.path.isdir(OS_DIR): + os.makedirs(OS_DIR) + os.chown(OS_DIR, user_id, group_id) + + if not os.path.isdir(GLOBAL_OS_DIR): + os.makedirs(GLOBAL_OS_DIR) + + if not os.path.isfile(USER_CLOUDS_YAML): + _create_clouds_yaml(USER_CLOUDS_YAML) + + if not os.path.isfile(GLOBAL_CLOUDS_YAML): + _create_clouds_yaml(GLOBAL_CLOUDS_YAML) + + user_clouds = _read_clouds_yaml(USER_CLOUDS_YAML) + global_clouds = _read_clouds_yaml(GLOBAL_CLOUDS_YAML) + + user_clouds['clouds'].update(CLOUD) + global_clouds['clouds'].update(CLOUD) + + _write_clouds_yaml(USER_CLOUDS_YAML, user_clouds) + _write_clouds_yaml(GLOBAL_CLOUDS_YAML, global_clouds) + + os.chown(USER_CLOUDS_YAML, user_id, group_id) +except Exception: + print('ERROR: Create clouds.yaml failed.') + raise diff --git a/extraconfig/post_deploy/standalone_post.sh b/extraconfig/post_deploy/standalone_post.sh deleted file mode 100755 index 8bc97501ee..0000000000 --- a/extraconfig/post_deploy/standalone_post.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash -set -eux - -ln -sf /etc/puppet/hiera.yaml /etc/hiera.yaml - -HOMEDIR="$homedir" - -# write out clouds.yaml - -mkdir -p $HOMEDIR/.config/openstack -touch $HOMEDIR/.config/openstack/clouds.yaml -chown 600 $HOMEDIR/.config/openstack/clouds.yaml -cat <$HOMEDIR/.config/openstack/clouds.yaml -clouds: - $cloud_name: - auth: - auth_url: $auth_url - project_name: admin - username: admin - password: $admin_password - region_name: $region_name - identity_api_version: 3 - cloud: standalone -EOF - - diff --git a/extraconfig/post_deploy/standalone_post.yaml b/extraconfig/post_deploy/standalone_post.yaml index 44ac630bc4..c9074939ed 100644 --- a/extraconfig/post_deploy/standalone_post.yaml +++ b/extraconfig/post_deploy/standalone_post.yaml @@ -54,14 +54,19 @@ resources: StandalonePostConfig: type: OS::Heat::SoftwareConfig properties: - group: script - inputs: - - name: admin_password - - name: auth_url - - name: cloud_name - - name: homedir - - name: region_name - config: {get_file: ./standalone_post.sh} + group: ansible + config: | + --- + - name: StandalonePostConfig + connection: local + hosts: localhost + tasks: + - name: Hiera symlink + file: + src: /etc/puppet/hiera.yaml + dest: /etc/hiera.yaml + state: link + force: yes StandalonePostDeployment: type: OS::Heat::SoftwareDeployments @@ -69,9 +74,32 @@ resources: name: StandalonePostDeployment servers: {get_param: servers} config: {get_resource: StandalonePostConfig} + + CloudsYamlConfig: + type: OS::Heat::SoftwareConfig + properties: + group: script + inputs: + - name: admin_password + - name: auth_url + - name: cloud_name + - name: home_dir + - name: identity_api_version + - name: project_name + - name: project_domain_name + - name: region_name + - name: user_name + - name: user_domain_name + config: {get_file: ./clouds_yaml.py} + + CloudsYamlDeployment: + type: OS::Heat::SoftwareDeployments + properties: + name: CloudsYamlDeployment + servers: {get_param: servers} + config: {get_resource: CloudsYamlConfig} input_values: admin_password: {get_param: AdminPassword} - # if SSL is enabled we use the public virtual ip as the stackrc endpoint auth_url: if: - tls_enabled @@ -86,5 +114,10 @@ resources: port: 5000 path: / cloud_name: {get_param: StandaloneCloudName} - homedir: {get_param: StandaloneHomeDir} + home_dir: {get_param: StandaloneHomeDir} + identity_api_version: 3 + project_name: 'admin' + project_domain_name: 'Default' region_name: {get_param: KeystoneRegion} + user_name: 'admin' + user_domain_name: 'Default' diff --git a/extraconfig/post_deploy/undercloud_ctlplane_network.py b/extraconfig/post_deploy/undercloud_ctlplane_network.py index 42cc1bf942..f788560ca2 100644 --- a/extraconfig/post_deploy/undercloud_ctlplane_network.py +++ b/extraconfig/post_deploy/undercloud_ctlplane_network.py @@ -3,13 +3,10 @@ import json import netaddr import os -import os_client_config +import openstack import subprocess CTLPLANE_NETWORK_NAME = 'ctlplane' - -AUTH_URL = os.environ['auth_url'] -ADMIN_PASSWORD = os.environ['admin_password'] CONF = json.loads(os.environ['config']) @@ -265,12 +262,7 @@ if 'true' not in _run_command(['hiera', 'neutron_api_enabled'], print('WARNING: UndercloudCtlplaneNetworkDeployment : The Neutron API ' 'is disabled. The ctlplane network cannot be configured.') else: - sdk = os_client_config.make_sdk(auth_url=AUTH_URL, - project_name='admin', - username='admin', - password=ADMIN_PASSWORD, - project_domain_name='Default', - user_domain_name='Default') + sdk = openstack.connect(CONF['cloud_name']) network = _ensure_neutron_network(sdk) config_neutron_segments_and_subnets(sdk, network.id) diff --git a/extraconfig/post_deploy/undercloud_post.py b/extraconfig/post_deploy/undercloud_post.py index d71e259149..dae382da41 100644 --- a/extraconfig/post_deploy/undercloud_post.py +++ b/extraconfig/post_deploy/undercloud_post.py @@ -5,22 +5,12 @@ import os import openstack import subprocess -from keystoneauth1 import session from keystoneauth1 import exceptions as ks_exceptions -import keystoneauth1.identity.generic as ks_auth from mistralclient.api import client as mistralclient from mistralclient.api import base as mistralclient_exc -AUTH_URL = os.environ['auth_url'] -ADMIN_PASSWORD = os.environ['admin_password'] CONF = json.loads(os.environ['config']) -KS_AUTH = {'auth_url': AUTH_URL, - 'project_name': 'admin', - 'username': 'admin', - 'password': ADMIN_PASSWORD, - 'project_domain_name': 'Default', - 'user_domain_name': 'Default'} WORKBOOK_PATH = '/usr/share/openstack-tripleo-common/workbooks' THT_DIR = '/usr/share/openstack-tripleo-heat-templates' @@ -174,16 +164,15 @@ if not mistral_api_enabled: if not tripleo_validations_enabled: print('WARNING: Undercloud Post - Tripleo validations is disabled.') -sdk = openstack.connect(**KS_AUTH) +sdk = openstack.connect(CONF['cloud_name']) try: if nova_api_enabled: _configure_nova(sdk) _create_default_keypair(sdk) if mistral_api_enabled: - mistral = mistralclient.client( - mistral_url=sdk.workflow.get_endpoint(), - session=session.Session(auth=ks_auth.Password(**KS_AUTH))) + mistral = mistralclient.client(mistral_url=sdk.workflow.get_endpoint(), + session=sdk.session) _configure_wrokbooks_and_workflows(mistral) _create_logging_cron(mistral) _store_snmp_password_in_mistral_env(mistral) diff --git a/extraconfig/post_deploy/undercloud_post.yaml b/extraconfig/post_deploy/undercloud_post.yaml index 1dfd2a6cea..8fbd568eda 100644 --- a/extraconfig/post_deploy/undercloud_post.yaml +++ b/extraconfig/post_deploy/undercloud_post.yaml @@ -67,6 +67,14 @@ parameters: type: number constraints: - range: { min: 1000, max: 65536 } + KeystoneRegion: + type: string + default: 'regionOne' + description: Keystone region for endpoint + UndercloudCloudName: + type: string + default: 'undercloud' + description: Cloud name for the clouds.yaml conditions: @@ -99,6 +107,7 @@ resources: - name: admin_password - name: auth_url - name: internal_tls_ca_file + - name: cloud_name config: {get_file: ./undercloud_post.sh} UndercloudPostDeployment: @@ -111,6 +120,7 @@ resources: ssl_certificate: {get_param: SSLCertificate} homedir: {get_param: UndercloudHomeDir} admin_password: {get_param: AdminPassword} + cloud_name: {get_param: UndercloudCloudName} internal_tls_ca_file: if: - ca_file_enabled @@ -131,23 +141,29 @@ resources: port: 5000 path: / - UndercloudPostPyConfig: + CloudsYamlConfig: type: OS::Heat::SoftwareConfig properties: group: script inputs: - name: admin_password - name: auth_url - - name: config - config: {get_file: ./undercloud_post.py} + - name: cloud_name + - name: home_dir + - name: identity_api_version + - name: project_name + - name: project_domain_name + - name: region_name + - name: user_name + - name: user_domain_name + config: {get_file: ./clouds_yaml.py} - UndercloudPostPyDeployment: + CloudsYamlDeployment: type: OS::Heat::SoftwareDeployments - depends_on: UndercloudPostDeployment properties: - name: UndercloudPostPyDeployment + name: CloudsYamlDeployment servers: {get_param: servers} - config: {get_resource: UndercloudPostPyConfig} + config: {get_resource: CloudsYamlConfig} input_values: admin_password: {get_param: AdminPassword} auth_url: @@ -163,11 +179,37 @@ resources: host: {get_param: [DeployedServerPortMap, 'control_virtual_ip', fixed_ips, 0, ip_address]} port: 5000 path: / + cloud_name: {get_param: UndercloudCloudName} + home_dir: {get_param: UndercloudHomeDir} + identity_api_version: 3 + project_name: 'admin' + project_domain_name: 'Default' + region_name: {get_param: KeystoneRegion} + user_name: 'admin' + user_domain_name: 'Default' + + UndercloudPostPyConfig: + type: OS::Heat::SoftwareConfig + properties: + group: script + inputs: + - name: config + config: {get_file: ./undercloud_post.py} + + UndercloudPostPyDeployment: + type: OS::Heat::SoftwareDeployments + depends_on: [UndercloudPostDeployment, CloudsYamlDeployment] + properties: + name: UndercloudPostPyDeployment + servers: {get_param: servers} + config: {get_resource: UndercloudPostPyConfig} + input_values: config: str_replace: template: JSON params: JSON: + cloud_name: {get_param: UndercloudCloudName} home_dir: {get_param: UndercloudHomeDir} snmp_readonly_user_password: {get_param: SnmpdReadonlyUserPassword} @@ -177,39 +219,23 @@ resources: properties: group: script inputs: - - name: admin_password - - name: auth_url - name: config config: {get_file: ./undercloud_ctlplane_network.py} UndercloudCtlplaneNetworkDeployment: type: OS::Heat::SoftwareDeployments - depends_on: UndercloudPostDeployment + depends_on: [UndercloudPostDeployment, CloudsYamlDeployment] properties: name: UndercloudCtlplaneNetworkDeployment servers: {get_param: servers} config: {get_resource: UndercloudCtlplaneNetworkConfig} input_values: - admin_password: {get_param: AdminPassword} - # if SSL is enabled we use the public virtual ip as the stackrc endpoint - auth_url: - if: - - tls_enabled - - make_url: - scheme: https - host: {get_param: [DeployedServerPortMap, 'public_virtual_ip', fixed_ips, 0, ip_address]} - port: 13000 - path: / - - make_url: - scheme: http - host: {get_param: [DeployedServerPortMap, 'control_virtual_ip', fixed_ips, 0, ip_address]} - port: 5000 - path: / config: str_replace: template: JSON params: JSON: + cloud_name: {get_param: UndercloudCloudName} local_ip: {get_param: [DeployedServerPortMap, 'control_virtual_ip', fixed_ips, 0, ip_address]} local_subnet: {get_param: UndercloudCtlplaneLocalSubnet} nameservers: {get_param: DnsServers} @@ -217,3 +243,4 @@ resources: subnets: {get_param: UndercloudCtlplaneSubnets} enable_routed_networks: {get_param: UndercloudEnableRoutedNetworks} mtu: {get_param: UndercloudLocalMtu} + home_dir: {get_param: UndercloudHomeDir}