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
This commit is contained in:
Harald Jensås 2018-11-05 13:56:19 +01:00
parent 07241f33d1
commit afa16ae150
6 changed files with 188 additions and 85 deletions

View File

@ -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

View File

@ -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 <<EOF >$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

View File

@ -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'

View File

@ -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)

View File

@ -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)

View File

@ -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}