diff --git a/defaults/openstack/config.pan b/defaults/openstack/config.pan index 498f4ed..9ff5728 100644 --- a/defaults/openstack/config.pan +++ b/defaults/openstack/config.pan @@ -10,11 +10,49 @@ include 'site/openstack/config'; ################################## variable PRIMARY_IP ?= DB_IP[escape(FULL_HOSTNAME)]; +################################# +# Python modules root directory # +################################# +variable PYTHON_MODULES_ROOT_DIR ?= '/usr/lib/python3.9/site-packages'; + ##################### # SSL configuration # ##################### -variable OS_SSL_CERT ?= '/etc/certs/' + FULL_HOSTNAME + '.crt'; -variable OS_SSL_KEY ?= '/etc/certs/' + FULL_HOSTNAME + '.key'; +variable OS_SSL_USE_LETSENCRYPT ?= false; +# For Let's Encrypt, OS_SSL_CERTIFICATE_ROOT_DIR must be the directory containing all the certs +# (direcotry containing one directory per host) +variable OS_SSL_CERTIFICATE_ROOT_DIR ?= if ( OS_SSL_USE_LETSENCRYPT ) { + error("OS_SSL_USE_LETSENCRYPT=true but OS_SSL_CERTIFICATE_ROOT_DIR undefined"); +}; +# If OS_SSL_CERTIFICATE_ROOT_DIR is defined, the actual certificate directory is +# OS_SSL_CERTIFICATE_ROOT_DIR/FULL_HOSTNAME +variable OS_SSL_CERTIFICATE_DIR ?= if ( is_defined(OS_SSL_CERTIFICATE_ROOT_DIR) ) { + format("%s/%s", OS_SSL_CERTIFICATE_ROOT_DIR, FULL_HOSTNAME); +} else { + '/etc/certs'; +}; +# Excact name of the certificate/key file depends whether Let's Encrypt is used or not +variable OS_SSL_CERT ?= format( + '%s/%s', + OS_SSL_CERTIFICATE_DIR, + if ( OS_SSL_USE_LETSENCRYPT ) 'fullchain.pem' else format("%s.crt", FULL_HOSTNAME), +); +variable OS_SSL_KEY ?= format( + '%s/%s', + OS_SSL_CERTIFICATE_DIR, + if ( OS_SSL_USE_LETSENCRYPT ) 'privkey.pem' else format("%s.key", FULL_HOSTNAME), +); +# Default URL for the ACME challenge if Let's Encrypt is used (null if not used) +variable OS_SSL_ACME_CHALLENGE_URL ?= if ( OS_SSL_USE_LETSENCRYPT ) { + toks = matches(OS_SSL_CERTIFICATE_ROOT_DIR, '^(/.*)/[\w\-]+$'); + if ( length(toks) == 2 ) { + format("%s/acme-challenge", toks[1]); + } else { + error("Unable to retrieve parent of certificate directory (%s)", OS_SSL_CERTIFICATE_ROOT_DIR); + }; +} else { + null; +}; ##################### # Region parameters # @@ -56,7 +94,7 @@ variable OS_EC2_AUTH_ENABLED ?= false; # Glance specific variable # ############################ variable OS_GLANCE_CONTROLLER_HOST ?= error('OS_GLANCE_CONTROLLER_HOST must be declared'); -variable OS_GLANCE_CONTROLLER_PROTOCOL ?= 'http'; +variable OS_GLANCE_CONTROLLER_PROTOCOL ?= 'https'; variable OS_GLANCE_PUBLIC_HOST ?= OS_GLANCE_CONTROLLER_HOST; variable OS_GLANCE_CONTROLLER_PORT ?= if ( OS_GLANCE_CONTROLLER_PROTOCOL == 'https' ) 9293 else 9292; variable OS_GLANCE_PUBLIC_PORT ?= if ( OS_GLANCE_CONTROLLER_PROTOCOL == 'https' ) 9292 else null; @@ -65,18 +103,31 @@ variable OS_GLANCE_DB_USERNAME ?= 'glance'; variable OS_GLANCE_DB_PASSWORD ?= 'GLANCE_DBPASS'; variable OS_GLANCE_USERNAME ?= 'glance'; variable OS_GLANCE_PASSWORD ?= 'GLANCE_PASS'; +# Site-specific policy for Glance +variable OS_GLANCE_POLICY ?= undef; ################### # Magnum variales # ################### -variable OS_MAGNUM_PROTOCOL ?= 'http'; -variable OS_MAGNUM_HOST ?= error('OS_MAGNUM_HOST must be declared'); -variable OS_MAGNUM_PORT ?= 9511; +variable OS_MAGNUM_PROTOCOL ?= 'https'; +variable OS_MAGNUM_PUBLIC_HOST ?= if ( is_defined(OS_MAGNUM_HOST) ) { + OS_MAGNUM_HOST; +} else { + error('OS_MAGNUM_PUBLIC_HOST or OS_MAGNUM_HOST must be declared'); +}; +variable OS_MAGNUM_CONTROLLER_HOST ?= if ( is_defined(OS_MAGNUM_HOST) ) { + OS_MAGNUM_HOST; +} else { + error('OS_MAGNUM_CONTROLLER_HOST or OS_MAGNUM_HOST must be declared'); +}; +variable OS_MAGNUM_CONTROLLER_PORT ?= if ( OS_MAGNUM_PROTOCOL == 'https' ) 9512 else 9511; +variable OS_MAGNUM_PUBLIC_PORT ?= if ( OS_MAGNUM_PROTOCOL == 'https' ) 9511 else null; variable OS_MAGNUM_DEFAULT_VOLUME_TYPE ?= 'magnum_volume_type'; variable OS_REGION_NAME ?= 'default'; variable OS_MAGNUM_DB_USERNAME ?= 'DB USER TO SET'; variable OS_MAGNUM_DB_PASSWORD ?= 'DB_MAGNUM_DBPASS'; variable OS_MAGNUM_DB_HOST ?= OS_DB_HOST; +variable OS_MAGNUM_DB_POOL_SIZE ?= 5; variable OS_MAGNUM_ADMIN_USERNAME ?= 'magnum'; variable OS_MAGNUM_ADMIN_PASSWORD ?= 'MAGNUM_ADMNINPASS'; variable OS_MAGNUM_ADMIN_TENANT_NAME ?= 'service'; @@ -84,13 +135,28 @@ variable OS_MAGNUM_DOMAIN_ADMIN_USERNAME ?= 'magnum_domain_admin_user'; variable OS_MAGNUM_DOMAIN_ADMIN_PASSWORD ?= 'MAGNUM_DOMAIN_ADMIN_USER_PASS'; variable OS_MAGNUM_CLUSTER_USER_TRUST ?= true; variable OS_MAGNUM_RPC_CONN_POOL_SIZE ?= 200; +variable OS_MAGNUM_USERNAME ?= 'magnum'; +# Site-specific policy for Magnum +variable OS_MAGNUM_POLICY ?= undef; ########################## # Heat specific variable # ########################## -variable OS_HEAT_HOST ?= OS_MAGNUM_HOST; -variable OS_HEAT_PROTOCOL ?= 'http'; +variable OS_HEAT_PUBLIC_HOST ?= if ( is_defined(OS_HEAT_HOST) ) { + OS_HEAT_HOST; +} else { + error('OS_HEAT_PUBLIC_HOST or OS_HEAT_HOST must be declared'); +}; +variable OS_HEAT_CONTROLLER_HOST ?= if ( is_defined(OS_HEAT_HOST) ) { + OS_HEAT_HOST; +} else { + error('OS_HEAT_CONTROLLER_HOST or OS_HEAT_HOST must be declared'); +}; +variable OS_HEAT_PROTOCOL ?= 'https'; variable OS_HEAT_DB_HOST ?= OS_DB_HOST; +variable OS_HEAT_DB_POOL_SIZE ?= 5; +variable OS_HEAT_CONTROLLER_PORT ?= if ( OS_HEAT_PROTOCOL == 'https' ) 8005 else 8004; +variable OS_HEAT_PUBLIC_PORT ?= if ( OS_HEAT_PROTOCOL == 'https' ) 8004 else null; variable OS_HEAT_ENABLED ?= false; variable OS_HEAT_DB_USERNAME ?= 'heat'; variable OS_HEAT_DB_PASSWORD ?= 'HEAT_DBPASS'; @@ -100,27 +166,54 @@ variable OS_HEAT_STACK_DOMAIN ?= 'heat'; variable OS_HEAT_USER_DOMAIN ?= 'default'; variable OS_HEAT_DOMAIN_ADMIN_USERNAME ?= 'heat_domain_admin'; variable OS_HEAT_DOMAIN_ADMIN_PASSWORD ?= 'HEAT_DOMAIN_ADMIN_PASS'; +# Site-specific policy for Heat +variable OS_HEAT_POLICY ?= undef; ###################### # Barbican variables # ###################### -variable OS_BARBICAN_HOST ?= OS_MAGNUM_HOST; -variable OS_BARBICAN_PROTOCOL ?= 'http'; -variable OS_BARBICAN_PORT ?= 9311; +variable OS_BARBICAN_PROTOCOL ?= 'https'; +variable OS_BARBICAN_PUBLIC_HOST ?= if ( is_defined(OS_BARBICAN_HOST) ) { + OS_BARBICAN_HOST; +} else { + error('OS_BARBICAN_PUBLIC_HOST or OS_BARBICAN_HOST must be declared'); +}; +variable OS_BARBICAN_CONTROLLER_HOST ?= if ( is_defined(OS_BARBICAN_HOST) ) { + OS_BARBICAN_HOST; +} else { + error('OS_BARBICAN_CONTROLLER_HOST or OS_BARBICAN_HOST must be declared'); +}; +variable OS_BARBICAN_CONTROLLER_PORT ?= if ( OS_BARBICAN_PROTOCOL == 'https' ) 9312 else 9311; +variable OS_BARBICAN_PUBLIC_PORT ?= if ( OS_BARBICAN_PROTOCOL == 'https' ) 9311 else null; +variable OS_BARBICAN_ENABLED ?= false; variable OS_BARBICAN_USERNAME ?= 'barbican'; variable OS_BARBICAN_PASSWORD ?= 'BARBICAN_PASS'; variable OS_BARBICAN_DB_USERNAME ?= 'barbican_user'; variable OS_BARBICAN_DB_PASSWORD ?= 'BARBICAN_REAL_PASS'; variable OS_BARBICAN_DB_HOST ?= OS_DB_HOST; +variable OS_BARBICAN_DB_POOL_SIZE ?= 5; +variable OS_BARBICAN_WSGI_POOL_SIZE ?= 100; +# Site-specific policy for Barbican +variable OS_BARBICAN_POLICY ?= undef; ############################## # Keystone specific variable # ############################## -variable OS_KEYSTONE_CONTROLLER_PROTOCOL ?= 'http'; -variable OS_KEYSTONE_CONTROLLER_HOST ?= error('OS_KEYSTONE_CONTROLLER_HOST must be declared'); -variable OS_KEYSTONE_CONTROLLER_TOKEN_PORT ?= '35357'; -variable OS_KEYSTONE_PUBLIC_CONTROLLER_HOST ?= OS_KEYSTONE_CONTROLLER_HOST; -variable OS_KEYSTONE_PUBLIC_CONTROLLER_PORT ?= '5000'; +variable OS_KEYSTONE_CONTROLLER_PROTOCOL ?= 'https'; +variable OS_KEYSTONE_PUBLIC_HOST ?= if ( is_defined(OS_KEYSTONE_HOST) ) { + OS_KEYSTONE_HOST; +} else { + error('OS_KEYSTONE_PUBLIC_HOST or OS_KEYSTONE_HOST must be declared'); +}; +variable OS_KEYSTONE_CONTROLLER_HOST ?= if ( is_defined(OS_KEYSTONE_HOST) ) { + OS_KEYSTONE_HOST; +} else { + error('OS_KEYSTONE_CONTROLLER_HOST or OS_KEYSTONE_HOST must be declared'); +}; +variable OS_KEYSTONE_CONTROLLER_STANDARD_PORT ?= if ( OS_KEYSTONE_CONTROLLER_PROTOCOL == 'https' ) 5001 else 5000; +variable OS_KEYSTONE_PUBLIC_STANDARD_PORT ?= if ( OS_KEYSTONE_CONTROLLER_PROTOCOL == 'https' ) 5000 else null; +variable OS_KEYSTONE_CONTROLLER_ADMIN_PORT ?= if ( OS_KEYSTONE_CONTROLLER_PROTOCOL == 'https' ) 35358 else 35357; +variable OS_KEYSTONE_PUBLIC_ADMIN_PORT ?= if ( OS_KEYSTONE_CONTROLLER_PROTOCOL == 'https' ) 35357 else null; variable OS_KEYSTONE_DB_HOST ?= OS_DB_HOST; variable OS_KEYSTONE_DB_USERNAME ?= 'keystone'; variable OS_KEYSTONE_DB_PASSWORD ?= 'KEYSTONE_DBPASS'; @@ -129,6 +222,8 @@ variable OS_KEYSTONE_ENFORCE_NEW_DEFAULTS ?= OS_KEYSTONE_ENFORCE_SCOPE; variable OS_KEYSTONE_IDENTITY_DRIVER ?= 'sql'; variable OS_KEYSTONE_IDENTITY_LDAP_PARAMS ?= dict(); variable OS_KEYSTONE_TOKEN_AUTH_TYPE ?= 'password'; +# Site-specific policy for Keystone +variable OS_KEYSTONE_POLICY ?= undef; ############################# # Trustee specific variable # @@ -143,10 +238,31 @@ variable OS_MEMCACHE_HOST ?= 'localhost'; ########################## # Nova specific variable # ########################## -variable OS_NOVA_CONTROLLER_HOST ?= error('OS_NOVA_CONTROLLER_HOST must be declared'); -variable OS_NOVA_VNC_HOST ?= OS_NOVA_CONTROLLER_HOST; -variable OS_NOVA_CONTROLLER_PROTOCOL ?= 'http'; -variable OS_NOVA_VNC_PROTOCOL ?= OS_NOVA_CONTROLLER_PROTOCOL; +variable OS_NOVA_PROTOCOL ?= 'https'; +variable OS_NOVA_PUBLIC_HOST ?= if ( is_defined(OS_NOVA_HOST) ) { + OS_NOVA_HOST; +} else { + error('OS_NOVA_PUBLIC_HOST or OS_NOVA_HOST must be declared'); +}; +variable OS_NOVA_CONTROLLER_HOST ?= if ( is_defined(OS_NOVA_HOST) ) { + OS_NOVA_HOST; +} else { + error('OS_NOVA_CONTROLLER_HOST or OS_NOVA_HOST must be declared'); +}; +# With https, do not use the port 8775 for the API as it is the default port for the metadata service +variable OS_NOVA_CONTROLLER_PORT ?= if ( OS_NOVA_PROTOCOL == 'https' ) 8773 else 8774; +variable OS_NOVA_PUBLIC_PORT ?= if ( OS_NOVA_PROTOCOL == 'https' ) 8774 else null; +variable OS_NOVA_METADATA_PORT ?= 8775; +variable OS_NOVA_NOVNC_PROTOCOL ?= OS_NOVA_PROTOCOL; +variable OS_NOVA_NOVNC_PUBLIC_HOST ?= OS_NOVA_PUBLIC_HOST; +# noVNC proxy has no reason to be access by the controller port if https used (nginx proxy) +variable OS_NOVA_NOVNC_CONTROLLER_HOST ?= if ( OS_NOVA_NOVNC_PROTOCOL == 'https' ) { + '127.0.0.1'; +} else { + OS_NOVA_PUBLIC_HOST; +}; +variable OS_NOVA_NOVNC_CONTROLLER_PORT ?= if ( OS_NOVA_PROTOCOL == 'https' ) 6081 else 6080; +variable OS_NOVA_NOVNC_PUBLIC_PORT ?= if ( OS_NOVA_PROTOCOL == 'https' ) 6080 else null; # OS_NOVA_COMPUTE_POLICY muste be a policy file if a non-default policy is rquired # Policy file extension must be json or yaml variable OS_NOVA_COMPUTE_POLICY ?= undef; @@ -172,15 +288,31 @@ variable OS_NOVA_USE_CEPH ?= true; variable OS_NOVA_CEPH_IMAGES_POOL ?= undef; variable OS_NOVA_CEPH_IMAGES_USER ?= undef; variable OS_NOVA_CEPH_IMAGES_CEPH_CONF ?= '/etc/ceph/ceph.conf'; +# So-called Nova workarounds +# OS_NOVA_CPU_CAPABILITIES_CHECK must be set to false if CPU capabilities checks are failing for bad reasons... +variable OS_NOVA_CPU_CAPABILITIES_CHECK ?= true; +# Site-specific policy for Nova compute and controller +variable OS_NOVA_COMPUTE_POLICY ?= undef; +variable OS_NOVA_CONTROLLER_POLICY ?= undef; ############################# # Neutron specific variable # ############################# -variable OS_NEUTRON_CONTROLLER_HOST ?= error('OS_NEUTRON_CONTROLLER_HOST must be declared'); +variable OS_NEUTRON_PROTOCOL ?= 'https'; +variable OS_NEUTRON_PUBLIC_HOST ?= if ( is_defined(OS_NEUTRON_HOST) ) { + OS_NEUTRON_HOST; +} else { + error('OS_NEUTRON_PUBLIC_HOST or OS_NEUTRON_HOST must be declared'); +}; +variable OS_NEUTRON_CONTROLLER_HOST ?= if ( is_defined(OS_NEUTRON_HOST) ) { + OS_NEUTRON_HOST; +} else { + error('OS_NEUTRON_CONTROLLER_HOST or OS_NEUTRON_HOST must be declared'); +}; +variable OS_NEUTRON_CONTROLLER_PORT ?= if ( OS_NEUTRON_PROTOCOL == 'https' ) 9697 else 9696; +variable OS_NEUTRON_PUBLIC_PORT ?= if ( OS_NEUTRON_PROTOCOL == 'https' ) 9696 else null; variable OS_NEUTRON_NETWORK_PROVIDER ?= OS_NEUTRON_CONTROLLER_HOST; -variable OS_NEUTRON_CONTROLLER_PROTOCOL ?= 'http'; -variable OS_NEUTRON_PUBLIC_HOST ?= OS_NEUTRON_CONTROLLER_HOST; variable OS_NEUTRON_DB_HOST ?= OS_DB_HOST; variable OS_NEUTRON_DB_USERNAME ?= 'neutron'; variable OS_NEUTRON_DB_PASSWORD ?= 'NEUTRON_DBPASS'; @@ -203,30 +335,45 @@ variable OS_NEUTRON_VLAN_RANGES ?= undef; variable OS_NEUTRON_DB_POOL_SIZE ?= 100; variable OS_NEUTRON_DB_MAX_OVERFLOW ?= 200; variable OS_NEUTRON_DHCP_LEASE_DURATION ?= 86400; +# Site-specific policy for Neutron +variable OS_NEUTRON_POLICY ?= undef; ############################ # Placement specific variable # ############################ -variable OS_PLACEMENT_CONTROLLER_HOST ?= OS_NOVA_CONTROLLER_HOST; -variable OS_PLACEMENT_CONTROLLER_PROTOCOL ?= OS_NOVA_CONTROLLER_PROTOCOL; -variable OS_PLACEMENT_CONTROLLER_PORT ?= 8778; +variable OS_PLACEMENT_PROTOCOL ?= 'https'; +variable OS_PLACEMENT_HOST ?= OS_NOVA_CONTROLLER_HOST; +variable OS_PLACEMENT_PUBLIC_HOST ?= if ( is_defined(OS_PLACEMENT_HOST) ) { + OS_PLACEMENT_HOST; +} else { + error('OS_PLACEMENT_PUBLIC_HOST or OS_PLACEMENT_HOST must be declared'); +}; +variable OS_PLACEMENT_CONTROLLER_HOST ?= if ( is_defined(OS_PLACEMENT_HOST) ) { + OS_PLACEMENT_HOST; +} else { + error('OS_PLACEMENT_CONTROLLER_HOST or OS_PLACEMENT_HOST must be declared'); +}; +variable OS_PLACEMENT_CONTROLLER_PORT ?= if ( OS_PLACEMENT_PROTOCOL == 'https' ) 8779 else 8778; +variable OS_PLACEMENT_PUBLIC_PORT ?= if ( OS_PLACEMENT_PROTOCOL == 'https' ) 8778 else null; variable OS_PLACEMENT_DB_HOST ?= OS_DB_HOST; variable OS_PLACEMENT_DB_USERNAME ?= 'placement'; variable OS_PLACEMENT_DB_PASSWORD ?= 'PLACEMENT_DBPASS'; variable OS_PLACEMENT_USERNAME ?= 'placement'; variable OS_PLACEMENT_PASSWORD ?= 'PLACEMENT_PASS'; +# Site-specific policy for Placement +variable OS_PLACEMENT_POLICY ?= undef; ############################ # Cinder specific variable # ############################ # Cinder Controller -variable OS_CINDER_ENABLED ?= false; variable OS_CINDER_CONTROLLER_HOST ?= error('OS_CINDER_CONTROLLER_HOST must be declared'); -variable OS_CINDER_CONTROLLER_PROTOCOL ?= 'http'; +variable OS_CINDER_CONTROLLER_PROTOCOL ?= 'https'; variable OS_CINDER_PUBLIC_HOST ?= OS_CINDER_CONTROLLER_HOST; variable OS_CINDER_CONTROLLER_PORT ?= if ( OS_CINDER_CONTROLLER_PROTOCOL == 'https' ) 8777 else 8776; variable OS_CINDER_PUBLIC_PORT ?= if ( OS_CINDER_CONTROLLER_PROTOCOL == 'https' ) 8776 else null; +variable OS_CINDER_ENABLED ?= false; variable OS_CINDER_DB_HOST ?= OS_DB_HOST; variable OS_CINDER_DB_USERNAME ?= 'cinder'; variable OS_CINDER_DB_PASSWORD ?= 'CINDER_DBPASS'; @@ -237,12 +384,14 @@ variable OS_CINDER_BACKUP_ENABLED ?= false; variable OS_CINDER_BACKUP_CEPH_POOL ?= 'backup'; variable OS_CINDER_BACKUP_CEPH_USER ?= 'cinder-backup'; variable OS_CINDER_BACKUP_CEPH_CONF ?= '/etc/ceph/ceph.conf'; +# Site-specfic policy for Cinder +variable OS_CINDER_POLICY ?= undef; ############################ # Ceilometer specific variable # ############################ variable OS_CEILOMETER_CONTROLLER_HOST ?= error('OS_CEILOMETER_CONTROLLER_HOST must be declared'); -variable OS_CEILOMETER_CONTROLLER_PROTOCOL ?= 'http'; +variable OS_CEILOMETER_CONTROLLER_PROTOCOL ?= 'https'; variable OS_CEILOMETER_METERS_ENABLED ?= false; variable OS_CEILOMETER_DB_HOST ?= OS_DB_HOST; variable OS_CEILOMETER_ENABLED ?= false; @@ -271,12 +420,16 @@ variable OS_HORIZON_HOST ?= if ( is_defined(OS_HORIZON_PUBLIC_NAMES[FULL_HOSTNAM FULL_HOSTNAME; }; variable OS_HORIZON_PROTOCOL ?= 'https'; +variable OS_HORIZON_INTERNAL_PORT ?= if ( OS_HORIZON_PROTOCOL == 'https' ) 8080 else 80; +variable OS_HORIZON_PUBLIC_PORT ?= if ( OS_HORIZON_PROTOCOL == 'https' ) 443 else null; variable OS_HORIZON_ALLOWED_HOSTS ?= list(OS_HORIZON_HOST); variable OS_HORIZON_CONFIGURE_LOCAL_SETTINGS ?= true; variable OS_HORIZON_DEFAULT_ROLE ?= 'users'; variable OS_HORIZON_SECRET_KEY ?= error('OS_HORIZON_SECRET_KEY must be defined'); variable OS_HORIZON_DEFAULT_DOMAIN ?= 'default'; variable OS_HORIZON_ROOT_URL ?= '/dashboard'; +# OS_HORIZON_USER_URL: URL redirected to the dashboard +variable OS_HORIZON_USER_URL ?= '/'; variable OS_HORIZON_KEYSTONE_API_VERSION ?= 3; variable OS_HORIZON_MULTIDOMAIN_ENABLED ?= if (OS_KEYSTONE_IDENTITY_DRIVER == 'sql') { false; @@ -289,16 +442,18 @@ variable OS_HORIZON_MULTIDOMAIN_ENABLED ?= if (OS_KEYSTONE_IDENTITY_DRIVER == 's # Octavia # ########### variable OS_OCTAVIA_CONTROLLER_HOST ?= error('OS_OCTAVIA_CONTROLLER_HOST must be declared'); -variable OS_OCTAVIA_CONTROLLER_PORT ?= 9876; variable OS_OCTAVIA_PUBLIC_HOST ?= OS_OCTAVIA_CONTROLLER_HOST; -variable OS_OCTAVIA_PUBLIC_PORT ?= 9876; -variable OS_OCTAVIA_PROTOCOL ?= 'http'; +variable OS_OCTAVIA_PROTOCOL ?= 'https'; +variable OS_OCTAVIA_CONTROLLER_PORT ?= if ( OS_OCTAVIA_PROTOCOL == 'https' ) 9877 else 9876; +variable OS_OCTAVIA_PUBLIC_PORT ?= if ( OS_OCTAVIA_PROTOCOL == 'https' ) 9876 else null; variable OS_OCTAVIA_DB_HOST ?= OS_DB_HOST; variable OS_OCTAVIA_DB_PASSWORD ?= 'OCTAVIA_DBPASS'; variable OS_OCTAVIA_DB_USERNAME ?= 'octavia'; variable OS_OCTAVIA_PASSWORD ?= 'OCTAVIA_PASS'; variable OS_OCTAVIA_USERNAME ?= 'octavia'; variable OS_OCTAVIA_CA_CERT_DIR ?= '/etc/octavia/certs'; +# Site-specific policy for Octavia +variable OS_OCTAVIA_POLICY ?= undef; ######################################## diff --git a/defaults/openstack/functions.pan b/defaults/openstack/functions.pan index c17caf9..0895f73 100644 --- a/defaults/openstack/functions.pan +++ b/defaults/openstack/functions.pan @@ -120,8 +120,8 @@ function openstack_add_component_dependency = { @documentation { -This function returns the value receive in argument if it is defined, null -otherwise. It is a helper for assigning optional values to the schema. + This function returns the value received in argument if it is defined, null + otherwise. It is a helper for assigning optional values to the schema. } function openstack_add_if_defined = { @@ -137,3 +137,35 @@ function openstack_add_if_defined = { null; }; }; + + +@documentation { + + This function returns a filecopy/services entry to load the policy file passed as + argument, after checking it as a valid extension + + Arguments: + - Name of the service the policy applies to (must match a directory under /etc on the target server) + - File path containing the policy source, relative to the current loadpath +} +function openstack_load_policy = { + if ( ARGC != 2 ) { + error('openstack_load_policy usage: openstack_load_policy(service, policy_file)'); + }; + service = ARGV[0]; + policy_source = ARGV[1]; + if ( is_defined(policy_source) ) { + if ( !match(policy_source, '.*\.yaml$') ) { + error('policy_source must be a file name with the extension .yaml'); + }; + policy_file = format('/etc/%s/policy.yaml', service); + SELF[escape(policy_file)] = dict( + 'config', file_contents(policy_source), + 'owner', 'root', + 'perms', '0644', + 'backup', true, + ); + }; + + SELF; +}; diff --git a/defaults/openstack/utils.pan b/defaults/openstack/utils.pan index 7737440..aac2798 100644 --- a/defaults/openstack/utils.pan +++ b/defaults/openstack/utils.pan @@ -14,65 +14,70 @@ prefix '/software/components/metaconfig/services/{/root/admin-openrc.sh}'; 'contents/variables/OS_TENANT_NAME' = 'admin'; 'contents/variables/OS_USERNAME' = OS_USERNAME; 'contents/variables/OS_PASSWORD' = OS_PASSWORD; -'contents/variables/OS_AUTH_URL' = OS_KEYSTONE_CONTROLLER_PROTOCOL + '://' + OS_KEYSTONE_CONTROLLER_HOST + ':35357/v3'; +'contents/variables/OS_AUTH_URL' = format( + '%s://%s:%s/v3', + OS_KEYSTONE_CONTROLLER_PROTOCOL, + OS_KEYSTONE_CONTROLLER_HOST, + if ( !is_null(OS_KEYSTONE_PUBLIC_ADMIN_PORT) ) OS_KEYSTONE_PUBLIC_ADMIN_PORT else OS_KEYSTONE_CONTROLLER_ADMIN_PORT, +); 'contents/variables/OS_IDENTITY_API_VERSION' = 3; # Create a initialization script variable CONTENTS_INIT_SCRIPT = { - if (OS_NEUTRON_DEFAULT) { - file_contents('defaults/openstack/init.sh') + file_contents('defaults/openstack/init-network.sh'); - } else { - file_contents('defaults/openstack/init.sh'); - }; + if (OS_NEUTRON_DEFAULT) { + file_contents('defaults/openstack/init.sh') + file_contents('defaults/openstack/init-network.sh'); + } else { + file_contents('defaults/openstack/init.sh'); + }; }; include 'components/filecopy/config'; prefix '/software/components/filecopy/services'; '{/root/init.sh}' = dict( - 'perms' ,'755', - 'config', format( - CONTENTS_INIT_SCRIPT, - OS_RABBITMQ_USERNAME, - OS_RABBITMQ_PASSWORD, - OS_REGION_NAME, - OS_KEYSTONE_CONTROLLER_HOST, - OS_KEYSTONE_CONTROLLER_HOST, - OS_GLANCE_CONTROLLER_HOST, - OS_NOVA_CONTROLLER_HOST, - OS_NEUTRON_CONTROLLER_HOST, - OS_HEAT_HOST, - OS_HEAT_HOST, - OS_CINDER_CONTROLLER_HOST, - OS_CINDER_CONTROLLER_HOST, - OS_CEILOMETER_CONTROLLER_HOST, - OS_USERNAME, - OS_PASSWORD, - OS_GLANCE_USERNAME, - OS_GLANCE_PASSWORD, - OS_NOVA_USERNAME, - OS_NOVA_PASSWORD, - OS_NEUTRON_USERNAME, - OS_NEUTRON_PASSWORD, - OS_HEAT_USERNAME, - OS_HEAT_PASSWORD, - OS_HEAT_STACK_DOMAIN, - OS_HEAT_DOMAIN_ADMIN_USERNAME, - OS_HEAT_DOMAIN_ADMIN_PASSWORD, - OS_CINDER_USERNAME, - OS_CINDER_PASSWORD, - OS_CEILOMETER_DB_HOST, - OS_CEILOMETER_DB_USERNAME, - OS_CEILOMETER_DB_PASSWORD, - OS_CEILOMETER_USERNAME, - OS_CEILOMETER_PASSWORD, - OS_ADMIN_TOKEN, - OS_NEUTRON_DEFAULT_NETWORKS, - OS_NEUTRON_DEFAULT_DHCP_POOL['start'], - OS_NEUTRON_DEFAULT_DHCP_POOL['end'], - OS_NEUTRON_DEFAULT_GATEWAY, - OS_NEUTRON_DEFAULT_NAMESERVER, - OS_PLACEMENT_USERNAME, - OS_PLACEMENT_PASSWORD, - OS_PLACEMENT_CONTROLLER_HOST, - ), + 'perms', '755', + 'config', format( + CONTENTS_INIT_SCRIPT, + OS_RABBITMQ_USERNAME, + OS_RABBITMQ_PASSWORD, + OS_REGION_NAME, + OS_KEYSTONE_CONTROLLER_HOST, + OS_KEYSTONE_CONTROLLER_HOST, + OS_GLANCE_CONTROLLER_HOST, + OS_NOVA_CONTROLLER_HOST, + OS_NEUTRON_CONTROLLER_HOST, + OS_HEAT_CONTROLLER_HOST, + OS_HEAT_CONTROLLER_HOST, + OS_CINDER_CONTROLLER_HOST, + OS_CINDER_CONTROLLER_HOST, + OS_CEILOMETER_CONTROLLER_HOST, + OS_USERNAME, + OS_PASSWORD, + OS_GLANCE_USERNAME, + OS_GLANCE_PASSWORD, + OS_NOVA_USERNAME, + OS_NOVA_PASSWORD, + OS_NEUTRON_USERNAME, + OS_NEUTRON_PASSWORD, + OS_HEAT_USERNAME, + OS_HEAT_PASSWORD, + OS_HEAT_STACK_DOMAIN, + OS_HEAT_DOMAIN_ADMIN_USERNAME, + OS_HEAT_DOMAIN_ADMIN_PASSWORD, + OS_CINDER_USERNAME, + OS_CINDER_PASSWORD, + OS_CEILOMETER_DB_HOST, + OS_CEILOMETER_DB_USERNAME, + OS_CEILOMETER_DB_PASSWORD, + OS_CEILOMETER_USERNAME, + OS_CEILOMETER_PASSWORD, + OS_ADMIN_TOKEN, + OS_NEUTRON_DEFAULT_NETWORKS, + OS_NEUTRON_DEFAULT_DHCP_POOL['start'], + OS_NEUTRON_DEFAULT_DHCP_POOL['end'], + OS_NEUTRON_DEFAULT_GATEWAY, + OS_NEUTRON_DEFAULT_NAMESERVER, + OS_PLACEMENT_USERNAME, + OS_PLACEMENT_PASSWORD, + OS_PLACEMENT_CONTROLLER_HOST, + ), ); diff --git a/features/barbican/config.pan b/features/barbican/config.pan index cf9c4e4..1e6133c 100644 --- a/features/barbican/config.pan +++ b/features/barbican/config.pan @@ -2,6 +2,11 @@ unique template features/barbican/config; variable OS_NODE_SERVICES = append('barbican'); +final variable OS_BARBICAN_API_PROCESSES ?= 8; +final variable OS_BARBICAN_LOG_DIR ?= '/var/log/barbican'; +final variable OS_BARBICAN_GROUP ?= OS_BARBICAN_USERNAME; + + # Load some useful functions include 'defaults/openstack/functions'; @@ -11,11 +16,13 @@ include 'types/openstack/barbican'; # Include general openstack variables include 'defaults/openstack/config'; +# Include policy file if OS_BARBICAN_POLICY is defined +include 'components/filecopy/config'; +'/software/components/filecopy/services' = openstack_load_policy('barbican', OS_BARBICAN_POLICY); + + include 'features/barbican/rpms'; -include 'components/systemd/config'; -prefix '/software/components/systemd/unit'; -'httpd/startstop' = true; ################################### # Configuration file for Barbican # @@ -26,7 +33,6 @@ prefix '/software/components/metaconfig/services/{/etc/barbican/barbican.conf}'; 'module' = 'tiny'; 'convert/joincomma' = true; 'convert/truefalse' = true; -'daemons/httpd' = 'restart'; # Restart memcached to ensure considtency with service configuration changes 'daemons/memcached' = 'restart'; bind '/software/components/metaconfig/services/{/etc/barbican/barbican.conf}/contents' = openstack_barbican_config; @@ -35,37 +41,41 @@ bind '/software/components/metaconfig/services/{/etc/barbican/barbican.conf}/con # [DEFAULT] section 'contents/DEFAULT' = openstack_load_config('features/openstack/base'); 'contents/DEFAULT' = openstack_load_config('features/openstack/logging/' + OS_LOGGING_TYPE); -'contents/DEFAULT' = openstack_load_ssl_config( OS_BARBICAN_PROTOCOL == 'https' ); 'contents/DEFAULT/my_ip' = PRIMARY_IP; 'contents/DEFAULT/log_file' = 'barbican-api.log'; -'contents/DEFAULT/host_href' = format('%s://%s:%s', OS_BARBICAN_PROTOCOL, OS_BARBICAN_HOST, OS_BARBICAN_PORT); +'contents/DEFAULT/host_href' = format( + '%s://%s:%s', + OS_BARBICAN_PROTOCOL, + OS_BARBICAN_PUBLIC_HOST, + if ( is_defined(OS_BARBICAN_PUBLIC_PORT) ) OS_BARBICAN_PUBLIC_PORT else OS_BARBICAN_CONTROLLER_PORT, +); 'contents/DEFAULT/log_dir' = '/var/log/barbican'; -'contents/DEFAULT/sql_connection' = format('mysql+pymysql://%s:%s@%s/barbican', OS_BARBICAN_DB_USERNAME, OS_BARBICAN_DB_PASSWORD, OS_BARBICAN_DB_HOST); +'contents/DEFAULT/rpc_response_timeout' = 120; +'contents/DEFAULT/sql_connection' = format( + 'mysql+pymysql://%s:%s@%s/barbican', + OS_BARBICAN_DB_USERNAME, + OS_BARBICAN_DB_PASSWORD, + OS_BARBICAN_DB_HOST, +); +'contents/DEFAULT/wsgi_default_pool_size' = OS_BARBICAN_WSGI_POOL_SIZE; # [keystone_authtoken] section 'contents/keystone_authtoken' = openstack_load_config(OS_AUTH_CLIENT_CONFIG); 'contents/keystone_authtoken/username' = OS_BARBICAN_USERNAME; 'contents/keystone_authtoken/password' = OS_BARBICAN_PASSWORD; +#[oslo_messaging_rabbit] section +'contents/oslo_messaging_rabbit' = openstack_load_config('features/rabbitmq/openstack/client/base'); +'contents/oslo_messaging_rabbit/heartbeat_in_pthread' = false; +'contents/oslo_messaging_rabbit/kombu_missing_consumer_retry_timeout' = 120; -# ############ -# httpd conf # -# ############ - -prefix '/software/components/metaconfig/services/{/etc/httpd/conf.d/wsgi-barbican.conf}'; -'module' = 'openstack/wsgi-barbican'; -'daemons/httpd' = 'restart'; -'contents/listen' = '9311'; +################### +# Configure uSWGI # +################### +include 'features/barbican/uwsgi/config'; -'contents/vhosts/0/port' = 9311; -'contents/vhosts/0/processgroup' = 'barbican-api'; -'contents/vhosts/0/script' = ' /usr/lib/python3.6/site-packages/barbican/api/app.wsgi'; -'contents/vhosts/0/ssl' = openstack_load_ssl_config( OS_BARBICAN_PROTOCOL == 'https' ); -# Load TT file to configure Barbican virtual host -# Run metaconfig in case the TT file was modified and configuration must be regenerated -include 'components/filecopy/config'; -'/software/components/filecopy/dependencies/post' = openstack_add_component_dependency('metaconfig'); -prefix '/software/components/filecopy/services/{/usr/share/templates/quattor/metaconfig/openstack/wsgi-barbican.tt}'; -'config' = file_contents('features/barbican/metaconfig/wsgi-barbican.tt'); -'perms' = '0644'; +######################################### +# Configure SSL proxy if SSL is enabled # +######################################### +include if ( OS_BARBICAN_PROTOCOL == 'https' ) 'features/barbican/nginx/config'; diff --git a/features/barbican/metaconfig/wsgi-barbican.tt b/features/barbican/metaconfig/wsgi-barbican.tt index b546da6..9da4ee6 100644 --- a/features/barbican/metaconfig/wsgi-barbican.tt +++ b/features/barbican/metaconfig/wsgi-barbican.tt @@ -7,7 +7,7 @@ Listen [% port %] WSGIDaemonProcess [% vhost.processgroup %] processes=2 threads=8 user=barbican group=barbican display-name=%{GROUP} WSGIProcessGroup [% vhost.processgroup %] - WSGIScriptAlias / [% vhost.script %] + WSGIScriptAlias / [% vhost.script_path %]/[% vhost.script_name %] WSGIApplicationGroup %{GLOBAL} WSGIPassAuthorization On = 2.4> @@ -23,7 +23,7 @@ Listen [% port %] ErrorLog /var/log/httpd//barbican_wsgi_main_error_ssl.log CustomLog /var/log/httpd/barbican_wsgi_main_access_ssl.log combined - + = 2.4> Require all granted diff --git a/features/barbican/nginx/config.pan b/features/barbican/nginx/config.pan new file mode 100644 index 0000000..0aedf90 --- /dev/null +++ b/features/barbican/nginx/config.pan @@ -0,0 +1,26 @@ +# Add a Nginx VH for handling barbican https requests + +unique template features/barbican/nginx/config; + +variable OS_BARBICAN_PUBLIC_HOST ?= error('OS_BARBICAN_PUBLIC_HOST must be defined when using SSL with Barbican'); +variable OS_BARBICAN_PUBLIC_PORT ?= error('OS_BARBICAN_PUBLIC_PORT must be defined when using SSL with Barbican'); + +include 'types/openstack/core'; + +# Add Nginx and its base configuration +include 'features/nginx/openstack/config'; + +# Nginx proxy configuration for Barbican +include 'components/metaconfig/config'; +prefix '/software/components/metaconfig/services/{/etc/nginx/conf.d/barbican.conf}'; +'module' = 'openstack/nginx-proxy'; +'daemons/nginx' = 'restart'; +# panlint disable=LP006 +bind '/software/components/metaconfig/services/{/etc/nginx/conf.d/barbican.conf}/contents' = openstack_nginx_proxy_config; + +'contents/bind_port' = OS_BARBICAN_PUBLIC_PORT; +'contents/proxy_host' = OS_BARBICAN_CONTROLLER_HOST; +'contents/proxy_port' = OS_BARBICAN_CONTROLLER_PORT; +'contents/server_name' = OS_BARBICAN_PUBLIC_HOST; +'contents/service' = 'barbican'; +'contents/ssl' = openstack_load_ssl_config( true ); diff --git a/features/barbican/rpms.pan b/features/barbican/rpms.pan index 7c32269..7c31fd9 100644 --- a/features/barbican/rpms.pan +++ b/features/barbican/rpms.pan @@ -7,7 +7,6 @@ include 'defaults/openstack/functions'; pkg_repl('python3-barbican'); pkg_repl('openstack-barbican-api'); pkg_repl('libibverbs'); - openstack_add_httpd_packages( OS_BARBICAN_PROTOCOL == 'https' ); SELF; }; diff --git a/features/barbican/uwsgi/config.pan b/features/barbican/uwsgi/config.pan new file mode 100644 index 0000000..0518ef0 --- /dev/null +++ b/features/barbican/uwsgi/config.pan @@ -0,0 +1,31 @@ +unique template features/barbican/uwsgi/config; + + +include 'features/uwsgi/openstack/config'; + +# Load TT file to configure uwsgi application +# Run metaconfig in case the TT file was modified and configuration must be regenerated +include 'components/filecopy/config'; +'/software/components/filecopy/dependencies/post' = openstack_add_component_dependency('metaconfig'); +prefix '/software/components/filecopy/services/{/usr/share/templates/quattor/metaconfig/openstack/barbican-api.tt}'; +'config' = file_contents('features/uwsgi/openstack/vassal-paste_deploy.ini.tt'); +'perms' = '0644'; + +# uwsgi configuration for Barbican API: no explicit restart needed, handled by uwsgi when config file changes +include 'components/metaconfig/config'; +prefix '/software/components/metaconfig/services/{/etc/uwsgi.d/barbican-api.ini}'; +'module' = 'openstack/barbican-api'; +# Owner/group must match the one used to run the application +'group' = OS_BARBICAN_GROUP; +'owner' = OS_BARBICAN_USERNAME; +# panlint disable=LP006 +bind '/software/components/metaconfig/services/{/etc/uwsgi.d/barbican-api.ini}/contents' = openstack_uwsgi_application_config; + +'contents/bind_host' = OS_BARBICAN_CONTROLLER_HOST; +'contents/bind_port' = OS_BARBICAN_CONTROLLER_PORT; +'contents/config_files' = list('/etc/barbican/barbican.conf'); +'contents/group' = OS_BARBICAN_GROUP; +'contents/log_file' = format("%s/api.log", OS_BARBICAN_LOG_DIR); +'contents/processes' = OS_BARBICAN_API_PROCESSES; +'contents/user' = OS_BARBICAN_USERNAME; +'contents/wsgi_file' = '/etc/barbican/barbican-api-paste.ini'; diff --git a/features/cinder/config.pan b/features/cinder/config.pan index ab357d0..dd0f7d5 100644 --- a/features/cinder/config.pan +++ b/features/cinder/config.pan @@ -11,6 +11,15 @@ include 'types/openstack/cinder'; # Include general openstack variables include 'defaults/openstack/config'; +variable OS_CINDER_API_PROCESSES ?= 8; +variable OS_CINDER_GROUP ?= OS_CINDER_USERNAME; +variable OS_CINDER_LOG_DIR ?= '/var/log/cinder'; + + +# Include policy file if OS_CINDER_POLICY is defined +include 'components/filecopy/config'; +'/software/components/filecopy/services' = openstack_load_policy('cinder', OS_CINDER_POLICY); + # Load Cinder RPMs include 'features/cinder/rpms'; @@ -18,6 +27,7 @@ include 'features/cinder/rpms'; include 'components/systemd/config'; prefix '/software/components/systemd/unit'; 'openstack-cinder-api/startstop' = true; +'openstack-cinder-api/state' = "disabled"; 'openstack-cinder-scheduler/startstop' = true; 'openstack-cinder-volume/startstop' = true; @@ -27,7 +37,7 @@ prefix '/software/components/metaconfig/services/{/etc/cinder/cinder.conf}'; 'module' = 'tiny'; 'convert/truefalse' = true; 'convert/joincomma' = true; -'daemons/openstack-cinder-api' = 'restart'; +# Do not restart API on configuration change as it is controlled by uwsgi 'daemons/openstack-cinder-scheduler' = 'restart'; 'daemons/openstack-cinder-volume' = 'restart'; # Restart memcached to ensure considtency with service configuration changes @@ -40,10 +50,20 @@ bind '/software/components/metaconfig/services/{/etc/cinder/cinder.conf}/content 'contents/DEFAULT/auth_strategy' = 'keystone'; 'contents/DEFAULT/enable_v3_api' = true; 'contents/DEFAULT/my_ip' = PRIMARY_IP; -'contents/DEFAULT/glance_api_servers' = list(format('%s://%s:%s', OS_GLANCE_CONTROLLER_PROTOCOL, OS_GLANCE_PUBLIC_HOST, OS_GLANCE_PUBLIC_PORT)); +'contents/DEFAULT/glance_api_servers' = list(format( + '%s://%s:%s', + OS_GLANCE_CONTROLLER_PROTOCOL, + OS_GLANCE_PUBLIC_HOST, + OS_GLANCE_PUBLIC_PORT, +)); # [database] section -'contents/database/connection' = format('mysql+pymysql://%s:%s@%s/cinder', OS_CINDER_DB_USERNAME, OS_CINDER_DB_PASSWORD, OS_CINDER_DB_HOST); +'contents/database/connection' = format( + 'mysql+pymysql://%s:%s@%s/cinder', + OS_CINDER_DB_USERNAME, + OS_CINDER_DB_PASSWORD, + OS_CINDER_DB_HOST, +); # [keystone_authtoken] section 'contents/keystone_authtoken' = openstack_load_config(OS_AUTH_CLIENT_CONFIG); @@ -58,11 +78,17 @@ bind '/software/components/metaconfig/services/{/etc/cinder/cinder.conf}/content #[oslo_messaging_rabbit] section 'contents/oslo_messaging_rabbit' = openstack_load_config('features/rabbitmq/openstack/client/base'); - +'contents/oslo_messaging_rabbit/heartbeat_in_pthread' = false; # Configure Cinder backends include 'features/cinder/backend/config'; +################### +# Configure uSWGI # +################### +include 'features/cinder/uwsgi/config'; + + # Configure SSL proxy if SSL is enabled # include if ( OS_CINDER_CONTROLLER_PROTOCOL == 'https' ) 'features/cinder/nginx/config'; diff --git a/features/cinder/nginx/config.pan b/features/cinder/nginx/config.pan index ec71ea4..fcfd15c 100644 --- a/features/cinder/nginx/config.pan +++ b/features/cinder/nginx/config.pan @@ -10,10 +10,12 @@ include 'types/openstack/core'; # Add Nginx and its base configuration include 'features/nginx/openstack/config'; -# Nginx proxy configuration for Glance +# Nginx proxy configuration for Cinder +include 'components/metaconfig/config'; prefix '/software/components/metaconfig/services/{/etc/nginx/conf.d/cinder.conf}'; 'module' = 'openstack/nginx-proxy'; 'daemons/nginx' = 'restart'; +# panlint disable=LP006 bind '/software/components/metaconfig/services/{/etc/nginx/conf.d/cinder.conf}/contents' = openstack_nginx_proxy_config; 'contents/bind_port' = OS_CINDER_PUBLIC_PORT; @@ -25,5 +27,6 @@ bind '/software/components/metaconfig/services/{/etc/nginx/conf.d/cinder.conf}/c # Define bind port used by Cinder and its public endpoint prefix '/software/components/metaconfig/services/{/etc/cinder/cinder.conf}'; +'contents/DEFAULT/osapi_volume_listen' = OS_CINDER_CONTROLLER_HOST; 'contents/DEFAULT/osapi_volume_listen_port' = OS_CINDER_CONTROLLER_PORT; 'contents/DEFAULT/public_endpoint' = format('https://%s:%s', OS_CINDER_PUBLIC_HOST, OS_CINDER_PUBLIC_PORT); diff --git a/features/cinder/uwsgi/config.pan b/features/cinder/uwsgi/config.pan new file mode 100644 index 0000000..5c97388 --- /dev/null +++ b/features/cinder/uwsgi/config.pan @@ -0,0 +1,32 @@ +unique template features/cinder/uwsgi/config; + + +include 'features/uwsgi/openstack/config'; + +# Load TT file to configure uwsgi application +# Run metaconfig in case the TT file was modified and configuration must be regenerated +include 'components/filecopy/config'; +'/software/components/filecopy/dependencies/post' = openstack_add_component_dependency('metaconfig'); +prefix '/software/components/filecopy/services/{/usr/share/templates/quattor/metaconfig/openstack/cinder-api.tt}'; +'config' = file_contents('features/uwsgi/openstack/vassal-generic.ini.tt'); +'perms' = '0644'; + +# uwsgi configuration for Cinder API: no explicit restart needed, handled by uwsgi when config file changes +include 'components/metaconfig/config'; +prefix '/software/components/metaconfig/services/{/etc/uwsgi.d/cinder-api.ini}'; +'module' = 'openstack/cinder-api'; +# Owner/group must match the one used to run the application +'group' = OS_CINDER_GROUP; +'owner' = OS_CINDER_USERNAME; +# panlint disable=LP006 +bind '/software/components/metaconfig/services/{/etc/uwsgi.d/cinder-api.ini}/contents' = openstack_uwsgi_application_config; + +'contents/bind_host' = OS_CINDER_CONTROLLER_HOST; +'contents/bind_port' = OS_CINDER_CONTROLLER_PORT; +'contents/config_files' = list('/etc/cinder/cinder.conf'); +'contents/group' = OS_CINDER_GROUP; +'contents/log_file' = format("%s/uwsgi-api.log", OS_CINDER_LOG_DIR); +'contents/processes' = OS_CINDER_API_PROCESSES; +'contents/threads' = 1; +'contents/user' = OS_CINDER_USERNAME; +'contents/wsgi_file' = '/usr/bin/cinder-wsgi'; diff --git a/features/dashboard/redirect/config.pan b/features/dashboard/redirect/config.pan deleted file mode 100644 index 36546dd..0000000 --- a/features/dashboard/redirect/config.pan +++ /dev/null @@ -1,30 +0,0 @@ -# Template to redirect the dashboard to another server after moving it -# This template CANNOT be used at the same time as features/dashboard/wsgi/config as -# it manages the same file -unique template features/dashboard/redirect/config; - -include 'features/dashboard/wsgi/schema'; - -# WSGI configuration: overwrite the httpd conf file provided by the RPM -prefix '/software/components/metaconfig/services/{/etc/httpd/conf.d/openstack-dashboard.conf}'; -'module' = 'openstack/wsgi-horizon'; -'daemons/httpd' = 'restart'; -bind '/software/components/metaconfig/services/{/etc/httpd/conf.d/openstack-dashboard.conf}/contents' = openstack_dashboard_httpd_config; - -'contents/server_name' = OS_HORIZON_NEW_HOST; -'contents/server_aliases' = if ( OS_HORIZON_NEW_HOST != FULL_HOSTNAME) { - list(FULL_HOSTNAME); -} else { - null; -}; -'contents/ssl' = openstack_load_ssl_config( OS_HORIZON_PROTOCOL == 'https' ); - -# Load TT file to configure the dashboard virtual host -# Run metaconfig in case the TT file was modified and configuration must be regenerated -include 'components/filecopy/config'; -'/software/components/filecopy/dependencies/post' = openstack_add_component_dependency('metaconfig'); -prefix '/software/components/filecopy/services/{/usr/share/templates/quattor/metaconfig/openstack/wsgi-horizon.tt}'; -'config' = file_contents('features/dashboard/redirect/horizon.tt'); -'perms' = '0644'; - - diff --git a/features/dashboard/redirect/horizon.tt b/features/dashboard/redirect/horizon.tt deleted file mode 100644 index b072157..0000000 --- a/features/dashboard/redirect/horizon.tt +++ /dev/null @@ -1,29 +0,0 @@ - - ServerName [% server_name %] - [%- IF server_aliases.size > 0 %] - ServerAlias [% server_aliases.join(" ") %] - [%- END %] - - RedirectMatch ^(.*)$ https://[% server_name %]$1 - - - - ServerName [% server_name %] - [%- IF server_aliases.size > 0 %] - ServerAlias [% server_aliases.join(" ") %] - [%- END %] - - RedirectMatch ^(.*)$ https://[% server_name %]$1 - - RewriteEngine on - RewriteCond %{HTTP_HOST} "!^[% server_name %]" [NC] - RewriteRule ^/(.*) https://[% server_name %]/$1 [L,R] - - SSLEngine On - SSLCertificateFile [% ssl.cert_file %] - SSLCertificateKeyFile [% ssl.key_file %] - SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown - - ErrorLog /var/log/httpd/dashboard-error.log - CustomLog /var/log/httpd/dashboard-access.log combined - diff --git a/features/dashboard/rpms.pan b/features/dashboard/rpms.pan deleted file mode 100644 index f873380..0000000 --- a/features/dashboard/rpms.pan +++ /dev/null @@ -1,18 +0,0 @@ -unique template features/dashboard/rpms; - -'/software/packages' = { - pkg_repl('openstack-dashboard'); - - if ( is_defined(OS_MAGNUM_HOST) ) { - pkg_repl('openstack-magnum-ui'); - pkg_repl('openstack-heat-ui'); - }; - - if ( is_defined(OS_MAGNUM_HOST) ) { - pkg_repl('openstack-octavia-ui'); - }; - - openstack_add_httpd_packages( OS_HORIZON_PROTOCOL == 'https' ); - - SELF; -}; diff --git a/features/dashboard/wsgi/horizon.tt b/features/dashboard/wsgi/horizon.tt deleted file mode 100644 index b537931..0000000 --- a/features/dashboard/wsgi/horizon.tt +++ /dev/null @@ -1,49 +0,0 @@ - - ServerName [% server_name %] - [%- IF server_aliases.size > 0 %] - ServerAlias [% server_aliases.join(" ") %] - [%- END %] - - RedirectMatch ^(.*)$ https://[% server_name %]$1 - - - - ServerName [% server_name %] - [%- IF server_aliases.size > 0 %] - ServerAlias [% server_aliases.join(" ") %] - [%- END %] - - RewriteEngine on - RewriteCond %{HTTP_HOST} "!^[% server_name %]" [NC] - RewriteRule ^/(.*) https://[% server_name %]/$1 [L,R] - - [%- UNLESS root_url == '/' %] - RedirectMatch ^/$ https://[% server_name %][% root_url %]/ - [%- END %] - - SSLEngine On - SSLCertificateFile [% ssl.cert_file %] - SSLCertificateKeyFile [% ssl.key_file %] - SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown - - # HTTP Strict Transport Security (HSTS) enforces that all communications - # with a server go over SSL. This mitigates the threat from attacks such - # as SSL-Strip which replaces links on the wire, stripping away https prefixes - # and potentially allowing an attacker to view confidential information on the - # wire - Header add Strict-Transport-Security "max-age=15768000" - - WSGIDaemonProcess horizon processes=3 threads=10 - - WSGIScriptAlias [% root_url %] /usr/share/openstack-dashboard/openstack_dashboard/wsgi.py - Alias [% root_url %]/static /usr/share/openstack-dashboard/static/ - - ErrorLog /var/log/httpd/dashboard-error.log - CustomLog /var/log/httpd/dashboard-access.log combined - - - Options None - AllowOverride None - Require all granted - - diff --git a/features/dashboard/wsgi/schema.pan b/features/dashboard/wsgi/schema.pan deleted file mode 100644 index cf03895..0000000 --- a/features/dashboard/wsgi/schema.pan +++ /dev/null @@ -1,11 +0,0 @@ -declaration template features/dashboard/wsgi/schema; - -include 'types/openstack/core'; - - -type openstack_dashboard_httpd_config = { - 'root_url' ? type_URI - 'server_aliases' ? type_hostname[] =list() - 'server_name' : type_hostname - 'ssl' : openstack_httpd_ssl_config -}; diff --git a/features/glance/config.pan b/features/glance/config.pan index 3d7b140..ffe1b59 100644 --- a/features/glance/config.pan +++ b/features/glance/config.pan @@ -45,6 +45,16 @@ variable OS_GLANCE_MULTIPLE_LOCATIONS = { }; }; +variable OS_GLANCE_API_PROCESSES ?= 8; +variable OS_GLANCE_GROUP ?= OS_GLANCE_USERNAME; +variable OS_GLANCE_LOG_DIR ?= '/var/log/glance'; + + +# Include policy file if OS_GLANCE_POLICY is defined +include 'components/filecopy/config'; +'/software/components/filecopy/services' = openstack_load_policy('glance', OS_GLANCE_POLICY); + + # Add Glance bae RPMs include 'features/glance/rpms'; @@ -52,6 +62,7 @@ include 'features/glance/rpms'; include 'components/systemd/config'; prefix '/software/components/systemd/unit'; 'openstack-glance-api/startstop' = true; +'openstack-glance-api/state' = "disabled"; ####################################### @@ -72,7 +83,6 @@ prefix '/software/components/metaconfig/services/{/etc/glance/glance-api.conf}'; 'module' = 'tiny'; 'convert/joincomma' = true; 'convert/truefalse' = true; -'daemons/openstack-glance-api' = 'restart'; # Restart memcached to ensure considtency with service configuration changes 'daemons/memcached' = 'restart'; bind '/software/components/metaconfig/services/{/etc/glance/glance-api.conf}/contents' = openstack_glance_api_config; @@ -110,6 +120,10 @@ bind '/software/components/metaconfig/services/{/etc/glance/glance-api.conf}/con # [oslo_messaging_notifications] section 'contents/oslo_messaging_notifications' = openstack_load_config('features/oslo_messaging/notifications'); +# [oslo_messaging_rabbit] section +'contents/oslo_messaging_rabbit' = openstack_load_config('features/rabbitmq/openstack/client/base'); +'contents/oslo_messaging_rabbit/heartbeat_in_pthread' = false; + # [taskflow_executor] section 'contents/taskflow_executor/max_workers' = to_long(OS_GLANCE_WORKERS_NUM * 1.2); @@ -120,6 +134,12 @@ bind '/software/components/metaconfig/services/{/etc/glance/glance-api.conf}/con include 'features/glance/store/config'; +################### +# Configure uSWGI # +################### +include 'features/glance/uwsgi/config'; + + ######################################### # Configure SSL proxy if SSL is enabled # ######################################### diff --git a/features/glance/nginx/config.pan b/features/glance/nginx/config.pan index 5f5846d..a4ab5ff 100644 --- a/features/glance/nginx/config.pan +++ b/features/glance/nginx/config.pan @@ -11,9 +11,11 @@ include 'types/openstack/core'; include 'features/nginx/openstack/config'; # Nginx proxy configuration for Glance +include 'components/metaconfig/config'; prefix '/software/components/metaconfig/services/{/etc/nginx/conf.d/glance.conf}'; 'module' = 'openstack/nginx-proxy'; 'daemons/nginx' = 'restart'; +# panlint disable=LP006 bind '/software/components/metaconfig/services/{/etc/nginx/conf.d/glance.conf}/contents' = openstack_nginx_proxy_config; 'contents/bind_port' = OS_GLANCE_PUBLIC_PORT; @@ -25,5 +27,6 @@ bind '/software/components/metaconfig/services/{/etc/nginx/conf.d/glance.conf}/c # Define bind port used by Glance and its public endpoint prefix '/software/components/metaconfig/services/{/etc/glance/glance-api.conf}'; +'contents/DEFAULT/bind_host' = OS_GLANCE_CONTROLLER_HOST; 'contents/DEFAULT/bind_port' = OS_GLANCE_CONTROLLER_PORT; 'contents/DEFAULT/public_endpoint' = format('https://%s:%s', OS_GLANCE_PUBLIC_HOST, OS_GLANCE_PUBLIC_PORT); diff --git a/features/glance/uwsgi/config.pan b/features/glance/uwsgi/config.pan new file mode 100644 index 0000000..27218cb --- /dev/null +++ b/features/glance/uwsgi/config.pan @@ -0,0 +1,32 @@ +unique template features/glance/uwsgi/config; + + +include 'features/uwsgi/openstack/config'; + +# Load TT file to configure uwsgi application +# Run metaconfig in case the TT file was modified and configuration must be regenerated +include 'components/filecopy/config'; +'/software/components/filecopy/dependencies/post' = openstack_add_component_dependency('metaconfig'); +prefix '/software/components/filecopy/services/{/usr/share/templates/quattor/metaconfig/openstack/glance-api.tt}'; +'config' = file_contents('features/uwsgi/openstack/vassal-generic.ini.tt'); +'perms' = '0644'; + +# uwsgi configuration for Glance API: no explicit restart needed, handled by uwsgi when config file changes +include 'components/metaconfig/config'; +prefix '/software/components/metaconfig/services/{/etc/uwsgi.d/glance-api.ini}'; +'module' = 'openstack/glance-api'; +# Owner/group must match the one used to run the application +'group' = OS_GLANCE_GROUP; +'owner' = OS_GLANCE_USERNAME; +# panlint disable=LP006 +bind '/software/components/metaconfig/services/{/etc/uwsgi.d/glance-api.ini}/contents' = openstack_uwsgi_application_config; + +'contents/bind_host' = OS_GLANCE_CONTROLLER_HOST; +'contents/bind_port' = OS_GLANCE_CONTROLLER_PORT; +'contents/config_files' = list('/etc/glance/glance.conf'); +'contents/group' = OS_GLANCE_GROUP; +'contents/log_file' = format("%s/uwsgi-api.log", OS_GLANCE_LOG_DIR); +'contents/processes' = OS_GLANCE_API_PROCESSES; +'contents/threads' = 1; +'contents/user' = OS_GLANCE_USERNAME; +'contents/wsgi_file' = '/usr/bin/glance-wsgi-api'; diff --git a/features/heat/config.pan b/features/heat/config.pan index c43125a..318df80 100644 --- a/features/heat/config.pan +++ b/features/heat/config.pan @@ -11,11 +11,21 @@ include 'types/openstack/heat'; # Include general openstack variables include 'defaults/openstack/config'; +variable OS_HEAT_API_PROCESSES ?= 8; +variable OS_HEAT_GROUP ?= OS_HEAT_USERNAME; +variable OS_HEAT_LOG_DIR ?= '/var/log/heat'; + +# Include policy file if OS_HEAT_POLICY is defined +include 'components/filecopy/config'; +'/software/components/filecopy/services' = openstack_load_policy('heat', OS_HEAT_POLICY); + + include 'features/heat/rpms'; include 'components/systemd/config'; prefix '/software/components/systemd/unit'; -'openstack-heat-api/startstop' = true; +# heat-api service is disabled as it is run via uwsgi +'openstack-heat-api/state' = 'disabled'; 'openstack-heat-api-cfn/startstop' = true; 'openstack-heat-engine/startstop' = true; @@ -25,7 +35,7 @@ prefix '/software/components/metaconfig/services/{/etc/heat/heat.conf}'; 'module' = 'tiny'; 'convert/joincomma' = true; 'convert/truefalse' = true; -'daemons/openstack-heat-api' = 'restart'; +# heat-api doesn't need to be explicitely restarted after a config change: handled by uwsgi 'daemons/openstack-heat-api-cfn' = 'restart'; 'daemons/openstack-heat-engine' = 'restart'; # Restart memcached to ensure considtency with service configuration changes @@ -35,26 +45,46 @@ bind '/software/components/metaconfig/services/{/etc/heat/heat.conf}/contents' = # DEFAULT section 'contents/DEFAULT' = openstack_load_config('features/openstack/base'); 'contents/DEFAULT' = openstack_load_config('features/openstack/logging/' + OS_LOGGING_TYPE); -'contents/DEFAULT' = openstack_load_ssl_config( OS_HEAT_PROTOCOL == 'https' ); -'contents/DEFAULT/heat_metadata_server_url' = format('%s://%s:8000', OS_HEAT_PROTOCOL, OS_HEAT_HOST); -'contents/DEFAULT/heat_waitcondition_server_url' = format('%s://%s:8000/v1/waitcondition', OS_HEAT_PROTOCOL, OS_HEAT_HOST); +'contents/DEFAULT/heat_metadata_server_url' = format('%s://%s:8000', OS_HEAT_PROTOCOL, OS_HEAT_CONTROLLER_HOST); +'contents/DEFAULT/heat_waitcondition_server_url' = format( + '%s://%s:8000/v1/waitcondition', + OS_HEAT_PROTOCOL, + OS_HEAT_CONTROLLER_HOST, +); 'contents/DEFAULT/my_ip' = PRIMARY_IP; 'contents/DEFAULT/region_name' = openstack_add_if_defined(OS_HEAT_REGION_NAME); 'contents/DEFAULT/region_name_for_services' = openstack_add_if_defined(OS_HEAT_ENDPOINTS_REGION_NAME); +'contents/DEFAULT/rpc_response_timeout' = 120; 'contents/DEFAULT/stack_domain_admin' = OS_HEAT_DOMAIN_ADMIN_USERNAME; 'contents/DEFAULT/stack_domain_admin_password' = OS_HEAT_DOMAIN_ADMIN_PASSWORD; 'contents/DEFAULT/stack_user_domain_name' = OS_HEAT_STACK_DOMAIN; # [clients_keystone] section -'contents/clients_keystone/auth_uri' = format("%s://%s:%s", OS_KEYSTONE_CONTROLLER_PROTOCOL, OS_KEYSTONE_PUBLIC_CONTROLLER_HOST, OS_KEYSTONE_PUBLIC_CONTROLLER_PORT); +'contents/clients_keystone/auth_uri' = format( + "%s://%s:%s", + OS_KEYSTONE_CONTROLLER_PROTOCOL, + OS_KEYSTONE_PUBLIC_HOST, + OS_KEYSTONE_PUBLIC_STANDARD_PORT, +); # [database] section -'contents/database/connection' = format('mysql+pymysql://%s:%s@%s/heat', OS_HEAT_DB_USERNAME, OS_HEAT_DB_PASSWORD, OS_HEAT_DB_HOST); +'contents/database/connection' = format( + 'mysql+pymysql://%s:%s@%s/heat', + OS_HEAT_DB_USERNAME, + OS_HEAT_DB_PASSWORD, + OS_HEAT_DB_HOST, +); +'contents/database/max_pool_size' = OS_HEAT_DB_POOL_SIZE; # [ec2authtoken] section 'contents/ec2authtoken' = { SELF['auth_uri'] = if ( OS_EC2_AUTH_ENABLED ) { - format("%s://%s:%s/v3", OS_KEYSTONE_CONTROLLER_PROTOCOL, OS_KEYSTONE_PUBLIC_CONTROLLER_HOST, OS_KEYSTONE_PUBLIC_CONTROLLER_PORT); + format( + "%s://%s:%s/v3", + OS_KEYSTONE_CONTROLLER_PROTOCOL, + OS_KEYSTONE_PUBLIC_HOST, + OS_KEYSTONE_PUBLIC_STANDARD_PORT, + ); } else { null; }; @@ -65,11 +95,16 @@ bind '/software/components/metaconfig/services/{/etc/heat/heat.conf}/contents' = }; }; +# [heat_api] section +'contents/heat_api/bind_port' = OS_HEAT_CONTROLLER_PORT; + # [oslo_messaging_notifications] section 'contents/oslo_messaging_notifications' = openstack_load_config('features/oslo_messaging/notifications'); # [oslo_messaging_rabbit] section 'contents/oslo_messaging_rabbit' = openstack_load_config('features/rabbitmq/openstack/client/base'); +'contents/oslo_messaging_rabbit/heartbeat_in_pthread' = false; +'contents/oslo_messaging_rabbit/kombu_missing_consumer_retry_timeout' = 120; # [keystone_authtoken] section 'contents/keystone_authtoken' = openstack_load_config(OS_AUTH_CLIENT_CONFIG); @@ -78,7 +113,25 @@ bind '/software/components/metaconfig/services/{/etc/heat/heat.conf}/contents' = # [trustee] section 'contents/trustee/auth_type' = OS_TRUSTEE_TOKEN_AUTH_TYPE; -'contents/trustee/auth_url' = format("%s://%s:%s", OS_KEYSTONE_CONTROLLER_PROTOCOL, OS_KEYSTONE_CONTROLLER_HOST, OS_KEYSTONE_CONTROLLER_TOKEN_PORT); +'contents/trustee/auth_url' = format( + "%s://%s:%s", + OS_KEYSTONE_CONTROLLER_PROTOCOL, + OS_KEYSTONE_CONTROLLER_HOST, + OS_KEYSTONE_PUBLIC_ADMIN_PORT, +); 'contents/trustee/username' = OS_HEAT_USERNAME; -'contents/trustee/password'= OS_HEAT_PASSWORD; +'contents/trustee/password' = OS_HEAT_PASSWORD; 'contents/trustee/user_domain_id' = OS_HEAT_USER_DOMAIN; + + +################### +# Configure uSWGI # +################### +include 'features/heat/uwsgi/config'; + + +######################################### +# Configure SSL proxy if SSL is enabled # +######################################### +include if ( OS_HEAT_PROTOCOL == 'https' ) 'features/heat/nginx/config'; + diff --git a/features/heat/nginx/config.pan b/features/heat/nginx/config.pan new file mode 100644 index 0000000..ae79db9 --- /dev/null +++ b/features/heat/nginx/config.pan @@ -0,0 +1,26 @@ +# Add a Nginx VH for handling heat https requests + +unique template features/heat/nginx/config; + +variable OS_HEAT_PUBLIC_HOST ?= error('OS_HEAT_PUBLIC_HOST must be defined when using SSL with Heat'); +variable OS_HEAT_PUBLIC_PORT ?= error('OS_HEAT_PUBLIC_PORT must be defined when using SSL with Heat'); + +include 'types/openstack/core'; + +# Add Nginx and its base configuration +include 'features/nginx/openstack/config'; + +# Nginx proxy configuration for Heat +include 'components/metaconfig/config'; +prefix '/software/components/metaconfig/services/{/etc/nginx/conf.d/heat.conf}'; +'module' = 'openstack/nginx-proxy'; +'daemons/nginx' = 'restart'; +# panlint disable=LP006 +bind '/software/components/metaconfig/services/{/etc/nginx/conf.d/heat.conf}/contents' = openstack_nginx_proxy_config; + +'contents/bind_port' = OS_HEAT_PUBLIC_PORT; +'contents/proxy_host' = OS_HEAT_CONTROLLER_HOST; +'contents/proxy_port' = OS_HEAT_CONTROLLER_PORT; +'contents/server_name' = OS_HEAT_PUBLIC_HOST; +'contents/service' = 'heat'; +'contents/ssl' = openstack_load_ssl_config( true ); diff --git a/features/heat/uwsgi/config.pan b/features/heat/uwsgi/config.pan new file mode 100644 index 0000000..69422bb --- /dev/null +++ b/features/heat/uwsgi/config.pan @@ -0,0 +1,32 @@ +unique template features/heat/uwsgi/config; + + +include 'features/uwsgi/openstack/config'; + +# Load TT file to configure uwsgi application +# Run metaconfig in case the TT file was modified and configuration must be regenerated +include 'components/filecopy/config'; +'/software/components/filecopy/dependencies/post' = openstack_add_component_dependency('metaconfig'); +prefix '/software/components/filecopy/services/{/usr/share/templates/quattor/metaconfig/openstack/heat-api.tt}'; +'config' = file_contents('features/uwsgi/openstack/vassal-generic.ini.tt'); +'perms' = '0644'; + +# uwsgi configuration for Heat API: no explicit restart needed, handled by uwsgi when config file changes +include 'components/metaconfig/config'; +prefix '/software/components/metaconfig/services/{/etc/uwsgi.d/heat-api.ini}'; +'module' = 'openstack/heat-api'; +# Owner/group must match the one used to run the application +'group' = OS_HEAT_GROUP; +'owner' = OS_HEAT_USERNAME; +# panlint disable=LP006 +bind '/software/components/metaconfig/services/{/etc/uwsgi.d/heat-api.ini}/contents' = openstack_uwsgi_application_config; + +'contents/bind_host' = OS_HEAT_CONTROLLER_HOST; +'contents/bind_port' = OS_HEAT_CONTROLLER_PORT; +'contents/config_files' = list('/etc/heat/heat.conf'); +'contents/group' = OS_HEAT_GROUP; +'contents/log_file' = format("%s/heat-api.log", OS_HEAT_LOG_DIR); +'contents/processes' = OS_HEAT_API_PROCESSES; +'contents/threads' = 1; +'contents/user' = OS_HEAT_USERNAME; +'contents/wsgi_file' = '/usr/bin/heat-wsgi-api'; diff --git a/features/dashboard/config.pan b/features/horizon/config.pan similarity index 60% rename from features/dashboard/config.pan rename to features/horizon/config.pan index 7b39f67..a9383fc 100644 --- a/features/dashboard/config.pan +++ b/features/horizon/config.pan @@ -1,4 +1,4 @@ -unique template features/dashboard/config; +unique template features/horizon/config; final variable OPENSTACK_DASHBOARD_OCTAVIA_UI_ENABLER ?= '_1482_project_load_balancer_panel.py'; @@ -16,13 +16,14 @@ include 'features/httpd/openstack/config'; # memcache configuration include 'features/memcache/config'; -include 'features/dashboard/rpms'; +include 'features/horizon/rpms'; # local_settings configuration -include if ( OS_HORIZON_CONFIGURE_LOCAL_SETTINGS ) 'features/dashboard/local_settings/config'; +include if ( OS_HORIZON_CONFIGURE_LOCAL_SETTINGS ) 'features/horizon/local_settings/config'; # WSGI configuration: overwrite the httpd conf file provided by the RPM -include 'features/dashboard/wsgi/config'; +# Apache is used instead of uwsgi as the RPM provides several files owned by apache user +include 'features/horizon/wsgi/config'; # Enable the Octavia section of the dashboard, if Octavia is configured include 'components/symlink/config'; @@ -30,7 +31,8 @@ include 'components/symlink/config'; if ( is_defined(OS_OCTAVIA_PUBLIC_HOST) ) { SELF[length(SELF)] = dict( "name", format( - '/usr/lib/python3.6/site-packages/octavia_dashboard/enabled/%s', + '%s/octavia_dashboard/enabled/%s', + PYTHON_MODULES_ROOT_DIR, OPENSTACK_DASHBOARD_OCTAVIA_UI_ENABLER ), "target", format('/etc/openstack-dashboard/enabled/%s', OPENSTACK_DASHBOARD_OCTAVIA_UI_ENABLER), @@ -45,3 +47,13 @@ include 'components/symlink/config'; null; }; }; + +# httpd: increase file limit +include 'components/systemd/config'; +'/software/components/systemd/unit/httpd/file/config/service/LimitNOFILE' = 4096; + + +######################################### +# Configure SSL proxy if SSL is enabled # +######################################### +include if ( OS_HORIZON_PROTOCOL == 'https' ) 'features/horizon/nginx/config'; diff --git a/features/dashboard/local_settings/config.pan b/features/horizon/local_settings/config.pan similarity index 84% rename from features/dashboard/local_settings/config.pan rename to features/horizon/local_settings/config.pan index 6d52e70..3b41cbf 100644 --- a/features/dashboard/local_settings/config.pan +++ b/features/horizon/local_settings/config.pan @@ -1,4 +1,4 @@ -unique template features/dashboard/local_settings/config; +unique template features/horizon/local_settings/config; @{ desc = policy files @@ -11,28 +11,29 @@ variable OS_HORIZON_POLICY_FILE_PATH ?= undef; include 'defaults/openstack/functions'; -include 'features/dashboard/local_settings/schema'; +include 'features/horizon/local_settings/schema'; # Load TT file to configure the dashboard configuration file # Run metaconfig in case the TT file was modified and configuration must be regenerated include 'components/filecopy/config'; '/software/components/filecopy/dependencies/post' = openstack_add_component_dependency('metaconfig'); prefix '/software/components/filecopy/services/{/usr/share/templates/quattor/metaconfig/openstack/django-horizon.tt}'; -'config' = file_contents('features/dashboard/local_settings/django-horizon.tt'); +'config' = file_contents('features/horizon/local_settings/django-horizon.tt'); include 'components/metaconfig/config'; prefix '/software/components/metaconfig/services/{/etc/openstack-dashboard/local_settings}'; 'module' = 'openstack/django-horizon'; 'convert/joincomma' = true; 'daemons/httpd' = 'restart'; +# panlint disable=LP006 bind '/software/components/metaconfig/services/{/etc/openstack-dashboard/local_settings}/contents' = openstack_dashboard_django_config; 'contents/allowed_hosts' = OS_HORIZON_ALLOWED_HOSTS; 'contents/cloud_timezone' = OS_CLOUD_TIMEZONE; -'contents/keystone/default_domain'= OS_HORIZON_DEFAULT_DOMAIN; +'contents/keystone/default_domain' = OS_HORIZON_DEFAULT_DOMAIN; 'contents/keystone/multidomain' = OS_HORIZON_MULTIDOMAIN_ENABLED; 'contents/keystone/protocol' = OS_KEYSTONE_CONTROLLER_PROTOCOL; -'contents/keystone/host' = OS_KEYSTONE_PUBLIC_CONTROLLER_HOST; +'contents/keystone/host' = OS_KEYSTONE_PUBLIC_HOST; 'contents/keystone/api_version' = OS_HORIZON_KEYSTONE_API_VERSION; 'contents/keystone/port' = 5000; 'contents/launch_instance' = if ( is_defined(OS_HORIZON_LAUNCH_INSTANCE) ) { @@ -47,6 +48,7 @@ bind '/software/components/metaconfig/services/{/etc/openstack-dashboard/local_s 'contents/role' = OS_HORIZON_DEFAULT_ROLE; 'contents/root_url' = OS_HORIZON_ROOT_URL; 'contents/secret_key' = OS_HORIZON_SECRET_KEY; +'contents/ssl' = if ( OS_HORIZON_PROTOCOL == 'https' ) true else false; # Configure WEBSSO entries if any defined 'contents/websso' = if ( is_defined(OS_KEYSTONE_FEDERATION_OIDC_PARAMS) ) { diff --git a/features/dashboard/local_settings/django-horizon.tt b/features/horizon/local_settings/django-horizon.tt similarity index 99% rename from features/dashboard/local_settings/django-horizon.tt rename to features/horizon/local_settings/django-horizon.tt index 67d5482..768366b 100644 --- a/features/dashboard/local_settings/django-horizon.tt +++ b/features/horizon/local_settings/django-horizon.tt @@ -414,3 +414,8 @@ WEBSSO_IDP_MAPPING = { } WEBSSO_INITIAL_CHOICE = 'credentials' [%- END %] + +[%- IF ssl %] +SECURE_SSL_REDIRECT = True +SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') +[%- END %] diff --git a/features/dashboard/local_settings/schema.pan b/features/horizon/local_settings/schema.pan similarity index 93% rename from features/dashboard/local_settings/schema.pan rename to features/horizon/local_settings/schema.pan index a1e7207..928f7b3 100644 --- a/features/dashboard/local_settings/schema.pan +++ b/features/horizon/local_settings/schema.pan @@ -1,4 +1,4 @@ -declaration template features/dashboard/local_settings/schema; +declaration template features/horizon/local_settings/schema; include 'types/openstack/core'; @@ -36,5 +36,6 @@ type openstack_dashboard_django_config = { 'role' : string 'root_url' : type_URI 'secret_key' : string + 'ssl' : boolean = true 'websso' ? openstack_dashboard_django_websso_entry[] }; diff --git a/features/horizon/nginx/config.pan b/features/horizon/nginx/config.pan new file mode 100644 index 0000000..c384de5 --- /dev/null +++ b/features/horizon/nginx/config.pan @@ -0,0 +1,32 @@ +# Add a Nginx VH for handling horizon https requests + +unique template features/horizon/nginx/config; + +variable OS_HORIZON_HOST ?= error('OS_HORIZON_HOST must be defined when using SSL with Horizon'); +variable OS_HORIZON_PUBLIC_PORT ?= error('OS_HORIZON_PUBLIC_PORT must be defined when using SSL with Horizon'); + +include 'types/openstack/core'; + +# Add Nginx and its base configuration +include 'features/nginx/openstack/config'; + +# Nginx proxy configuration for Horizon +include 'components/metaconfig/config'; +prefix '/software/components/metaconfig/services/{/etc/nginx/conf.d/horizon.conf}'; +'module' = 'openstack/nginx-proxy'; +'daemons/nginx' = 'restart'; +# panlint disable=LP006 +bind '/software/components/metaconfig/services/{/etc/nginx/conf.d/horizon.conf}/contents' = openstack_nginx_proxy_config; + +'contents/bind_port' = OS_HORIZON_PUBLIC_PORT; +'contents/proxy_port' = OS_HORIZON_INTERNAL_PORT; +'contents/server_name' = OS_HORIZON_HOST; +'contents/service' = 'horizon'; +'contents/ssl' = openstack_load_ssl_config( true ); + +# Redirect port 80 to the dashboard +prefix '/software/components/metaconfig/services/{/etc/nginx/conf.d/port_80.conf}'; +'contents/redirect_urls' = append(dict( + 'url', OS_HORIZON_USER_URL, + 'target', format('%s://%s:%s', OS_HORIZON_PROTOCOL, OS_HORIZON_HOST, OS_HORIZON_PUBLIC_PORT), +)); diff --git a/features/horizon/redirect/config.pan b/features/horizon/redirect/config.pan new file mode 100644 index 0000000..bad2269 --- /dev/null +++ b/features/horizon/redirect/config.pan @@ -0,0 +1,48 @@ +# Template to redirect the dashboard to another server after moving it +unique template features/horizon/redirect/config; + +@{ +desc = list of FQDN used to access Horizon on the current server +values = list of strings +default = empty list +required = no +} +variable OS_HORIZON_ALIAS_NAMES ?= list(); + +include 'features/horizon/wsgi/schema'; + +prefix '/software/components/metaconfig/services/{/etc/nginx/conf.d/horizon.conf}'; +include 'components/metaconfig/config'; +'module' = 'openstack/horizon-redirect'; +'daemons/nginx' = 'restart'; +# panlint disable=LP006 +bind '/software/components/metaconfig/services/{/etc/nginx/conf.d/horizon.conf}/contents' = openstack_dashboard_httpd_config; + +'contents/port' = OS_HORIZON_PUBLIC_PORT; +'contents/redirect_url' = format('%s://%s:%s', OS_HORIZON_PROTOCOL, OS_HORIZON_NEW_HOST, OS_HORIZON_PUBLIC_PORT); +'contents/server_aliases' = OS_HORIZON_ALIAS_NAMES; +'contents/server_name' = FULL_HOSTNAME; +'contents/ssl' = openstack_load_ssl_config( OS_HORIZON_PROTOCOL == 'https' ); +# Useless but required by schema +'contents/wsgi/process_group' = 'horizon'; +'contents/wsgi/script_path' = '/usr/share/openstack-dashboard'; +'contents/wsgi/script_name' = 'openstack_dashboard/wsgi.py'; + +# Load TT file to configure the dashboard virtual host +# Run metaconfig in case the TT file was modified and configuration must be regenerated +include 'components/filecopy/config'; +'/software/components/filecopy/dependencies/post' = openstack_add_component_dependency('metaconfig'); +prefix '/software/components/filecopy/services/{/usr/share/templates/quattor/metaconfig/openstack/horizon-redirect.tt}'; +'config' = file_contents('features/horizon/redirect/horizon.tt'); +'perms' = '0644'; + +# Redirect port 80 to the new Horizon server +prefix '/software/components/metaconfig/services/{/etc/nginx/conf.d/port_80.conf}'; +'contents/redirect_urls' = if ( OS_HORIZON_USER_URL == OS_HORIZON_ROOT_URL ) { + null; +} else { + append(dict( + 'url', OS_HORIZON_USER_URL, + 'target', format('%s://%s:%s', OS_HORIZON_PROTOCOL, OS_HORIZON_NEW_HOST, OS_HORIZON_PUBLIC_PORT), + )); +}; diff --git a/features/horizon/redirect/horizon.tt b/features/horizon/redirect/horizon.tt new file mode 100644 index 0000000..97e7b46 --- /dev/null +++ b/features/horizon/redirect/horizon.tt @@ -0,0 +1,20 @@ +server { + listen [% port %] [% IF ssl.defined %]ssl[% END %]; + listen [::]:[% port %] [% IF ssl.defined %]ssl[% END %]; + server_name [% server_name %] [% server_aliases.join(" ") %]; + access_log /var/log/nginx/[% service %].access.log combined; + error_log /var/log/nginx/[% service %].error.log warn; + + [%- IF ssl.defined %] + ssl_protocols TLSv1.2 TLSv1.3; + ssl_certificate [% ssl.cert_file %]; + ssl_certificate_key [% ssl.key_file %]; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; + [%- END %] + client_max_body_size 0; + + location / { + return 301 [% redirect_url %]$request_uri; + } +} diff --git a/features/horizon/rpms.pan b/features/horizon/rpms.pan new file mode 100644 index 0000000..881de02 --- /dev/null +++ b/features/horizon/rpms.pan @@ -0,0 +1,16 @@ +unique template features/horizon/rpms; + +'/software/packages' = { + pkg_repl('openstack-dashboard'); + + if ( is_defined(OS_MAGNUM_CONTROLLER_HOST) ) { + pkg_repl('openstack-magnum-ui'); + pkg_repl('openstack-heat-ui'); + }; + + if ( is_defined(OS_MAGNUM_CONTROLLER_HOST) ) { + pkg_repl('openstack-octavia-ui'); + }; + + SELF; +}; diff --git a/features/dashboard/wsgi/config.pan b/features/horizon/wsgi/config.pan similarity index 58% rename from features/dashboard/wsgi/config.pan rename to features/horizon/wsgi/config.pan index af6a964..45a7e63 100644 --- a/features/dashboard/wsgi/config.pan +++ b/features/horizon/wsgi/config.pan @@ -1,13 +1,25 @@ -unique template features/dashboard/wsgi/config; +unique template features/horizon/wsgi/config; -include 'features/dashboard/wsgi/schema'; +variable OS_HORIZON_WSGI_PROC_NUM ?= 10; +variable OS_HORIZON_WSGI_PROC_THREADS ?= 5; + +include 'features/horizon/wsgi/schema'; # WSGI configuration: overwrite the httpd conf file provided by the RPM +include 'components/metaconfig/config'; prefix '/software/components/metaconfig/services/{/etc/httpd/conf.d/openstack-dashboard.conf}'; 'module' = 'openstack/wsgi-horizon'; 'daemons/httpd' = 'restart'; +# panlint disable=LP006 bind '/software/components/metaconfig/services/{/etc/httpd/conf.d/openstack-dashboard.conf}/contents' = openstack_dashboard_httpd_config; +'contents/bind_host' = if ( OS_HORIZON_PROTOCOL == 'https' ) '127.0.0.1' else null; +'contents/port' = OS_HORIZON_INTERNAL_PORT; +'contents/wsgi/process_group' = 'horizon'; +'contents/wsgi/processes' = OS_HORIZON_WSGI_PROC_NUM; +'contents/wsgi/script_path' = '/usr/share/openstack-dashboard'; +'contents/wsgi/script_name' = 'openstack_dashboard/wsgi.py'; +'contents/wsgi/threads' = OS_HORIZON_WSGI_PROC_THREADS; 'contents/server_name' = OS_HORIZON_HOST; 'contents/server_aliases' = if ( OS_HORIZON_HOST != FULL_HOSTNAME) { list(FULL_HOSTNAME); @@ -15,14 +27,13 @@ bind '/software/components/metaconfig/services/{/etc/httpd/conf.d/openstack-dash null; }; 'contents/root_url' = OS_HORIZON_ROOT_URL; -'contents/ssl' = openstack_load_ssl_config( OS_HORIZON_PROTOCOL == 'https' ); # Load TT file to configure the dashboard virtual host # Run metaconfig in case the TT file was modified and configuration must be regenerated include 'components/filecopy/config'; '/software/components/filecopy/dependencies/post' = openstack_add_component_dependency('metaconfig'); prefix '/software/components/filecopy/services/{/usr/share/templates/quattor/metaconfig/openstack/wsgi-horizon.tt}'; -'config' = file_contents('features/dashboard/wsgi/horizon.tt'); +'config' = file_contents('features/horizon/wsgi/horizon.tt'); 'perms' = '0644'; diff --git a/features/horizon/wsgi/horizon.tt b/features/horizon/wsgi/horizon.tt new file mode 100644 index 0000000..25bbe75 --- /dev/null +++ b/features/horizon/wsgi/horizon.tt @@ -0,0 +1,33 @@ +Listen [% port %] + + + ServerName [% server_name %] + [%- IF server_aliases.size > 0 %] + ServerAlias [% server_aliases.join(" ") %] + [%- END %] + + RewriteEngine on + RewriteCond %{HTTP_HOST} "!^[% server_name %]" [NC] + RewriteRule ^/(.*) https://[% server_name %]/$1 [L,R] + + [%- UNLESS root_url == '/' %] + RedirectMatch ^/$ https://[% server_name %][% root_url %]/ + [%- END %] + + SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown + + WSGIDaemonProcess [% wsgi.process_group %] processes=[% wsgi.processes %] threads=[% wsgi.threads %] display-name=[% wsgi.process_group %] + WSGIProcessGroup [% wsgi.process_group %] + + WSGIScriptAlias [% root_url %] [% wsgi.script_path %]/[% wsgi.script_name %] + Alias [% root_url %]/static [% wsgi.script_path %]/static/ + + ErrorLog /var/log/httpd/dashboard-error.log + CustomLog /var/log/httpd/dashboard-access.log combined + + + Options None + AllowOverride None + Require all granted + + diff --git a/features/horizon/wsgi/schema.pan b/features/horizon/wsgi/schema.pan new file mode 100644 index 0000000..5111aed --- /dev/null +++ b/features/horizon/wsgi/schema.pan @@ -0,0 +1,13 @@ +declaration template features/horizon/wsgi/schema; + +include 'types/openstack/core'; +include 'types/openstack/httpd'; + + +type openstack_dashboard_httpd_config = { + include openstack_httpd_vhost + 'redirect_url' ? type_hostURI + 'root_url' ? type_URI + 'server_aliases' ? type_hostname[] = list() + 'server_name' : type_hostname +}; diff --git a/features/httpd/openstack/config.pan b/features/httpd/openstack/config.pan index dde5c17..1ff047d 100644 --- a/features/httpd/openstack/config.pan +++ b/features/httpd/openstack/config.pan @@ -1,5 +1,11 @@ unique template features/httpd/openstack/config; +# Hack to prevent conflict with Nginx when used with Let's Encrypt/ACME +final variable OS_HTTPD_DISABLE_PORT_80 ?= true; + +# Configure SSL defaults +final variable OS_HTTPD_CONFIGURE_SSL_DEFAULTS ?= false; + # RPMs must be added in the service using http with the function openstack_add_httpd_packages include 'components/systemd/config'; @@ -7,4 +13,18 @@ prefix '/software/components/systemd/unit'; 'httpd/startstop' = true; # Configure SSL defaults -include 'features/httpd/openstack/ssl/config'; +include if ( OS_HTTPD_CONFIGURE_SSL_DEFAULTS ) 'features/httpd/openstack/ssl/config'; + +# Overwrite default httpd configuration to disable port 80 +include 'components/filecopy/config'; +'/software/components/filecopy/services' = { + if ( OS_HTTPD_DISABLE_PORT_80 ) { + SELF[escape('/etc/httpd/conf/httpd.conf')] = dict( + 'config', file_contents('features/httpd/openstack/httpd-port-80-disabled.conf'), + 'owner', 'root:root', + 'perms', '0644', + 'restart', 'systemctl restart httpd', + ); + }; + SELF; +}; diff --git a/features/httpd/openstack/httpd-port-80-disabled.conf b/features/httpd/openstack/httpd-port-80-disabled.conf new file mode 100644 index 0000000..8e0fad0 --- /dev/null +++ b/features/httpd/openstack/httpd-port-80-disabled.conf @@ -0,0 +1,358 @@ +# +# This is the main Apache HTTP server configuration file. It contains the +# configuration directives that give the server its instructions. +# See for detailed information. +# In particular, see +# +# for a discussion of each configuration directive. +# +# See the httpd.conf(5) man page for more information on this configuration, +# and httpd.service(8) on using and configuring the httpd service. +# +# Do NOT simply read the instructions in here without understanding +# what they do. They're here only as hints or reminders. If you are unsure +# consult the online docs. You have been warned. +# +# Configuration and logfile names: If the filenames you specify for many +# of the server's control files begin with "/" (or "drive:/" for Win32), the +# server will use that explicit path. If the filenames do *not* begin +# with "/", the value of ServerRoot is prepended -- so 'log/access_log' +# with ServerRoot set to '/www' will be interpreted by the +# server as '/www/log/access_log', where as '/log/access_log' will be +# interpreted as '/log/access_log'. + +# +# ServerRoot: The top of the directory tree under which the server's +# configuration, error, and log files are kept. +# +# Do not add a slash at the end of the directory path. If you point +# ServerRoot at a non-local disk, be sure to specify a local disk on the +# Mutex directive, if file-based mutexes are used. If you wish to share the +# same ServerRoot for multiple httpd daemons, you will need to change at +# least PidFile. +# +ServerRoot "/etc/httpd" + +# +# Listen: Allows you to bind Apache to specific IP addresses and/or +# ports, instead of the default. See also the +# directive. +# +# Change this to Listen on a specific IP address, but note that if +# httpd.service is enabled to run at boot time, the address may not be +# available when the service starts. See the httpd.service(8) man +# page for more information. +# +#Listen 12.34.56.78:80 +#Listen 80 + +# +# Dynamic Shared Object (DSO) Support +# +# To be able to use the functionality of a module which was built as a DSO you +# have to place corresponding `LoadModule' lines at this location so the +# directives contained in it are actually available _before_ they are used. +# Statically compiled modules (those listed by `httpd -l') do not need +# to be loaded here. +# +# Example: +# LoadModule foo_module modules/mod_foo.so +# +Include conf.modules.d/*.conf + +# +# If you wish httpd to run as a different user or group, you must run +# httpd as root initially and it will switch. +# +# User/Group: The name (or #number) of the user/group to run httpd as. +# It is usually good practice to create a dedicated user and group for +# running httpd, as with most system services. +# +User apache +Group apache + +# 'Main' server configuration +# +# The directives in this section set up the values used by the 'main' +# server, which responds to any requests that aren't handled by a +# definition. These values also provide defaults for +# any containers you may define later in the file. +# +# All of these directives may appear inside containers, +# in which case these default settings will be overridden for the +# virtual host being defined. +# + +# +# ServerAdmin: Your address, where problems with the server should be +# e-mailed. This address appears on some server-generated pages, such +# as error documents. e.g. admin@your-domain.com +# +ServerAdmin root@localhost + +# +# ServerName gives the name and port that the server uses to identify itself. +# This can often be determined automatically, but we recommend you specify +# it explicitly to prevent problems during startup. +# +# If your host doesn't have a registered DNS name, enter its IP address here. +# +#ServerName www.example.com:80 + +# +# Deny access to the entirety of your server's filesystem. You must +# explicitly permit access to web content directories in other +# blocks below. +# + + AllowOverride none + Require all denied + + +# +# Note that from this point forward you must specifically allow +# particular features to be enabled - so if something's not working as +# you might expect, make sure that you have specifically enabled it +# below. +# + +# +# DocumentRoot: The directory out of which you will serve your +# documents. By default, all requests are taken from this directory, but +# symbolic links and aliases may be used to point to other locations. +# +DocumentRoot "/var/www/html" + +# +# Relax access to content within /var/www. +# + + AllowOverride None + # Allow open access: + Require all granted + + +# Further relax access to the default document root: + + # + # Possible values for the Options directive are "None", "All", + # or any combination of: + # Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews + # + # Note that "MultiViews" must be named *explicitly* --- "Options All" + # doesn't give it to you. + # + # The Options directive is both complicated and important. Please see + # http://httpd.apache.org/docs/2.4/mod/core.html#options + # for more information. + # + Options Indexes FollowSymLinks + + # + # AllowOverride controls what directives may be placed in .htaccess files. + # It can be "All", "None", or any combination of the keywords: + # Options FileInfo AuthConfig Limit + # + AllowOverride None + + # + # Controls who can get stuff from this server. + # + Require all granted + + +# +# DirectoryIndex: sets the file that Apache will serve if a directory +# is requested. +# + + DirectoryIndex index.html + + +# +# The following lines prevent .htaccess and .htpasswd files from being +# viewed by Web clients. +# + + Require all denied + + +# +# ErrorLog: The location of the error log file. +# If you do not specify an ErrorLog directive within a +# container, error messages relating to that virtual host will be +# logged here. If you *do* define an error logfile for a +# container, that host's errors will be logged there and not here. +# +ErrorLog "logs/error_log" + +# +# LogLevel: Control the number of messages logged to the error_log. +# Possible values include: debug, info, notice, warn, error, crit, +# alert, emerg. +# +LogLevel warn + + + # + # The following directives define some format nicknames for use with + # a CustomLog directive (see below). + # + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined + LogFormat "%h %l %u %t \"%r\" %>s %b" common + + + # You need to enable mod_logio.c to use %I and %O + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio + + + # + # The location and format of the access logfile (Common Logfile Format). + # If you do not define any access logfiles within a + # container, they will be logged here. Contrariwise, if you *do* + # define per- access logfiles, transactions will be + # logged therein and *not* in this file. + # + #CustomLog "logs/access_log" common + + # + # If you prefer a logfile with access, agent, and referer information + # (Combined Logfile Format) you can use the following directive. + # + CustomLog "logs/access_log" combined + + + + # + # Redirect: Allows you to tell clients about documents that used to + # exist in your server's namespace, but do not anymore. The client + # will make a new request for the document at its new location. + # Example: + # Redirect permanent /foo http://www.example.com/bar + + # + # Alias: Maps web paths into filesystem paths and is used to + # access content that does not live under the DocumentRoot. + # Example: + # Alias /webpath /full/filesystem/path + # + # If you include a trailing / on /webpath then the server will + # require it to be present in the URL. You will also likely + # need to provide a section to allow access to + # the filesystem path. + + # + # ScriptAlias: This controls which directories contain server scripts. + # ScriptAliases are essentially the same as Aliases, except that + # documents in the target directory are treated as applications and + # run by the server when requested rather than as documents sent to the + # client. The same rules about trailing "/" apply to ScriptAlias + # directives as to Alias. + # + ScriptAlias /cgi-bin/ "/var/www/cgi-bin/" + + + +# +# "/var/www/cgi-bin" should be changed to whatever your ScriptAliased +# CGI directory exists, if you have that configured. +# + + AllowOverride None + Options None + Require all granted + + + + # + # TypesConfig points to the file containing the list of mappings from + # filename extension to MIME-type. + # + TypesConfig /etc/mime.types + + # + # AddType allows you to add to or override the MIME configuration + # file specified in TypesConfig for specific file types. + # + #AddType application/x-gzip .tgz + # + # AddEncoding allows you to have certain browsers uncompress + # information on the fly. Note: Not all browsers support this. + # + #AddEncoding x-compress .Z + #AddEncoding x-gzip .gz .tgz + # + # If the AddEncoding directives above are commented-out, then you + # probably should define those extensions to indicate media types: + # + AddType application/x-compress .Z + AddType application/x-gzip .gz .tgz + + # + # AddHandler allows you to map certain file extensions to "handlers": + # actions unrelated to filetype. These can be either built into the server + # or added with the Action directive (see below) + # + # To use CGI scripts outside of ScriptAliased directories: + # (You will also need to add "ExecCGI" to the "Options" directive.) + # + #AddHandler cgi-script .cgi + + # For type maps (negotiated resources): + #AddHandler type-map var + + # + # Filters allow you to process content before it is sent to the client. + # + # To parse .shtml files for server-side includes (SSI): + # (You will also need to add "Includes" to the "Options" directive.) + # + AddType text/html .shtml + AddOutputFilter INCLUDES .shtml + + +# +# Specify a default charset for all content served; this enables +# interpretation of all content as UTF-8 by default. To use the +# default browser choice (ISO-8859-1), or to allow the META tags +# in HTML content to override this choice, comment out this +# directive: +# +AddDefaultCharset UTF-8 + + + # + # The mod_mime_magic module allows the server to use various hints from the + # contents of the file itself to determine its type. The MIMEMagicFile + # directive tells the module where the hint definitions are located. + # + MIMEMagicFile conf/magic + + +# +# Customizable error responses come in three flavors: +# 1) plain text 2) local redirects 3) external redirects +# +# Some examples: +#ErrorDocument 500 "The server made a boo boo." +#ErrorDocument 404 /missing.html +#ErrorDocument 404 "/cgi-bin/missing_handler.pl" +#ErrorDocument 402 http://www.example.com/subscription_info.html +# + +# +# EnableMMAP and EnableSendfile: On systems that support it, +# memory-mapping or the sendfile syscall may be used to deliver +# files. This usually improves server performance, but must +# be turned off when serving from networked-mounted +# filesystems or if support for these functions is otherwise +# broken on your system. +# Defaults if commented: EnableMMAP On, EnableSendfile Off +# +#EnableMMAP off +EnableSendfile on + +# Supplemental configuration +# +# Load config files in the "/etc/httpd/conf.d" directory, if any. +IncludeOptional conf.d/*.conf diff --git a/features/keystone/client/config.pan b/features/keystone/client/config.pan index 7182056..23d616b 100644 --- a/features/keystone/client/config.pan +++ b/features/keystone/client/config.pan @@ -16,7 +16,7 @@ structure template features/keystone/client/config; 'www_authenticate_uri' = format( '%s://%s:%S/%s', OS_KEYSTONE_CONTROLLER_PROTOCOL, - OS_KEYSTONE_PUBLIC_CONTROLLER_HOST, - OS_KEYSTONE_PUBLIC_CONTROLLER_PORT, + OS_KEYSTONE_PUBLIC_HOST, + OS_KEYSTONE_PUBLIC_STANDARD_PORT, OS_KEYSTONE_VERSION, ); diff --git a/features/keystone/config.pan b/features/keystone/config.pan index 3bc13b9..31330af 100644 --- a/features/keystone/config.pan +++ b/features/keystone/config.pan @@ -47,9 +47,15 @@ requied = no variable OS_KEYSTONE_FEDERATION_OIDC_PARAMS ?= undef; +# Include policy file if OS_KEYSTONE_POLICY is defined +include 'components/filecopy/config'; +'/software/components/filecopy/services' = openstack_load_policy('keystone', OS_KEYSTONE_POLICY); + + include 'features/keystone/rpms'; # httpd configuration +# httpd is used instead of uwsgi because federation identity requires mod_openidc include 'features/httpd/openstack/config'; include 'features/keystone/wsgi/config'; @@ -70,7 +76,6 @@ bind '/software/components/metaconfig/services/{/etc/keystone/keystone.conf}/con # [DEFAULT] section 'contents/DEFAULT' = openstack_load_config('features/openstack/base'); 'contents/DEFAULT' = openstack_load_config('features/openstack/logging/' + OS_LOGGING_TYPE); -'contents/DEFAULT' = openstack_load_ssl_config( OS_KEYSTONE_CONTROLLER_PROTOCOL == 'https' ); 'contents/DEFAULT/admin_token' ?= OS_ADMIN_TOKEN; # Remove unsupported parameters 'contents/DEFAULT/auth_strategy' = null; @@ -145,3 +150,10 @@ bind '/software/components/metaconfig/services/{/etc/keystone/keystone.conf}/con # Configure identity backend include 'features/keystone/identity/' + OS_KEYSTONE_IDENTITY_DRIVER; + + +######################################### +# Configure SSL proxy if SSL is enabled # +######################################### +include if ( OS_KEYSTONE_CONTROLLER_PROTOCOL == 'https' ) 'features/keystone/nginx/config'; + diff --git a/features/keystone/identity/ldap.pan b/features/keystone/identity/ldap.pan index 9b441bd..65e173a 100644 --- a/features/keystone/identity/ldap.pan +++ b/features/keystone/identity/ldap.pan @@ -1,7 +1,7 @@ unique template features/keystone/identity/ldap; -# If ldap is used as backend, we configure a openldap server -include 'features/openldap/openstack/config'; +# Add OpenLDAP clients +'/software/packages' = pkg_repl('openldap-clients'); # keystone.conf file is already populate with some common variable # We add ldap configuration variable @@ -14,52 +14,55 @@ prefix '/software/components/metaconfig/services/{/etc/keystone/keystone.conf}'; # (/etc/keystone/domains/keystone.DOMAIN_NAME.conf) prefix '/software/components/metaconfig'; 'services' = { - foreach(domain;params;OS_KEYSTONE_IDENTITY_LDAP_PARAMS) { - # Populate configuration file with some default value - SELF[escape('/etc/keystone/domains/keystone.'+domain+'.conf')] = dict( - 'module', 'tiny', - 'contents', dict('ldap',dict()), - ); - SELF[escape('/etc/keystone/domains/keystone.'+domain+'.conf')]['daemons'] = dict( - 'httpd', 'restart', - ); - # Others domain is on ldap - SELF[escape('/etc/keystone/domains/keystone.'+domain+'.conf')]['contents']['identity'] = dict('driver', 'ldap'); - SELF[escape('/etc/keystone/domains/keystone.'+domain+'.conf')]['contents']['ldap'] = dict( - 'use_dump_member', 'False', - 'allow_subtree_delete', 'False', - 'user_objectclass', 'inetOrgPerson', - 'user_allow_create', 'False', - 'user_allow_update', 'False', - 'user_allow_delete', 'False', - 'group_objectclass', 'groupOfNames', - 'group_allow_create', 'False', - 'group_allow_update', 'False', - 'group_allow_delete', 'False', - ); - # Verify if all needed parameters exists - if (!exists(params['url'])) { - error('LDAP identity need params [url]'); + foreach(domain; params; OS_KEYSTONE_IDENTITY_LDAP_PARAMS) { + # Populate configuration file with some default value + SELF[escape(format('/etc/keystone/domains/keystone.%s.conf', domain))] = dict( + 'module', 'tiny', + 'contents', dict('ldap', dict()), + ); + SELF[escape(format('/etc/keystone/domains/keystone.%s.conf', domain))]['daemons'] = dict( + 'httpd', 'restart', + ); + # Others domain is on ldap + SELF[escape(format('/etc/keystone/domains/keystone.%s.conf', domain))]['contents']['identity'] = dict( + 'driver', 'ldap', + ); + SELF[escape(format('/etc/keystone/domains/keystone.%s.conf', domain))]['contents']['ldap'] = dict( + 'use_dump_member', 'False', + 'allow_subtree_delete', 'False', + 'user_objectclass', 'inetOrgPerson', + 'user_allow_create', 'False', + 'user_allow_update', 'False', + 'user_allow_delete', 'False', + 'group_objectclass', 'groupOfNames', + 'group_allow_create', 'False', + 'group_allow_update', 'False', + 'group_allow_delete', 'False', + ); + # Verify if all needed parameters exists + if (!exists(params['url'])) { + error('LDAP identity need params [url]'); + }; + if (!exists(params['user'])) { + error('LDAP identity need params [user]'); + }; + if (!exists(params['password'])) { + error('LDAP identity need params [password]'); + }; + if (!exists(params['suffix'])) { + error('LDAP identity need params [suffix]'); + }; + if (!exists(params['user_tree_dn'])) { + error('LDAP identity need params [user_tree_dn]'); + }; + if (!exists(params['group_tree_dn'])) { + error('LDAP identity need params [group_tree_dn]'); }; - if (!exists(params['user'])) { - error('LDAP identity need params [user]'); - }; - if (!exists(params['password'])) { - error('LDAP identity need params [password]'); - }; - if (!exists(params['suffix'])) { - error('LDAP identity need params [suffix]'); - }; - if (!exists(params['user_tree_dn'])) { - error('LDAP identity need params [user_tree_dn]'); - }; - if (!exists(params['group_tree_dn'])) { - error('LDAP identity need params [group_tree_dn]'); - }; - foreach(attribute;attribute_value;params) { - SELF[escape('/etc/keystone/domains/keystone.'+domain+'.conf')]['contents']['ldap'][attribute] = attribute_value; + foreach(attribute; attribute_value; params) { + k = escape(format('/etc/keystone/domains/keystone.%s.conf', domain)); + SELF[k]['contents']['ldap'][attribute] = attribute_value; + }; }; - }; - SELF; + SELF; }; diff --git a/features/keystone/nginx/config.pan b/features/keystone/nginx/config.pan new file mode 100644 index 0000000..561ae16 --- /dev/null +++ b/features/keystone/nginx/config.pan @@ -0,0 +1,48 @@ +# Add a Nginx VH for handling keystone https requests + +unique template features/keystone/nginx/config; + +variable OS_KEYSTONE_PUBLIC_HOST ?= error( + 'OS_KEYSTONE_PUBLIC_HOST must be defined when using SSL with Keystone' +); +variable OS_KEYSTONE_PUBLIC_STANDARD_PORT ?= error( + 'OS_KEYSTONE_PUBLIC_STANDARD_PORT must be defined when using SSL with Keystone' +); +variable OS_KEYSTONE_PUBLIC_ADMIN_PORT ?= error( + 'OS_KEYSTONE_PUBLIC_ADMIN_PORT must be defined when using SSL with Keystone' +); + +include 'types/openstack/core'; + +# Add Nginx and its base configuration +include 'features/nginx/openstack/config'; + +# Nginx proxy configuration for Keystone standard (unprivileged) port +include 'components/metaconfig/config'; +prefix '/software/components/metaconfig/services/{/etc/nginx/conf.d/keystone-standard.conf}'; +'module' = 'openstack/nginx-proxy'; +'daemons/nginx' = 'restart'; +# panlint disable=LP006 +bind '/software/components/metaconfig/services/{/etc/nginx/conf.d/keystone-standard.conf}/contents' = openstack_nginx_proxy_config; + +'contents/bind_port' = OS_KEYSTONE_PUBLIC_STANDARD_PORT; +'contents/proxy_host' = OS_KEYSTONE_CONTROLLER_HOST; +'contents/proxy_port' = OS_KEYSTONE_CONTROLLER_STANDARD_PORT; +'contents/server_name' = OS_KEYSTONE_PUBLIC_HOST; +'contents/service' = 'keystone'; +'contents/ssl' = openstack_load_ssl_config( true ); + +# Nginx proxy configuration for Keystone admin (privileged) port +prefix '/software/components/metaconfig/services/{/etc/nginx/conf.d/keystone-admin.conf}'; +'module' = 'openstack/nginx-proxy'; +'daemons/nginx' = 'restart'; +# panlint disable=LP006 +bind '/software/components/metaconfig/services/{/etc/nginx/conf.d/keystone-admin.conf}/contents' = openstack_nginx_proxy_config; + +'contents/bind_port' = OS_KEYSTONE_PUBLIC_ADMIN_PORT; +'contents/proxy_host' = OS_KEYSTONE_CONTROLLER_HOST; +'contents/proxy_port' = OS_KEYSTONE_CONTROLLER_ADMIN_PORT; +'contents/server_name' = OS_KEYSTONE_PUBLIC_HOST; +'contents/service' = 'keystone'; +'contents/ssl' = openstack_load_ssl_config( true ); + diff --git a/features/keystone/rpms.pan b/features/keystone/rpms.pan index ebe39ff..921ea2f 100644 --- a/features/keystone/rpms.pan +++ b/features/keystone/rpms.pan @@ -4,7 +4,7 @@ unique template features/keystone/rpms; pkg_repl('openstack-keystone'); pkg_repl('python3-keystoneclient'); pkg_repl('python3-etcd3gw'); - openstack_add_httpd_packages( OS_KEYSTONE_CONTROLLER_PROTOCOL == 'https' ); + openstack_add_httpd_packages( false ); if ( is_defined(OS_KEYSTONE_FEDERATION_OIDC_PARAMS) ) { pkg_repl('mod_auth_openidc'); diff --git a/features/keystone/wsgi/config.pan b/features/keystone/wsgi/config.pan index d4caf21..8c6ab1d 100644 --- a/features/keystone/wsgi/config.pan +++ b/features/keystone/wsgi/config.pan @@ -1,28 +1,84 @@ unique template features/keystone/wsgi/config; +# Define default parameter values for processes, threads and listen-backlog +# Other parameter defaults are taken from the schema +variable OS_KEYSTONE_WSGI_PARAMS_PUBLIC = { + if ( !is_defined(SELF['processes']) ) { + SELF['processes'] = 15; + }; + if ( !is_defined(SELF['threads']) ) { + SELF['threads'] = 20; + }; + if ( !is_defined(SELF['listen_backlog']) ) { + SELF['listen_backlog'] = SELF['processes'] * SELF['threads']; + }; + + SELF; +}; + +variable OS_KEYSTONE_WSGI_PARAMS_ADMIN = { + if ( !is_defined(SELF['processes']) ) { + SELF['processes'] = 15; + }; + if ( !is_defined(SELF['threads']) ) { + SELF['threads'] = 20; + }; + if ( !is_defined(SELF['listen_backlog']) ) { + SELF['listen_backlog'] = SELF['processes'] * SELF['threads']; + }; + + SELF; +}; + + include 'features/keystone/wsgi/schema'; +include 'components/metaconfig/config'; prefix '/software/components/metaconfig/services/{/etc/httpd/conf.d/keystone.conf}'; 'module' = 'openstack/wsgi-keystone'; 'daemons/httpd' = 'restart'; -bind '/software/components/metaconfig/services/{/etc/httpd/conf.d/keystone.conf}/contents' = openstack_keystone_httpd_config; +# panlint disable=LP006 +bind '/software/components/metaconfig/services/{/etc/httpd/conf.d/keystone.conf}/contents' = openstack_httpd_config; -'contents/listen' = list(5000, 35357); 'contents/oidc_enabled' = if ( is_defined(OS_KEYSTONE_FEDERATION_OIDC_PARAMS) ) { true; } else { false; }; -'contents/vhosts/0/port' = 5000; -'contents/vhosts/0/processgroup' = 'keystone-public'; -'contents/vhosts/0/script' = '/usr/bin/keystone-wsgi-public'; -'contents/vhosts/0/ssl' = openstack_load_ssl_config( OS_KEYSTONE_CONTROLLER_PROTOCOL == 'https' ); +'contents/vhosts/0/bind_host' = if ( OS_HORIZON_PROTOCOL == 'https' ) OS_KEYSTONE_CONTROLLER_HOST else null; +'contents/vhosts/0/port' = OS_KEYSTONE_CONTROLLER_STANDARD_PORT; +'contents/vhosts/0/wsgi/process_group' = 'keystone-public'; +'contents/vhosts/0/wsgi/script_path' = '/usr/bin'; +'contents/vhosts/0/wsgi/script_name' = 'keystone-wsgi-public'; +'contents/vhosts/0/wsgi' = { + foreach (param; val; OS_KEYSTONE_WSGI_PARAMS_PUBLIC) { + SELF[param] = val; + }; -'contents/vhosts/1/port' = 35357; -'contents/vhosts/1/processgroup' = 'keystone-admin'; -'contents/vhosts/1/script' = '/usr/bin/keystone-wsgi-admin'; -'contents/vhosts/1/ssl' = openstack_load_ssl_config( OS_KEYSTONE_CONTROLLER_PROTOCOL == 'https' ); + SELF; +}; + +'contents/vhosts/1/bind_host' = if ( OS_HORIZON_PROTOCOL == 'https' ) OS_KEYSTONE_CONTROLLER_HOST else null; +'contents/vhosts/1/port' = OS_KEYSTONE_CONTROLLER_ADMIN_PORT; +'contents/vhosts/1/wsgi/process_group' = 'keystone-admin'; +'contents/vhosts/1/wsgi/script_path' = '/usr/bin'; +'contents/vhosts/1/wsgi/script_name' = 'keystone-wsgi-admin'; +'contents/vhosts/1/wsgi' = { + foreach (param; val; OS_KEYSTONE_WSGI_PARAMS_ADMIN) { + SELF[param] = val; + }; + + SELF; +}; + +'contents/listen' = { + vhosts = value('/software/components/metaconfig/services/{/etc/httpd/conf.d/keystone.conf}/contents/vhosts'); + foreach (i; vhost; vhosts) { + append(vhost['port']); + }; + SELF; +}; # Load TT file to configure the keystone virtual host # Run metaconfig in case the TT file was modified and configuration must be regenerated diff --git a/features/keystone/wsgi/keystone.tt b/features/keystone/wsgi/keystone.tt index 6cdd1b4..c66a0f5 100644 --- a/features/keystone/wsgi/keystone.tt +++ b/features/keystone/wsgi/keystone.tt @@ -4,10 +4,10 @@ Listen [% port %] [%- END -%] [% FOREACH vhost IN vhosts -%] - - WSGIDaemonProcess [% vhost.processgroup %] processes=15 threads=10 user=keystone group=keystone display-name=%{GROUP} - WSGIProcessGroup [% vhost.processgroup %] - WSGIScriptAlias / [% vhost.script %] + + WSGIDaemonProcess [% vhost.wsgi.process_group %] processes=[% vhost.wsgi.processes %] threads=[% vhost.wsgi.threads %] user=[% vhost.wsgi.user %] group=[% vhost.wsgi.group %] display-name=[% vhost.wsgi.process_group %] listen-backlog=[% vhost.wsgi.listen_backlog %] queue-timeout=[% vhost.wsgi.queue_timeout %] request-timeout=[% vhost.wsgi.request_timeout %] inactivity-timeout=[% vhost.wsgi.inactivity_timeout %] deadlock-timeout=[% vhost.wsgi.deadlock_timeout %] graceful-timeout=[% vhost.wsgi.graceful_timeout %] eviction-timeout=[% vhost.wsgi.eviction_timeout %] + WSGIProcessGroup [% vhost.wsgi.process_group %] + WSGIScriptAlias / [% vhost.wsgi.script_path %]/[% vhost.wsgi.script_name %] WSGIApplicationGroup %{GLOBAL} WSGIPassAuthorization On = 2.4> @@ -26,7 +26,7 @@ Listen [% port %] ErrorLog /var/log/httpd/keystone-error.log CustomLog /var/log/httpd/keystone-access.log combined - + Require all granted diff --git a/features/keystone/wsgi/oidc.pan b/features/keystone/wsgi/oidc.pan index 5e47e8d..c123c5f 100644 --- a/features/keystone/wsgi/oidc.pan +++ b/features/keystone/wsgi/oidc.pan @@ -13,17 +13,19 @@ variable OS_KEYSTONE_FEDERATION_OIDC_PARAMS = { error('%s: attribute missing in OS_KEYSTONE_FEDERATION_OIDC_PARAMS (%s)', identity_provider, attr); }; }; - - SELF[identity_provider]['RedirectURI'] = format('https://%s:5000/v3/OS-FEDERATION/identity_providers/%s/protocols/openid/auth', - OS_KEYSTONE_PUBLIC_CONTROLLER_HOST, - identity_provider, - ); + + SELF[identity_provider]['RedirectURI'] = format( + 'https://%s:5000/v3/OS-FEDERATION/identity_providers/%s/protocols/openid/auth', + OS_KEYSTONE_PUBLIC_HOST, + identity_provider, + ); }; SELF; }; +include 'components/metaconfig/config'; prefix '/software/components/metaconfig/services/{/etc/httpd/conf.d/keystone-oidc.include}'; 'module' = 'openstack/wsgi-keystone-oidc'; 'daemons/httpd' = 'restart'; @@ -35,8 +37,9 @@ bind '/software/components/metaconfig/services/{/etc/httpd/conf.d/keystone-oidc. # Load TT file to configure the keystone OIDCq parameters # Run metaconfig in case the TT file was modified and configuration must be regenerated include 'components/filecopy/config'; -'/software/components/filecopy/dependencies/post' = openstack_add_component_dependency('metaconfig'); -prefix '/software/components/filecopy/services/{/usr/share/templates/quattor/metaconfig/openstack/wsgi-keystone-oidc.tt}'; +prefix '/software/components/filecopy'; +'dependencies/post' = openstack_add_component_dependency('metaconfig'); +prefix 'services/{/usr/share/templates/quattor/metaconfig/openstack/wsgi-keystone-oidc.tt}'; 'config' = file_contents('features/keystone/wsgi/keystone-oidc.tt'); 'perms' = '0644'; diff --git a/features/keystone/wsgi/schema.pan b/features/keystone/wsgi/schema.pan index 12af457..4301c44 100644 --- a/features/keystone/wsgi/schema.pan +++ b/features/keystone/wsgi/schema.pan @@ -1,6 +1,6 @@ declaration template features/keystone/wsgi/schema; -include 'types/openstack/core'; +include 'types/openstack/httpd'; type openstack_keystone_httpd_oidc_provider = { @@ -17,16 +17,3 @@ type openstack_keystone_httpd_oidc_provider = { type openstack_keystone_httpd_oidc = { 'oidc' : openstack_keystone_httpd_oidc_provider{} }; - -type openstack_keystone_httpd_vhost = { - 'port' : type_port - 'processgroup' : string - 'script' : absolute_file_path - 'ssl' : openstack_httpd_ssl_config -}; - -type openstack_keystone_httpd_config = { - 'listen' : type_port[] - 'oidc_enabled' : boolean = false - 'vhosts' : openstack_keystone_httpd_vhost[] -}; diff --git a/features/magnum/config.pan b/features/magnum/config.pan index 16defca..6245b92 100644 --- a/features/magnum/config.pan +++ b/features/magnum/config.pan @@ -1,13 +1,5 @@ unique template features/magnum/config; -@desc{ -desc = defines the cluster creation timeout (max time) -values = long -default = 60 -required = no -} -variable OS_MAGNUM_CLUSTER_CREATION_TIMEOUT ?= 60; - variable OS_NODE_SERVICES = append('magnum'); # Load some useful functions @@ -19,11 +11,29 @@ include 'types/openstack/magnum'; # Include general openstack variables include 'defaults/openstack/config'; +@desc{ +desc = defines the cluster creation timeout (max time) +values = long +default = 60 +required = no +} +variable OS_MAGNUM_CLUSTER_CREATION_TIMEOUT ?= 60; + +variable OS_MAGNUM_API_PROCESSES ?= 8; +variable OS_MAGNUM_GROUP ?= OS_MAGNUM_USERNAME; +variable OS_MAGNUM_LOG_DIR ?= '/var/log/magnum'; + +# Include policy file if OS_MAGNUM_POLICY is defined +include 'components/filecopy/config'; +'/software/components/filecopy/services' = openstack_load_policy('magnum', OS_MAGNUM_POLICY); + + include 'features/magnum/rpms'; include 'components/systemd/config'; prefix '/software/components/systemd/unit'; -'openstack-magnum-api/startstop' = true; +# magnum-api service is disabled as it is run via uwsgi +'openstack-magnum-api/state' = 'disabled'; 'openstack-magnum-conductor/startstop' = true; # Configuration file for Magnum @@ -32,7 +42,7 @@ prefix '/software/components/metaconfig/services/{/etc/magnum/magnum.conf}'; 'module' = 'tiny'; 'convert/joincomma' = true; 'convert/truefalse' = true; -'daemons/openstack-magnum-api' = 'restart'; +# magnum-api doesn't need to be explicitely restarted after a config change: handled by uwsgi 'daemons/openstack-magnum-conductor' = 'restart'; # Restart memcached to ensure considtency with service configuration changes 'daemons/memcached' = 'restart'; @@ -41,16 +51,18 @@ bind '/software/components/metaconfig/services/{/etc/magnum/magnum.conf}/content # [DEFAULT] section 'contents/DEFAULT' = openstack_load_config('features/openstack/base'); 'contents/DEFAULT' = openstack_load_config('features/openstack/logging/' + OS_LOGGING_TYPE); -'contents/DEFAULT' = openstack_load_ssl_config( OS_MAGNUM_PROTOCOL == 'https' ); 'contents/DEFAULT/my_ip' = PRIMARY_IP; -'contents/DEFAULT/log_file' = 'magnum.log'; -'contents/DEFAULT/log_dir' = '/var/log/magnum'; +'contents/DEFAULT/log_dir' = OS_MAGNUM_LOG_DIR; +'contents/DEFAULT/rpc_response_timeout' = 120; # [api] section -'contents/api/host' = OS_MAGNUM_HOST; -'contents/api/port' = OS_MAGNUM_PORT; -'contents/api/enable_ssl' = OS_MAGNUM_PROTOCOL == 'https'; -'contents/api' = openstack_load_ssl_config( OS_MAGNUM_PROTOCOL == 'https' ); +# When using https, the API service is access through a local Nginx proxy +'contents/api/host' = if ( OS_MAGNUM_PROTOCOL == 'https' ) { + '127.0.0.1'; +} else { + OS_MAGNUM_CONTROLLER_HOST; +}; +'contents/api/port' = OS_MAGNUM_CONTROLLER_PORT; # [certificates] section 'contents/certificates/cert_manager_type' = 'barbican'; @@ -65,7 +77,13 @@ bind '/software/components/metaconfig/services/{/etc/magnum/magnum.conf}/content 'contents/cluster_heat/create_timeout' = OS_MAGNUM_CLUSTER_CREATION_TIMEOUT; # [database] section -'contents/database/connection' = format('mysql+pymysql://%s:%s@%s/magnum', OS_MAGNUM_DB_USERNAME, OS_MAGNUM_DB_PASSWORD, OS_MAGNUM_DB_HOST); +'contents/database/connection' = format( + 'mysql+pymysql://%s:%s@%s/magnum', + OS_MAGNUM_DB_USERNAME, + OS_MAGNUM_DB_PASSWORD, + OS_MAGNUM_DB_HOST, +); +'contents/database/max_pool_size' = OS_MAGNUM_DB_POOL_SIZE; # [heat_client] section 'contents/heat_client/region_name' = OS_HEAT_REGION_NAME; @@ -90,6 +108,8 @@ bind '/software/components/metaconfig/services/{/etc/magnum/magnum.conf}/content # [oslo_messaging_rabbit] section 'contents/oslo_messaging_rabbit' = openstack_load_config('features/rabbitmq/openstack/client/base'); +'contents/oslo_messaging_rabbit/heartbeat_in_pthread' = false; +'contents/oslo_messaging_rabbit/kombu_missing_consumer_retry_timeout' = 120; # [trust] section 'contents/trust/cluster_user_trust' = OS_MAGNUM_CLUSTER_USER_TRUST; @@ -97,3 +117,23 @@ bind '/software/components/metaconfig/services/{/etc/magnum/magnum.conf}/content 'contents/trust/trustee_domain_admin_name' = OS_MAGNUM_DOMAIN_ADMIN_USERNAME; 'contents/trust/trustee_domain_admin_password' = OS_MAGNUM_DOMAIN_ADMIN_PASSWORD; 'contents/trust/trustee_keysone_interface' = 'public'; + + +################### +# Configure uSWGI # +################### +include 'features/magnum/uwsgi/config'; + + +######################################### +# Configure SSL proxy if SSL is enabled # +######################################### +include if ( OS_MAGNUM_PROTOCOL == 'https' ) 'features/magnum/nginx/config'; + + +################################################ +# Patches to Magnum K8s initialization scripts # +# Patches must be applied manually # +################################################ +include 'features/magnum/k8s-fragment-fixes'; + diff --git a/features/magnum/k8s-fragment-fixes.pan b/features/magnum/k8s-fragment-fixes.pan new file mode 100644 index 0000000..1dd825b --- /dev/null +++ b/features/magnum/k8s-fragment-fixes.pan @@ -0,0 +1,21 @@ +# Magnum fixes for supporting recent K8s versions +# Fixes must be applied with patch command +unique template features/magnum/k8s-fragment-fixes; + +include 'components/filecopy/config'; +prefix '/software/components/filecopy'; + +# auto-scaling patch +prefix 'services/{/usr/lib/python3.9/site-packages/magnum/drivers/common/templates/kubernetes/fragments/enable-auto-scaling.sh.patch}'; +'config' = file_contents('features/magnum/magnum-k8s-fixes/enable-auto-scaling.sh.patch'); +'perms' = '0644'; + +# cinder-csi patch +prefix 'services/{/usr/lib/python3.9/site-packages/magnum/drivers/common/templates/kubernetes/fragments/enable-cinder-csi.sh.patch}'; +'config' = file_contents('features/magnum/magnum-k8s-fixes/enable-cinder-csi.sh.patch'); +'perms' = '0644'; + +# keystone-auth patch +prefix 'services/{/usr/lib/python3.9/site-packages/magnum/drivers/common/templates/kubernetes/fragments/enable-keystone-auth.sh.patch}'; +'config' = file_contents('features/magnum/magnum-k8s-fixes/enable-keystone-auth.sh.patch'); +'perms' = '0644'; diff --git a/features/magnum/magnum-k8s-fixes/enable-auto-scaling.sh.patch b/features/magnum/magnum-k8s-fixes/enable-auto-scaling.sh.patch new file mode 100644 index 0000000..e3940a5 --- /dev/null +++ b/features/magnum/magnum-k8s-fixes/enable-auto-scaling.sh.patch @@ -0,0 +1,30 @@ +--- /usr/lib/python3.9/site-packages/magnum/drivers/common/templates/kubernetes/fragments/enable-auto-scaling.sh.original 2024-06-25 17:20:49.122542315 +0200 ++++ /usr/lib/python3.9/site-packages/magnum/drivers/common/templates/kubernetes/fragments/enable-auto-scaling.sh 2024-06-26 09:12:01.252586815 +0200 +@@ -38,6 +38,9 @@ + resources: ["endpoints"] + resourceNames: ["cluster-autoscaler"] + verbs: ["get", "update", "patch", "delete"] ++ - apiGroups: [""] ++ resources: ["namespaces"] ++ verbs: ["get", "list"] + # accessing & modifying cluster state (nodes & pods) + - apiGroups: [""] + resources: ["nodes"] +@@ -65,7 +68,7 @@ + resources: ["poddisruptionbudgets"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] +- resources: ["storageclasses", "csinodes"] ++ resources: ["storageclasses", "csinodes", "csidrivers", "csistoragecapacities"] + verbs: ["get", "list", "watch"] + # misc access + - apiGroups: [""] +@@ -136,7 +139,7 @@ + serviceAccountName: cluster-autoscaler-account + containers: + - name: cluster-autoscaler +- image: ${_docker_ca_prefix}cluster-autoscaler:${AUTOSCALER_TAG} ++ image: registry.k8s.io/autoscaling/cluster-autoscaler:${AUTOSCALER_TAG} + imagePullPolicy: Always + command: + - ./cluster-autoscaler diff --git a/features/magnum/magnum-k8s-fixes/enable-cinder-csi.sh.patch b/features/magnum/magnum-k8s-fixes/enable-cinder-csi.sh.patch new file mode 100644 index 0000000..5dfcffe --- /dev/null +++ b/features/magnum/magnum-k8s-fixes/enable-cinder-csi.sh.patch @@ -0,0 +1,83 @@ +--- enable-cinder-csi.sh.original 2024-06-25 17:06:09.379005593 +0200 ++++ enable-cinder-csi.sh 2024-07-05 15:10:25.648732433 +0200 +@@ -233,7 +233,7 @@ + node-role.kubernetes.io/master: "" + containers: + - name: csi-attacher +- image: ${CONTAINER_INFRA_PREFIX:-k8s.gcr.io/sig-storage/}csi-attacher:${CSI_ATTACHER_TAG} ++ image: ${CONTAINER_INFRA_PREFIX:-registry.k8s.io/sig-storage/}csi-attacher:${CSI_ATTACHER_TAG} + args: + - "--csi-address=\$(ADDRESS)" + - "--timeout=3m" +@@ -249,7 +249,7 @@ + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: csi-provisioner +- image: ${CONTAINER_INFRA_PREFIX:-k8s.gcr.io/sig-storage/}csi-provisioner:${CSI_PROVISIONER_TAG} ++ image: ${CONTAINER_INFRA_PREFIX:-registry.k8s.io/sig-storage/}csi-provisioner:${CSI_PROVISIONER_TAG} + args: + - "--csi-address=\$(ADDRESS)" + - "--timeout=3m" +@@ -268,7 +268,7 @@ + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: csi-snapshotter +- image: ${CONTAINER_INFRA_PREFIX:-k8s.gcr.io/sig-storage/}csi-snapshotter:${CSI_SNAPSHOTTER_TAG} ++ image: ${CONTAINER_INFRA_PREFIX:-registry.k8s.io/sig-storage/}csi-snapshotter:${CSI_SNAPSHOTTER_TAG} + args: + - "--csi-address=\$(ADDRESS)" + - "--timeout=3m" +@@ -285,7 +285,7 @@ + - mountPath: /var/lib/csi/sockets/pluginproxy/ + name: socket-dir + - name: csi-resizer +- image: ${CONTAINER_INFRA_PREFIX:-k8s.gcr.io/sig-storage/}csi-resizer:${CSI_RESIZER_TAG} ++ image: ${CONTAINER_INFRA_PREFIX:-registry.k8s.io/sig-storage/}csi-resizer:${CSI_RESIZER_TAG} + args: + - "--csi-address=\$(ADDRESS)" + - "--timeout=3m" +@@ -302,7 +302,7 @@ + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: liveness-probe +- image: ${CONTAINER_INFRA_PREFIX:-k8s.gcr.io/sig-storage/}livenessprobe:${CSI_LIVENESS_PROBE_TAG} ++ image: ${CONTAINER_INFRA_PREFIX:-registry.k8s.io/sig-storage/}livenessprobe:${CSI_LIVENESS_PROBE_TAG} + args: + - "--csi-address=\$(ADDRESS)" + resources: +@@ -315,7 +315,7 @@ + - mountPath: /var/lib/csi/sockets/pluginproxy/ + name: socket-dir + - name: cinder-csi-plugin +- image: ${CONTAINER_INFRA_PREFIX:-docker.io/k8scloudprovider/}cinder-csi-plugin:${CINDER_CSI_PLUGIN_TAG} ++ image: ${CONTAINER_INFRA_PREFIX:-registry.k8s.io/provider-os/}cinder-csi-plugin:${CINDER_CSI_PLUGIN_TAG} + args: + - /bin/cinder-csi-plugin + - "--endpoint=\$(CSI_ENDPOINT)" +@@ -416,7 +416,7 @@ + hostNetwork: true + containers: + - name: node-driver-registrar +- image: ${CONTAINER_INFRA_PREFIX:-k8s.gcr.io/sig-storage/}csi-node-driver-registrar:${CSI_NODE_DRIVER_REGISTRAR_TAG} ++ image: ${CONTAINER_INFRA_PREFIX:-registry.k8s.io/sig-storage/}csi-node-driver-registrar:${CSI_NODE_DRIVER_REGISTRAR_TAG} + args: + - "--csi-address=\$(ADDRESS)" + - "--kubelet-registration-path=\$(DRIVER_REG_SOCK_PATH)" +@@ -436,7 +436,7 @@ + - name: registration-dir + mountPath: /registration + - name: liveness-probe +- image: ${CONTAINER_INFRA_PREFIX:-k8s.gcr.io/sig-storage/}livenessprobe:${CSI_LIVENESS_PROBE_TAG} ++ image: ${CONTAINER_INFRA_PREFIX:-registry.k8s.io/sig-storage/}livenessprobe:${CSI_LIVENESS_PROBE_TAG} + args: + - --csi-address=/csi/csi.sock + resources: +@@ -451,7 +451,7 @@ + capabilities: + add: ["SYS_ADMIN"] + allowPrivilegeEscalation: true +- image: ${CONTAINER_INFRA_PREFIX:-docker.io/k8scloudprovider/}cinder-csi-plugin:${CINDER_CSI_PLUGIN_TAG} ++ image: ${CONTAINER_INFRA_PREFIX:-registry.k8s.io/provider-os/}cinder-csi-plugin:${CINDER_CSI_PLUGIN_TAG} + args: + - /bin/cinder-csi-plugin + - "--endpoint=\$(CSI_ENDPOINT)" diff --git a/features/magnum/magnum-k8s-fixes/enable-keystone-auth.sh.patch b/features/magnum/magnum-k8s-fixes/enable-keystone-auth.sh.patch new file mode 100644 index 0000000..ed7af6f --- /dev/null +++ b/features/magnum/magnum-k8s-fixes/enable-keystone-auth.sh.patch @@ -0,0 +1,11 @@ +--- enable-keystone-auth.sh.original 2024-07-05 15:35:22.868933362 +0200 ++++ enable-keystone-auth.sh 2024-07-05 15:38:46.696212423 +0200 +@@ -4,7 +4,7 @@ + printf "Starting to run ${step}\n" + + if [ "$(echo $KEYSTONE_AUTH_ENABLED | tr '[:upper:]' '[:lower:]')" != "false" ]; then +- _prefix=${CONTAINER_INFRA_PREFIX:-docker.io/k8scloudprovider/} ++ _prefix=${CONTAINER_INFRA_PREFIX:-registry.k8s.io/provider-os/} + CERT_DIR=/etc/kubernetes/certs + + # Create policy configmap for keystone auth diff --git a/features/magnum/nginx/config.pan b/features/magnum/nginx/config.pan new file mode 100644 index 0000000..df95930 --- /dev/null +++ b/features/magnum/nginx/config.pan @@ -0,0 +1,26 @@ +# Add a Nginx VH for handling magnum https requests + +unique template features/magnum/nginx/config; + +variable OS_MAGNUM_PUBLIC_HOST ?= error('OS_MAGNUM_PUBLIC_HOST must be defined when using SSL with Magnum'); +variable OS_MAGNUM_PUBLIC_PORT ?= error('OS_MAGNUM_PUBLIC_PORT must be defined when using SSL with Magnum'); + +include 'types/openstack/core'; + +# Add Nginx and its base configuration +include 'features/nginx/openstack/config'; + +# Nginx proxy configuration for Magnum +include 'components/metaconfig/config'; +prefix '/software/components/metaconfig/services/{/etc/nginx/conf.d/magnum.conf}'; +'module' = 'openstack/nginx-proxy'; +'daemons/nginx' = 'restart'; +# panlint disable=LP006 +bind '/software/components/metaconfig/services/{/etc/nginx/conf.d/magnum.conf}/contents' = openstack_nginx_proxy_config; + +'contents/bind_port' = OS_MAGNUM_PUBLIC_PORT; +'contents/proxy_host' = OS_MAGNUM_CONTROLLER_HOST; +'contents/proxy_port' = OS_MAGNUM_CONTROLLER_PORT; +'contents/server_name' = OS_MAGNUM_PUBLIC_HOST; +'contents/service' = 'magnum'; +'contents/ssl' = openstack_load_ssl_config( true ); diff --git a/features/magnum/uwsgi/config.pan b/features/magnum/uwsgi/config.pan new file mode 100644 index 0000000..3009ce3 --- /dev/null +++ b/features/magnum/uwsgi/config.pan @@ -0,0 +1,32 @@ +unique template features/magnum/uwsgi/config; + + +include 'features/uwsgi/openstack/config'; + +# Load TT file to configure uwsgi application +# Run metaconfig in case the TT file was modified and configuration must be regenerated +include 'components/filecopy/config'; +'/software/components/filecopy/dependencies/post' = openstack_add_component_dependency('metaconfig'); +prefix '/software/components/filecopy/services/{/usr/share/templates/quattor/metaconfig/openstack/magnum-api.tt}'; +'config' = file_contents('features/uwsgi/openstack/vassal-generic.ini.tt'); +'perms' = '0644'; + +# uwsgi configuration for Magnum API: no explicit restart needed, handled by uwsgi when config file changes +include 'components/metaconfig/config'; +prefix '/software/components/metaconfig/services/{/etc/uwsgi.d/magnum-api.ini}'; +'module' = 'openstack/magnum-api'; +# Owner/group must match the one used to run the application +'group' = OS_MAGNUM_GROUP; +'owner' = OS_MAGNUM_USERNAME; +# panlint disable=LP006 +bind '/software/components/metaconfig/services/{/etc/uwsgi.d/magnum-api.ini}/contents' = openstack_uwsgi_application_config; + +'contents/bind_host' = OS_MAGNUM_CONTROLLER_HOST; +'contents/bind_port' = OS_MAGNUM_CONTROLLER_PORT; +'contents/config_files' = list('/etc/magnum/magnum.conf'); +'contents/group' = OS_MAGNUM_GROUP; +'contents/log_file' = format("%s/magnum-api.log", OS_MAGNUM_LOG_DIR); +'contents/processes' = OS_MAGNUM_API_PROCESSES; +'contents/threads' = 1; +'contents/user' = OS_MAGNUM_USERNAME; +'contents/wsgi_file' = '/usr/bin/magnum-api-wsgi'; diff --git a/features/neutron/agents/linuxbridge_agent.pan b/features/neutron/agents/linuxbridge_agent.pan index 706a485..6863c51 100644 --- a/features/neutron/agents/linuxbridge_agent.pan +++ b/features/neutron/agents/linuxbridge_agent.pan @@ -17,6 +17,11 @@ prefix '/software/components/systemd/unit'; include 'components/metaconfig/config'; +# Since Antelope, linuxbridge-agent plugin is considered experimental as it is +# not well maintained. Must be enabled explicitely. +prefix '/software/components/metaconfig/services/{/etc/neutron/neutron.conf}'; +'contents/experimental/linuxbridge' = true; + # Configure Netfilter for linuxbridge-agent # Do not take any special action in case of changes as they are not expected to happen # and taking a change into account basically requires a reboot diff --git a/features/neutron/controller/config.pan b/features/neutron/controller/config.pan index ff9343c..6318823 100644 --- a/features/neutron/controller/config.pan +++ b/features/neutron/controller/config.pan @@ -34,31 +34,8 @@ include 'features/neutron/base'; include 'features/neutron/server'; # Include policy file if OS_NEUTRON_POLICY is defined -@{ -desc = file to load as the policy file. File extension is used to determine the policy file extension -values = path relative to include paths -default = undef -requied = no -} -variable OS_NEUTRON_POLICY ?= undef; include 'components/filecopy/config'; -'/software/components/filecopy/services' = { - if ( is_defined(OS_NEUTRON_POLICY) ) { - toks = matches(OS_NEUTRON_POLICY, '.*\.(json|yaml)$'); - if ( length(toks) < 2 ) { - error('OS_NEUTRON_POLICY must be a file name with the extension .json or .yaml'); - }; - policy_file = format('/etc/neutron/policy.%s', toks[1]); - SELF[escape(policy_file)] = dict( - 'config', file_contents(OS_NEUTRON_POLICY), - 'owner', 'root', - 'perms', '0644', - 'backup', true, - ); - }; - - SELF; -}; +'/software/components/filecopy/services' = openstack_load_policy('neutron', OS_NEUTRON_POLICY); # neutron.conf @@ -74,11 +51,17 @@ prefix '/software/components/metaconfig/services/{/etc/neutron/neutron.conf}'; bind '/software/components/metaconfig/services/{/etc/neutron/neutron.conf}/contents' = openstack_neutron_server_config; # [DEFAULT] +'contents/DEFAULT/bind_host' = if ( OS_NEUTRON_PROTOCOL == 'https' ) { + OS_NEUTRON_CONTROLLER_HOST; +} else { + '0.0.0.0'; +}; +'contents/DEFAULT/bind_port' = OS_NEUTRON_CONTROLLER_PORT; 'contents/DEFAULT/notify_nova_on_port_status_changes' = true; 'contents/DEFAULT/notify_nova_on_port_data_changes' = true; -'contents/DEFAULT/use_ssl' = OS_NEUTRON_CONTROLLER_PROTOCOL == 'https'; 'contents/DEFAULT/api_workers' = OS_NEUTRON_API_WORKERS; 'contents/DEFAULT/rpc_workers' = OS_NEUTRON_RPC_WORKERS; +'contents/DEFAULT/use_ssl' = false; # [database] 'contents/database/connection' = format( @@ -98,5 +81,8 @@ bind '/software/components/metaconfig/services/{/etc/neutron/neutron.conf}/conte # [oslo_concurrency] 'contents/oslo_concurrency/lock_path' = '/var/lib/neutron/tmp'; -# [ssl] section -'contents/ssl' = openstack_load_ssl_config( OS_NEUTRON_CONTROLLER_PROTOCOL == 'https' ); + +######################################### +# Configure SSL proxy if SSL is enabled # +######################################### +include if ( OS_NEUTRON_PROTOCOL == 'https' ) 'features/neutron/controller/nginx/config'; diff --git a/features/neutron/controller/nginx/config.pan b/features/neutron/controller/nginx/config.pan new file mode 100644 index 0000000..03f8c06 --- /dev/null +++ b/features/neutron/controller/nginx/config.pan @@ -0,0 +1,26 @@ +# Add a Nginx VH for handling neutron https requests + +unique template features/neutron/controller/nginx/config; + +variable OS_NEUTRON_PUBLIC_HOST ?= error('OS_NEUTRON_PUBLIC_HOST must be defined when using SSL with Neutron'); +variable OS_NEUTRON_PUBLIC_PORT ?= error('OS_NEUTRON_PUBLIC_PORT must be defined when using SSL with Neutron'); + +include 'types/openstack/core'; + +# Add Nginx and its base configuration +include 'features/nginx/openstack/config'; + +# Nginx proxy configuration for Neutron +include 'components/metaconfig/config'; +prefix '/software/components/metaconfig/services/{/etc/nginx/conf.d/neutron-server.conf}'; +'module' = 'openstack/nginx-proxy'; +'daemons/nginx' = 'restart'; +# panlint disable=LP006 +bind '/software/components/metaconfig/services/{/etc/nginx/conf.d/neutron-server.conf}/contents' = openstack_nginx_proxy_config; + +'contents/bind_port' = OS_NEUTRON_PUBLIC_PORT; +'contents/proxy_host' = OS_NEUTRON_CONTROLLER_HOST; +'contents/proxy_port' = OS_NEUTRON_CONTROLLER_PORT; +'contents/server_name' = OS_NEUTRON_PUBLIC_HOST; +'contents/service' = 'neutron'; +'contents/ssl' = openstack_load_ssl_config( true ); diff --git a/features/nginx/openstack/config.pan b/features/nginx/openstack/config.pan index 2053205..c920e47 100644 --- a/features/nginx/openstack/config.pan +++ b/features/nginx/openstack/config.pan @@ -15,3 +15,6 @@ include 'components/filecopy/config'; prefix '/software/components/filecopy/services/{/usr/share/templates/quattor/metaconfig/openstack/nginx-proxy.tt}'; 'config' = file_contents('features/nginx/openstack/proxy.tt'); 'perms' = '0644'; + +# If ACME protocol is enabled, configure a VH to handle port 80 +include if ( is_defined(OS_SSL_ACME_CHALLENGE_URL) ) 'features/nginx/openstack/port_80'; diff --git a/features/nginx/openstack/port_80.pan b/features/nginx/openstack/port_80.pan new file mode 100644 index 0000000..610ab96 --- /dev/null +++ b/features/nginx/openstack/port_80.pan @@ -0,0 +1,25 @@ +# Template to configure Nbinx port 80 to handle certificate ACME protocol + +unique template features/nginx/openstack/port_80; + +include 'features/nginx/openstack/port_80_schema'; + +# Load TT file to configure the port 80 virtual host, used in particular by certificate ACME protocol +# Run metaconfig in case the TT file was modified and configuration must be regenerated +include 'components/filecopy/config'; +'/software/components/filecopy/dependencies/post' = openstack_add_component_dependency('metaconfig'); +prefix '/software/components/filecopy/services/{/usr/share/templates/quattor/metaconfig/openstack/nginx-port-80.tt}'; +'config' = file_contents('features/nginx/openstack/port_80.tt'); +'perms' = '0644'; + +# Nginx configuration for port 80 virtual host +include 'components/metaconfig/config'; +prefix '/software/components/metaconfig/services/{/etc/nginx/conf.d/port_80.conf}'; +'module' = 'openstack/nginx-port-80'; +'daemons/nginx' = 'restart'; +# panlint disable=LP006 +bind '/software/components/metaconfig/services/{/etc/nginx/conf.d/port_80.conf}/contents' = openstack_nginx_port_80_config; + +# Adding server FQDN is enough to ask a certificate for this name and aliases +'contents/server_name' = FULL_HOSTNAME; +'contents/acme_challenge_url' = OS_SSL_ACME_CHALLENGE_URL; diff --git a/features/nginx/openstack/port_80.tt b/features/nginx/openstack/port_80.tt new file mode 100644 index 0000000..09409ec --- /dev/null +++ b/features/nginx/openstack/port_80.tt @@ -0,0 +1,30 @@ +# Port 80 is configured to handle only AMCE challenge +server { + listen *:80; + listen [::]:80; + server_name [% server_name %]; + access_log /var/log/nginx/[% service %].access.log combined; + error_log /var/log/nginx/[% service %].error.log warn; + + [%- IF acme_challenge_url %] + location ^~ /.well-known/acme-challenge { + alias [% acme_challenge_url %]; + } + [%- END %] + + [%- SET catchall_deny = 1 %] + [%- IF redirect_urls.defined %] + [%- FOREACH redirect IN redirect_urls %] + [%- IF redirect.url == "/" %][% SET catchall_deny = 0 %][% END %] + location [% redirect.url %] { + return 301 [% redirect.target %]$request_uri; + } + [%- END %] + [%- END %] + + [%- IF catchall_deny %] + location / { + deny all; + } + [% END %] +} diff --git a/features/nginx/openstack/port_80_schema.pan b/features/nginx/openstack/port_80_schema.pan new file mode 100644 index 0000000..b8a61e3 --- /dev/null +++ b/features/nginx/openstack/port_80_schema.pan @@ -0,0 +1,19 @@ +unique template features/nginx/openstack/port_80_schema; + +type openstack_nginx_redirect_entry = { + 'target' : type_hostURI + 'url' : type_URI +}; + +@documentation { + Configuration of a Nginx VH used to handle port 80 requests + Configuration restricted to certificate ACMPE protocol by default +} +type openstack_nginx_port_80_config = { + 'acme_challenge_url' ? type_URI + 'server_name' : type_hostname + 'server_aliases' ? string[] + 'service' : string = 'port_80' + 'redirect_urls' ? openstack_nginx_redirect_entry[] +}; + diff --git a/features/nginx/openstack/proxy.tt b/features/nginx/openstack/proxy.tt index 2f43028..17a1ad3 100644 --- a/features/nginx/openstack/proxy.tt +++ b/features/nginx/openstack/proxy.tt @@ -1,11 +1,10 @@ server { - listen [% bind_port %] ssl; - listen [::]:[% bind_port %]; + listen *:[% bind_port %] ssl; + listen [::]:[% bind_port %] ssl; server_name [% server_name %]; access_log /var/log/nginx/[% service %].access.log combined; error_log /var/log/nginx/[% service %].error.log warn; - ssl on; ssl_protocols TLSv1.2 TLSv1.3; ssl_certificate [% ssl.cert_file %]; ssl_certificate_key [% ssl.key_file %]; @@ -13,11 +12,21 @@ server { ssl_session_timeout 10m; client_max_body_size 0; + [%- IF http_https_redirect %] + # If they come here using HTTP (statut=497), bounce them to the correct scheme (https) + error_page 497 https://$server_name:$server_port$request_uri; + [%- END %] + location / { + proxy_buffers [% proxy_buffers_number %] [% proxy_buffers_size %]; proxy_pass http://[% proxy_host %]:[% proxy_port %]; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; proxy_set_header Host $http_host; +[%- IF websocket %] + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; +[%- END %] } } diff --git a/features/nginx/openstack/rpms.pan b/features/nginx/openstack/rpms.pan index 8ca6973..cb89a92 100644 --- a/features/nginx/openstack/rpms.pan +++ b/features/nginx/openstack/rpms.pan @@ -1,13 +1,15 @@ unique template features/nginx/openstack/rpms; -variable OS_NGINX_VERSION ?= "1.22"; +variable OS_NGINX_VERSION ?= "1.24"; +include 'components/spma/config'; '/software/components/spma/modules' = true; '/software/modules' = { - SELF['nginx'] = nlist('stream', OS_NGINX_VERSION, - 'enable', true - ); + SELF['nginx'] = dict( + 'stream', OS_NGINX_VERSION, + 'enable', true, + ); SELF; }; diff --git a/features/nova/common/config.pan b/features/nova/common/config.pan index e6fbe8f..77bc020 100644 --- a/features/nova/common/config.pan +++ b/features/nova/common/config.pan @@ -42,8 +42,10 @@ prefix '/software/components/metaconfig/services/{/etc/nova/nova.conf}'; # [upgrade_levels] section # Require OS_NOVA_UPGRADE_LEVELS to be <= to current server version +# With version >= Zed, names restart at the beginning of the alphabet 'contents/upgrade_levels' = if ( is_defined(OS_NOVA_UPGRADE_LEVELS) ) { - if ( OS_NOVA_UPGRADE_LEVELS <= OPENSTACK_VERSION_NAME ) { + if ( (OS_NOVA_UPGRADE_LEVELS <= OPENSTACK_VERSION_NAME) || + (OPENSTACK_VERSION_NAME <= "liberty") ) { dict('compute', OS_NOVA_UPGRADE_LEVELS); } else { error( diff --git a/features/nova/compute/config.pan b/features/nova/compute/config.pan index 5425058..648ce79 100644 --- a/features/nova/compute/config.pan +++ b/features/nova/compute/config.pan @@ -1,5 +1,16 @@ unique template features/nova/compute/config; +variable OS_NODE_SERVICES = append('nova'); + +# Load some useful functions +include 'defaults/openstack/functions'; + +# Load Nova-related type definitions +include 'types/openstack/nova'; + +# Include general openstack variables +include 'defaults/openstack/config'; + @{ desc = template with site-specific configuration for live-migration values = template path (namespece). Set to null to disable it. @@ -13,11 +24,12 @@ desc = max number of files that can be opened. Must be large enough when \ the compute server has a large number of cores, to accomodate a large \ number of VMs values = long -default = 32 files / physical core (e.g. 4096 on a 128 physical core machine), with a minimum = 1024 +default = 32 files / physical core (e.g. 4096 on a 128 physical core machine), with a minimum = 1024 \ + taking into account the CPU ratio defined in Nova configuration required = no } variable OS_NOVA_COMPUTE_MAX_FILES ?= { - nofile = value('/hardware/cpu/0/cores') * length(value('/hardware/cpu')) * 32; + nofile = to_long(value('/hardware/cpu/0/cores') * length(value('/hardware/cpu')) * OS_NOVA_CPU_RATIO * 32); # 1024 is the default value, do not set a lower value if ( nofile < 1024 ) { nofile = 1024; @@ -25,16 +37,30 @@ variable OS_NOVA_COMPUTE_MAX_FILES ?= { nofile; }; -variable OS_NODE_SERVICES = append('nova'); - -# Load some useful functions -include 'defaults/openstack/functions'; +@{ +desc = file system format to use for ephemeral devices when non specified in (image) metadata +values = string +default = ext4 (xfs has contraints of label legnth improperly handled) +required =no +} +variable OS_NOVA_DEFAULT_EPHEMERAL_FILESYSTEM ?= 'ext4'; -# Load Nova-related type definitions -include 'types/openstack/nova'; +@{ +desc = default HW type per architecture +values = dict where the key is the architecture and the value the machine type +default = see variable +required = no +} +variable OS_NOVA_DEFAULT_HW_TYPE = { + if ( is_null(SELF) ) { + return(undef); + }; + if ( !is_defined(SELF['x86_64']) ) { + SELF['x86_64'] = 'q35'; + }; + SELF; +}; -# Include general openstack variables -include 'defaults/openstack/config'; # Include RPMS for nova hypervisor configuration include 'features/nova/compute/rpms'; @@ -43,31 +69,9 @@ include 'features/nova/compute/rpms'; include 'features/nova/compute/placement'; # Include policy file if OS_NOVA_COMPUTE_POLICY is defined -@{ -desc = file to load as the policy file. File extension is used to determine the policy file extension -values = path relative to include paths -default = undef -requied = no -} -variable OS_NOVA_COMPUTE_POLICY ?= undef; include 'components/filecopy/config'; -'/software/components/filecopy/services' = { - if ( is_defined(OS_NOVA_COMPUTE_POLICY) ) { - toks = matches(OS_NOVA_COMPUTE_POLICY, '.*\.(json|yaml)$'); - if ( length(toks) < 2 ) { - error('OS_NOVA_COMPUTE_POLICY must be a file name with the extension .json or .yaml'); - }; - policy_file = format('/etc/nova/policy.%s', toks[1]); - SELF[escape(policy_file)] = dict( - 'config', file_contents(OS_NOVA_COMPUTE_POLICY), - 'owner', 'root', - 'perms', '0644', - 'backup', true, - ); - }; +'/software/components/filecopy/services' = openstack_load_policy('nova', OS_NOVA_COMPUTE_POLICY); - SELF; -}; # Enable nested virtualization if needed include if ( is_defined(OS_NOVA_COMPUTE_NESTED) && OS_NOVA_COMPUTE_NESTED ) 'features/nova/compute/nested'; @@ -77,13 +81,30 @@ include 'features/nova/compute/vm-migration/config'; # Add site-specific configuration for live migration, if any include OS_NOVA_LIVE_MIGRATION_SITE_CONFIG; -# Restart nova specific daemon +# Restart nova and libvirt daemons include 'components/systemd/config'; -prefix '/software/components/systemd/unit'; -'libvirtd/startstop' = true; -'openstack-nova-compute/startstop' = true; +prefix '/software/components/systemd'; +'unit/openstack-nova-compute/startstop' = true; +# Modular libvirt daemons and sockets +'unit' = { + drivers = list('qemu', 'network', 'nodedev', 'nwfilter', 'secret', 'storage'); + foreach (i; drv; drivers) { + unit_prefix = format('virt%sd', drv); + SELF[unit_prefix] = dict( + 'startstop', false, + 'state', 'enabled', + ); + foreach (j; socket; list('admin', 'ro')) { + SELF[format('%s-%s', unit_prefix, socket)] = dict( + 'startstop', true, + 'type', 'socket', + ); + }; + }; + SELF; +}; -'openstack-nova-compute/file/config/service/LimitNOFILE' = OS_NOVA_COMPUTE_MAX_FILES; +'unit/openstack-nova-compute/file/config/service/LimitNOFILE' = OS_NOVA_COMPUTE_MAX_FILES; # Configuration file for nova include 'components/metaconfig/config'; @@ -91,7 +112,6 @@ prefix '/software/components/metaconfig/services/{/etc/nova/nova.conf}'; 'module' = 'tiny'; 'convert/joincomma' = true; 'convert/truefalse' = true; -'daemons/libvirtd' = 'restart'; 'daemons/openstack-nova-compute' = 'restart'; # Restart memcached to ensure considtency with service configuration changes 'daemons/memcached' = 'restart'; @@ -103,6 +123,7 @@ include 'features/nova/common/config'; # [DEFAULT] section 'contents/DEFAULT/compute_driver' = 'libvirt.LibvirtDriver'; 'contents/DEFAULT/cpu_allocation_ratio' = OS_NOVA_CPU_RATIO; +'contents/DEFAULT/default_ephemeral_format' = OS_NOVA_DEFAULT_EPHEMERAL_FILESYSTEM; 'contents/DEFAULT/initial_cpu_allocation_ratio' = OS_NOVA_INITIAL_CPU_RATIO; 'contents/DEFAULT/disk_allocation_ratio' = OS_NOVA_DISK_RATIO; 'contents/DEFAULT/initial_disk_allocation_ratio' = OS_NOVA_INITIAL_DISK_RATIO; @@ -125,13 +146,31 @@ include 'features/nova/common/config'; }; # [libvirtd] section +'contents/libvirt/hw_machine_type' = if ( is_defined(OS_NOVA_DEFAULT_HW_TYPE) ) { + hw_type_list = ''; + foreach (arch; hw_type; OS_NOVA_DEFAULT_HW_TYPE) { + hw_type_list = format("%s %s=%s", hw_type_list, arch, hw_type); + }; + replace('^\s+', '', hw_type_list); +} else { + null; +}; 'contents/libvirt/virt_type' = OS_NOVA_VIRT_TYPE; +'contents/libvirt/num_pcie_ports' = 28; # [vnc] section 'contents/vnc/enabled' = true; 'contents/vnc/server_listen' = '0.0.0.0'; 'contents/vnc/server_proxyclient_address' = PRIMARY_IP; -'contents/vnc/novncproxy_base_url' = OS_NOVA_VNC_PROTOCOL + '://' + OS_NOVA_VNC_HOST + ':6080/vnc_auto.html'; +'contents/vnc/novncproxy_base_url' = format( + "%s://%s:%s/vnc_lite.html", + OS_NOVA_NOVNC_PROTOCOL, + OS_NOVA_NOVNC_PUBLIC_HOST, + OS_NOVA_NOVNC_PUBLIC_PORT, +); + +# [workarounds] section +'contents/workarounds/skip_cpu_compare_on_dest' = ! OS_NOVA_CPU_CAPABILITIES_CHECK; # Configure Ceph if needed include if ( OS_NOVA_USE_CEPH ) 'features/nova/compute/ceph'; diff --git a/features/nova/compute/nested.pan b/features/nova/compute/nested.pan index bb6bcfa..49e59d8 100644 --- a/features/nova/compute/nested.pan +++ b/features/nova/compute/nested.pan @@ -1,10 +1,17 @@ unique template features/nova/compute/nested; include 'components/modprobe/config'; +include 'components/metaconfig/config'; prefix '/software/components/metaconfig/services/{/etc/nova/nova.conf}/contents'; 'libvirt/cpu_mode' = 'host-passthrough'; -"/software/components/modprobe/modules" = push(nlist("name","kvm_intel","options","nested=1")); -"/software/components/modprobe/modules" = push(nlist("name","kvm_amd","options","nested=1")); +"/software/components/modprobe/modules" = push(dict( + "name", "kvm_intel", + "options", "nested=1", +)); +"/software/components/modprobe/modules" = push(dict( + "name", "kvm_amd", + "options", "nested=1", +)); "/software/components/modprobe/file" = "/etc/modprobe.d/kvm.conf"; diff --git a/features/nova/compute/rpms.pan b/features/nova/compute/rpms.pan index 7160c92..380a5f8 100644 --- a/features/nova/compute/rpms.pan +++ b/features/nova/compute/rpms.pan @@ -5,5 +5,10 @@ unique template features/nova/compute/rpms; pkg_repl('sysfsutils'); pkg_repl('libvirt-client'); + # Antelope: the 2 following RPMs are required for virtio support but are not explicit + # dependencies of openstack-nova-compute + pkg_repl('qemu-kvm-device-display-virtio-gpu.x86_64'); + pkg_repl('qemu-kvm-device-display-virtio-gpu-pci.x86_64'); + SELF; }; diff --git a/features/nova/compute/vm-migration/config.pan b/features/nova/compute/vm-migration/config.pan index ab1b6ba..86f6232 100644 --- a/features/nova/compute/vm-migration/config.pan +++ b/features/nova/compute/vm-migration/config.pan @@ -5,5 +5,3 @@ include 'features/nova/compute/vm-migration/live'; # Configuration specific to cold migration # include 'features/nova/compute/vm-migration/cold'; - - diff --git a/features/nova/compute/vm-migration/live.pan b/features/nova/compute/vm-migration/live.pan index 40ec7f2..f40bb96 100644 --- a/features/nova/compute/vm-migration/live.pan +++ b/features/nova/compute/vm-migration/live.pan @@ -9,26 +9,48 @@ required = no variable OS_NOVA_LIVE_MIGRATION_MODE ?= 'normal'; final variable OS_NOVA_LIVE_MIGRATION_VALID_MODS = list('auto-convergence', 'normal', 'post-copy'); -variable OS_NOVA_LIVE_MIGRATION_MODE = if ( index(OS_NOVA_LIVE_MIGRATION_MODE, OS_NOVA_LIVE_MIGRATION_VALID_MODS) < 0 ) { - error("OS_NOVA_LIVE_MIGRATION_MODE invalid value(%s). Valid values = %s", OS_NOVA_LIVE_MIGRATION_MODE, to_string(OS_NOVA_LIVE_MIGRATION_VALID_MODS)); +variable OS_NOVA_LIVE_MIGRATION_MODE = +if ( index(OS_NOVA_LIVE_MIGRATION_MODE, OS_NOVA_LIVE_MIGRATION_VALID_MODS) < 0 ) { + error( + "OS_NOVA_LIVE_MIGRATION_MODE invalid value(%s). Valid values = %s", + OS_NOVA_LIVE_MIGRATION_MODE, + to_string(OS_NOVA_LIVE_MIGRATION_VALID_MODS), + ); } else { SELF; }; +# Add and enable libvirt-daemon-proxy +include 'components/systemd/config'; +'/software/packages' = pkg_repl('libvirt-daemon-proxy'); +'/software/components/systemd/unit' = { + unit_prefix = 'virtproxyd'; + SELF[unit_prefix] = dict( + 'startstop', false, + 'state', 'enabled', + ); + foreach (j; socket; list('admin', 'ro', 'tcp')) { + SELF[format('%s-%s', unit_prefix, socket)] = dict( + 'startstop', true, + 'type', 'socket', + ); + }; + SELF; +}; + # Define libvirt configuration include 'components/metaconfig/config'; -include 'metaconfig/libvirtd/config'; -prefix '/software/components/metaconfig/services/{/etc/libvirt/libvirtd.conf}/contents'; -'listen_tls' = false; -'listen_tcp' = true; -'auth_tcp' = 'none'; - -include 'components/systemd/config'; -prefix '/software/components/systemd/unit'; -'libvirtd-tcp/startstop' = true; -'libvirtd-tcp/type' = 'socket'; - +prefix '/software/components/metaconfig/services/{/etc/libvirt/virtproxyd.conf}'; +# The mataconfig libvirtd module defines that libvirtd daemon must be restarted when the file changes +# but it doesn't exist anymore on EL9 (modular daemons are started by socket units) +'module' = 'tiny'; +'backup' = '.old'; +'convert/doublequote' = true; +bind '/software/components/metaconfig/services/{/etc/libvirt/virtproxyd.conf}/contents' = openstack_nova_libvirt_proxyd; +'contents/listen_tls' = false; +'contents/listen_tcp' = true; +'contents/auth_tcp' = 'none'; # Enable auto-convergence or post-copy, if requested prefix '/software/components/metaconfig/services/{/etc/nova/nova.conf}'; diff --git a/features/nova/controller/config.pan b/features/nova/controller/config.pan index 2b49161..916c6cb 100644 --- a/features/nova/controller/config.pan +++ b/features/nova/controller/config.pan @@ -13,11 +13,11 @@ include 'defaults/openstack/config'; variable OS_NOVA_SCHEDULER_ENABLED_FILTERS ?= list( - 'AggregateInstanceExtraSpecsFilter', - 'AvailabilityZoneFilter', 'ComputeFilter', + 'AggregateMultiTenancyIsolation', 'ComputeCapabilitiesFilter', 'ImagePropertiesFilter', + 'AggregateInstanceExtraSpecsFilter', 'ServerGroupAntiAffinityFilter', 'ServerGroupAffinityFilter', ); @@ -26,41 +26,25 @@ variable OS_NOVA_SCHEDULER_ENABLED_FILTERS ?= list( # Null value keeps the default of any zone variable OS_NOVA_DEFAULT_SCHEDULE_ZONE ?= null; +final variable OS_NOVA_API_PROCESSES ?= 20; +final variable OS_NOVA_METADATA_PROCESSES ?= 20; +final variable OS_NOVA_GROUP ?= OS_NOVA_USERNAME; + # Install RPMs for compute part of neutron include 'features/nova/controller/rpms'; # Include policy file if OS_NOVA_CONTROLLER_POLICY is defined -@{ -desc = file to load as the policy file. File extension is used to determine the policy file extension -values = path relative to include paths -default = undef -requied = no -} -variable OS_NOVA_CONTROLLER_POLICY ?= undef; include 'components/filecopy/config'; -'/software/components/filecopy/services' = { - if ( is_defined(OS_NOVA_CONTROLLER_POLICY) ) { - toks = matches(OS_NOVA_CONTROLLER_POLICY, '.*\.(json|yaml)$'); - if ( length(toks) < 2 ) { - error('OS_NOVA_CONTROLLER_POLICY must be a file name with the extension .json or .yaml'); - }; - policy_file = format('/etc/nova/policy.%s', toks[1]); - SELF[escape(policy_file)] = dict( - 'config', file_contents(OS_NOVA_CONTROLLER_POLICY), - 'owner', 'root', - 'perms', '0644', - 'backup', true, - ); - }; - - SELF; -}; +'/software/components/filecopy/services' = openstack_load_policy('nova', OS_NOVA_CONTROLLER_POLICY); include 'components/systemd/config'; prefix '/software/components/systemd/unit'; 'openstack-nova-api/startstop' = true; +'openstack-nova-api/state' = 'disabled'; +'openstack-nova-metadata/state' = 'disabled'; +'openstack-nova-metadata/startstop' = true; 'openstack-nova-scheduler/startstop' = true; 'openstack-nova-conductor/startstop' = true; 'openstack-nova-novncproxy/startstop' = true; @@ -70,10 +54,9 @@ prefix '/software/components/metaconfig/services/{/etc/nova/nova.conf}'; 'module' = 'tiny'; 'convert/joincomma' = true; 'convert/truefalse' = true; -'daemons/openstack-nova-api'='restart'; -'daemons/openstack-nova-scheduler'='restart'; -'daemons/openstack-nova-conductor'='restart'; -'daemons/openstack-nova-novncproxy'='restart'; +# Do not restart services managed by uwsgi on configuration changes +'daemons/openstack-nova-conductor' = 'restart'; +'daemons/openstack-nova-novncproxy' = 'restart'; # Restart memcached to ensure considtency with service configuration changes 'daemons/memcached' = 'restart'; bind '/software/components/metaconfig/services/{/etc/nova/nova.conf}/contents' = openstack_nova_server_config; @@ -83,38 +66,36 @@ bind '/software/components/metaconfig/services/{/etc/nova/nova.conf}/contents' = include 'features/nova/common/config'; # [DEFAULT] section -'contents/DEFAULT' = openstack_load_ssl_config( OS_NOVA_CONTROLLER_PROTOCOL == 'https' ); -'contents/DEFAULT/default_schedule_zone' = OS_NOVA_DEFAULT_SCHEDULE_ZONE; 'contents/DEFAULT/cpu_allocation_ratio' = OS_NOVA_CPU_RATIO; +'contents/DEFAULT/default_schedule_zone' = OS_NOVA_DEFAULT_SCHEDULE_ZONE; 'contents/DEFAULT/enabled_apis' = list('osapi_compute', 'metadata'); -'contents/DEFAULT/enabled_ssl_apis' = if ( OS_NOVA_CONTROLLER_PROTOCOL == 'https') { - list('osapi_compute'); +'contents/DEFAULT/my_ip' = PRIMARY_IP; +'contents/DEFAULT/osapi_compute_listen' = if ( OS_NOVA_PROTOCOL == 'https' ) { + OS_NOVA_CONTROLLER_HOST; } else { - null; + '0.0.0.0'; }; -'contents/DEFAULT/my_ip' = PRIMARY_IP; +'contents/DEFAULT/osapi_compute_listen_port' = OS_NOVA_CONTROLLER_PORT; 'contents/DEFAULT/ram_allocation_ratio' = OS_NOVA_RAM_RATIO; -# Enable SSL for novnc -'contents/DEFAULT' = { - if ( OS_NOVA_CONTROLLER_PROTOCOL == 'https' ) { - SELF['cert'] = SELF['cert_file']; - SELF['key'] = SELF['key_file']; - SELF['ssl_only'] = true; - } else { - SELF['ssl_only'] = false; - }; - SELF; -}; - # [api] section 'contents/api/dhcp_domain' = OS_NEUTRON_DNS_DOMAIN; # [api_database] section -'contents/api_database/connection' = format('mysql+pymysql://%s:%s@%s/nova_api', OS_NOVA_DB_USERNAME, OS_NOVA_DB_PASSWORD, OS_NOVA_DB_HOST); +'contents/api_database/connection' = format( + 'mysql+pymysql://%s:%s@%s/nova_api', + OS_NOVA_DB_USERNAME, + OS_NOVA_DB_PASSWORD, + OS_NOVA_DB_HOST, +); # [database] section -'contents/database/connection' = format('mysql+pymysql://%s:%s@%s/nova', OS_NOVA_DB_USERNAME, OS_NOVA_DB_PASSWORD, OS_NOVA_DB_HOST); +'contents/database/connection' = format( + 'mysql+pymysql://%s:%s@%s/nova', + OS_NOVA_DB_USERNAME, + OS_NOVA_DB_PASSWORD, + OS_NOVA_DB_HOST, +); # [filter_scheduler] section 'contents/filter_scheduler/available_filters' = list('nova.scheduler.filters.all_filters'); @@ -136,6 +117,9 @@ include 'features/nova/common/config'; #[oslo_messaging_notifications] section 'contents/oslo_messaging_notifications' = openstack_load_config('features/oslo_messaging/notifications'); +# [oslo_messaging_rabbit] section +'contents/oslo_messaging_rabbit/heartbeat_in_pthread' = false; + # [placement] section 'contents/placement/os_region_name' = OS_REGION_NAME; 'contents/placement/project_domain_name' = 'default'; @@ -146,17 +130,18 @@ include 'features/nova/common/config'; 'contents/placement/auth_url' = OS_KEYSTONE_CONTROLLER_PROTOCOL + '://' + OS_KEYSTONE_CONTROLLER_HOST + ':35357/v3'; 'contents/placement/auth_type' = 'password'; -# [wsgi] section -'contents/wsgi' = openstack_load_ssl_config( OS_NOVA_CONTROLLER_PROTOCOL == 'https' ); -'contents/wsgi/ssl_cert_file' = if ( exists('/software/components/metaconfig/services/{/etc/nova/nova.conf}/contents/wsgi/cert_file') ) { - value('/software/components/metaconfig/services/{/etc/nova/nova.conf}/contents/wsgi/cert_file'); -} else { - null; -}; -'contents/wsgi/ssl_key_file' = if ( exists('/software/components/metaconfig/services/{/etc/nova/nova.conf}/contents/wsgi/key_file') ) { - value('/software/components/metaconfig/services/{/etc/nova/nova.conf}/contents/wsgi/key_file'); -} else { - null; -}; -'contents/wsgi/cert_file' = null; -'contents/wsgi/key_file' = null; +# [vnc] section +'contents/vnc/novncproxy_host' = OS_NOVA_NOVNC_CONTROLLER_HOST; +'contents/vnc/novncproxy_port' = OS_NOVA_NOVNC_CONTROLLER_PORT; + + +################### +# Configure uSWGI # +################### +include 'features/nova/controller/uwsgi/config'; + + +######################################### +# Configure SSL proxy if SSL is enabled # +######################################### +include if ( OS_NOVA_PROTOCOL == 'https' ) 'features/nova/controller/nginx/config'; diff --git a/features/nova/controller/nginx/config.pan b/features/nova/controller/nginx/config.pan new file mode 100644 index 0000000..3181d4e --- /dev/null +++ b/features/nova/controller/nginx/config.pan @@ -0,0 +1,41 @@ +# Add a Nginx VH for handling nova https requests + +unique template features/nova/controller/nginx/config; + +variable OS_NOVA_PUBLIC_HOST ?= error('OS_NOVA_PUBLIC_HOST must be defined when using SSL with Nova'); +variable OS_NOVA_PUBLIC_PORT ?= error('OS_NOVA_PUBLIC_PORT must be defined when using SSL with Nova'); + +include 'types/openstack/core'; + +# Add Nginx and its base configuration +include 'features/nginx/openstack/config'; + +# Nginx proxy configuration for Nova API +include 'components/metaconfig/config'; +prefix '/software/components/metaconfig/services/{/etc/nginx/conf.d/nova-api.conf}'; +'module' = 'openstack/nginx-proxy'; +'daemons/nginx' = 'restart'; +# panlint disable=LP006 +bind '/software/components/metaconfig/services/{/etc/nginx/conf.d/nova-api.conf}/contents' = openstack_nginx_proxy_config; + +'contents/bind_port' = OS_NOVA_PUBLIC_PORT; +'contents/proxy_host' = OS_NOVA_CONTROLLER_HOST; +'contents/proxy_port' = OS_NOVA_CONTROLLER_PORT; +'contents/server_name' = OS_NOVA_PUBLIC_HOST; +'contents/service' = 'nova'; +'contents/ssl' = openstack_load_ssl_config( true ); + +# Nginx proxy configuration for Nova noVNC proxy +prefix '/software/components/metaconfig/services/{/etc/nginx/conf.d/nova-novnc.conf}'; +'module' = 'openstack/nginx-proxy'; +'daemons/nginx' = 'restart'; +# panlint disable=LP006 +bind '/software/components/metaconfig/services/{/etc/nginx/conf.d/nova-novnc.conf}/contents' = openstack_nginx_proxy_config; + +'contents/bind_port' = OS_NOVA_NOVNC_PUBLIC_PORT; +'contents/proxy_host' = OS_NOVA_NOVNC_CONTROLLER_HOST; +'contents/proxy_port' = OS_NOVA_NOVNC_CONTROLLER_PORT; +'contents/server_name' = OS_NOVA_NOVNC_PUBLIC_HOST; +'contents/service' = 'nova-novnc'; +'contents/ssl' = openstack_load_ssl_config( true ); +'contents/websocket' = true; diff --git a/features/nova/controller/rpms.pan b/features/nova/controller/rpms.pan index f9aaaa1..fc0d1d3 100644 --- a/features/nova/controller/rpms.pan +++ b/features/nova/controller/rpms.pan @@ -9,7 +9,6 @@ include 'defaults/openstack/functions'; pkg_repl('openstack-nova-scheduler'); pkg_repl('python3-etcd3gw'); pkg_repl('python3-novaclient'); - openstack_add_httpd_packages( OS_NOVA_CONTROLLER_PROTOCOL == 'https' ); SELF; }; diff --git a/features/nova/controller/uwsgi/config.pan b/features/nova/controller/uwsgi/config.pan new file mode 100644 index 0000000..9bab75e --- /dev/null +++ b/features/nova/controller/uwsgi/config.pan @@ -0,0 +1,71 @@ +unique template features/nova/controller/uwsgi/config; + + +include 'features/uwsgi/openstack/config'; + + +############ +# nova-api # +############ + +# Load TT file to configure uwsgi application +# Run metaconfig in case the TT file was modified and configuration must be regenerated +include 'components/filecopy/config'; +'/software/components/filecopy/dependencies/post' = openstack_add_component_dependency('metaconfig'); +prefix '/software/components/filecopy/services/{/usr/share/templates/quattor/metaconfig/openstack/nova-api.tt}'; +'config' = file_contents('features/uwsgi/openstack/vassal-generic.ini.tt'); +'perms' = '0644'; + +# uwsgi configuration for Nova API: no explicit restart needed, handled by uwsgi when config file changes +include 'components/metaconfig/config'; +prefix '/software/components/metaconfig/services/{/etc/uwsgi.d/nova-api.ini}'; +'module' = 'openstack/nova-api'; +# Owner/group must match the one used to run the application +'group' = OS_NOVA_GROUP; +'owner' = OS_NOVA_USERNAME; +# panlint disable=LP006 +bind '/software/components/metaconfig/services/{/etc/uwsgi.d/nova-api.ini}/contents' = openstack_uwsgi_application_config; + +'contents/bind_host' = OS_NOVA_CONTROLLER_HOST; +'contents/bind_port' = OS_NOVA_CONTROLLER_PORT; +'contents/config_files' = list('/etc/nova/nova.conf'); +'contents/config_files' = list('/etc/nova/nova.conf'); +'contents/group' = OS_NOVA_GROUP; +'contents/log_file' = format("%s/uwsgi-api.log", OS_NOVA_LOG_DIR); +'contents/processes' = OS_NOVA_API_PROCESSES; +'contents/threads' = 1; +'contents/user' = OS_NOVA_USERNAME; +'contents/wsgi_file' = '/usr/bin/nova-api-wsgi'; + + +################# +# nova-metadata # +################# + +# Load TT file to configure uwsgi application +# Run metaconfig in case the TT file was modified and configuration must be regenerated +include 'components/filecopy/config'; +'/software/components/filecopy/dependencies/post' = openstack_add_component_dependency('metaconfig'); +prefix '/software/components/filecopy/services/{/usr/share/templates/quattor/metaconfig/openstack/nova-metadata.tt}'; +'config' = file_contents('features/uwsgi/openstack/vassal-generic.ini.tt'); +'perms' = '0644'; + +# uwsgi configuration for Nova metadata service: no explicit restart needed, handled by uwsgi when config file changes +prefix '/software/components/metaconfig/services/{/etc/uwsgi.d/nova-metadata.ini}'; +'module' = 'openstack/nova-metadata'; +# Owner/group must match the one used to run the application +'group' = OS_NOVA_GROUP; +'owner' = OS_NOVA_USERNAME; +# panlint disable=LP006 +bind '/software/components/metaconfig/services/{/etc/uwsgi.d/nova-metadata.ini}/contents' = openstack_uwsgi_application_config; + +'contents/bind_host' = OS_NOVA_CONTROLLER_HOST; +'contents/bind_port' = OS_NOVA_METADATA_PORT; +'contents/config_files' = list('/etc/nova/nova.conf'); +'contents/config_files' = list('/etc/nova/nova.conf'); +'contents/group' = OS_NOVA_GROUP; +'contents/log_file' = format("%s/uwsgi-metadata.log", OS_NOVA_LOG_DIR); +'contents/processes' = OS_NOVA_METADATA_PROCESSES; +'contents/threads' = 1; +'contents/user' = OS_NOVA_USERNAME; +'contents/wsgi_file' = '/usr/bin/nova-metadata-wsgi'; diff --git a/features/octavia/config.pan b/features/octavia/config.pan index df2b01e..afc4af5 100644 --- a/features/octavia/config.pan +++ b/features/octavia/config.pan @@ -11,9 +11,14 @@ include 'types/openstack/octavia'; # Include general openstack variables include 'defaults/openstack/config'; -# Configure gunicorn -# 2024-03-17: Work in progress - not working yet -#include 'features/octavia/gunicorn/config'; + +@{ +desc = number of processes to handle Octavia API requests +values = long +default = 16 +required = no +} +variable OS_OCTAVIA_API_PROCESSES ?= 16; @{ desc = password used to encrypt CA private key for both Octavia CAs @@ -60,6 +65,13 @@ variable OS_OCTAVIA_HEARTBEAT_KEY = if ( length(OS_OCTAVIA_HEARTBEAT_KEY) >= 20 error('OS_OCTAVIA_HEARTBEAT_KEY must be at least 20-character long'); }; +@{ +desc = Directory for Octavia services +values = absolute file path +default = /var/log/octavia +required = no +} +variable OS_OCTAVIA_LOG_DIR ?= '/var/log/octavia'; @{ desc = Octavia management network OpenStack ID @@ -87,22 +99,29 @@ variable OS_OCTAVIA_SERVICE_SSH_KEY ?= error( # For the following parameters, default values should be appropriate include 'features/octavia/management-network/defaults'; -variable OS_OCTAVIA_API_BIND_PORT ?= 9876; -variable OS_OCTAVIA_HEALTH_MANAGER_BIND_PORT ?= 5555; +variable OS_OCTAVIA_API_PORT ?= OS_OCTAVIA_CONTROLLER_PORT; +variable OS_OCTAVIA_HEALTH_MANAGER_PORT ?= 5555; variable OS_OCTAVIA_HEALTH_MANAGER_CONTROLLER_IP_PORT_LIST ?= list(format( '%s:%s', OS_OCTAVIA_MGMT_NETWORK_MGT_PORT_IP, - OS_OCTAVIA_HEALTH_MANAGER_BIND_PORT, + OS_OCTAVIA_HEALTH_MANAGER_PORT, )); +variable OS_OCTAVIA_GROUP ?= OS_OCTAVIA_USERNAME; + + +# Include policy file if OS_OCTAVIA_POLICY is defined +include 'components/filecopy/config'; +'/software/components/filecopy/services' = openstack_load_policy('octavia', OS_OCTAVIA_POLICY); -# Add Glance bae RPMs +# Add Octavia bae RPMs include 'features/octavia/rpms'; -# Configgure Glance services +# Configgure Octavia services include 'components/systemd/config'; prefix '/software/components/systemd/unit'; -'octavia-api/startstop' = true; +# octavia-api service is disabled as it is run via uwsgi +'octavia-api/state' = 'disabled'; 'octavia-health-manager/startstop' = true; 'octavia-housekeeping/startstop' = true; 'octavia-worker/startstop' = true; @@ -117,7 +136,7 @@ prefix '/software/components/metaconfig/services/{/etc/octavia/octavia.conf}'; 'module' = 'tiny'; 'convert/joincomma' = true; 'convert/truefalse' = true; -'daemons/octavia-api' = 'restart'; +# octavia-api doesn't need to be explicitely restarted after a config change: handled by uwsgi 'daemons/octavia-health-manager' = 'restart'; 'daemons/octavia-housekeeping' = 'restart'; 'daemons/octavia-worker' = 'restart'; @@ -131,7 +150,7 @@ bind '/software/components/metaconfig/services/{/etc/octavia/octavia.conf}/conte 'contents/DEFAULT' = openstack_load_config('features/openstack/logging/' + OS_LOGGING_TYPE); # [api_settings] section -'contents/api_settings/bind_port' = OS_OCTAVIA_API_BIND_PORT; +'contents/api_settings/bind_port' = OS_OCTAVIA_API_PORT; # [certificates] section 'contents/certificates/ca_certificate' = format('%s/server_ca.cert.pem', OS_OCTAVIA_CA_CERT_DIR); @@ -159,7 +178,7 @@ bind '/software/components/metaconfig/services/{/etc/octavia/octavia.conf}/conte # [health_manager] section 'contents/health_manager/bind_ip' = OS_OCTAVIA_MGMT_NETWORK_MGT_PORT_IP; -'contents/health_manager/bind_port' = OS_OCTAVIA_HEALTH_MANAGER_BIND_PORT; +'contents/health_manager/bind_port' = OS_OCTAVIA_HEALTH_MANAGER_PORT; 'contents/health_manager/controller_ip_port_list' = OS_OCTAVIA_HEALTH_MANAGER_CONTROLLER_IP_PORT_LIST; 'contents/health_manager/heartbeat_key' = OS_OCTAVIA_HEARTBEAT_KEY; @@ -174,6 +193,10 @@ bind '/software/components/metaconfig/services/{/etc/octavia/octavia.conf}/conte # [oslo_messaging_notifications] section 'contents/oslo_messaging_notifications' = openstack_load_config('features/oslo_messaging/notifications'); +#[oslo_messaging_rabbit] section +'contents/oslo_messaging_rabbit' = openstack_load_config('features/rabbitmq/openstack/client/base'); +'contents/oslo_messaging_rabbit/heartbeat_in_pthread' = false; + # [service_auth] section 'contents/service_auth' = value( '/software/components/metaconfig/services/{/etc/octavia/octavia.conf}/contents/keystone_authtoken' @@ -216,3 +239,14 @@ prefix '/software/components/filecopy/services/{/root/octavia-initialization.REA 'perms' = '0644'; +################### +# Configure uSWGI # +################### +include 'features/octavia/uwsgi/config'; + + +######################################### +# Configure SSL proxy if SSL is enabled # +######################################### +include if ( OS_OCTAVIA_PROTOCOL == 'https' ) 'features/octavia/nginx/config'; + diff --git a/features/octavia/dual_CA/config.pan b/features/octavia/dual_CA/config.pan index 6fdd079..f51a904 100644 --- a/features/octavia/dual_CA/config.pan +++ b/features/octavia/dual_CA/config.pan @@ -14,11 +14,13 @@ include 'components/metaconfig/config'; # Create CA creation script # ############################# -prefix '/software/components/filecopy/services/{/usr/share/templates/quattor/metaconfig/openstack/create_dual_intermediate_CA.tt}'; +prefix '/software/components/filecopy/services'; +prefix '{/usr/share/templates/quattor/metaconfig/openstack/create_dual_intermediate_CA.tt}'; 'config' = file_contents('features/octavia/dual_CA/create_dual_intermediate_CA.sh.tt'); 'perms' = '0644'; -prefix '/software/components/metaconfig/services/{/root/octavia_ca/create_dual_intermediate_CA.sh}'; +prefix '/software/components/metaconfig/services'; +prefix '{/root/octavia_ca/create_dual_intermediate_CA.sh}'; 'module' = 'openstack/create_dual_intermediate_CA'; 'convert/truefalse' = true; 'convert/joincomma' = true; @@ -37,7 +39,8 @@ prefix '/software/components/filecopy/services/{/root/octavia_ca/priv_key_pwd}'; # Create openssl.cnf used by the creation script # ################################################## -prefix '/software/components/filecopy/services/{/usr/share/templates/quattor/metaconfig/openstack/openssl.cnf.tt}'; +prefix '/software/components/filecopy'; +prefix '{/usr/share/templates/quattor/metaconfig/openstack/openssl.cnf.tt}'; 'config' = file_contents('features/octavia/dual_CA/openssl.cnf.tt'); 'perms' = '0644'; @@ -47,7 +50,9 @@ prefix '/software/components/metaconfig/services/{/root/octavia_ca/openssl.cnf}' 'convert/joincomma' = true; 'mode' = 0600; bind '/software/components/metaconfig/services/{/root/octavia_ca/openssl.cnf}/contents' = octavia_ca_parameters_config; -'contents' = value('/software/components/metaconfig/services/{/root/octavia_ca/create_dual_intermediate_CA.sh}/contents'); +'contents' = { + value('/software/components/metaconfig/services/{/root/octavia_ca/create_dual_intermediate_CA.sh}/contents'); +}; ############################################################# @@ -56,11 +61,11 @@ bind '/software/components/metaconfig/services/{/root/octavia_ca/openssl.cnf}/co include 'components/dirperm/config'; prefix '/software/components/dirperm'; 'paths' = { - SELF[length(SELF)] = dict( - 'path', OS_OCTAVIA_CA_CERT_DIR, - 'owner', 'octavia:octavia', - 'type', 'd', - 'perm', '0755', - ); - SELF; + SELF[length(SELF)] = dict( + 'path', OS_OCTAVIA_CA_CERT_DIR, + 'owner', format('%s:%s', OS_OCTAVIA_USERNAME, OS_OCTAVIA_GROUP), + 'type', 'd', + 'perm', '0755', + ); + SELF; }; diff --git a/features/octavia/gunicorn/config.pan b/features/octavia/gunicorn/config.pan deleted file mode 100644 index d29c142..0000000 --- a/features/octavia/gunicorn/config.pan +++ /dev/null @@ -1,17 +0,0 @@ -unique template features/octavia/gunicorn/config; - - -# Include gunicorn base configuration -include 'features/openstack/gunicorn/config'; - - -# Define gunicorn configuration for Octavia -include 'components/metaconfig/config'; -prefix '/software/components/metaconfig/services/{/etc/sysconfig/gunicorn.octavia}'; -'module' = 'tiny'; -# panlint disable=LP006 -bind '/software/components/metaconfig/services/{/etc/sysconfig/gunicorn.octavia}/contents' = openstack_gunicorn_sysconfig; - -'contents/GUNICORN_APP' = "\"'octavia.api.app:setup_app()'\""; -'contents/GUNICORN_APP_CONFIG' = '/var/lib/octavia/gunicorn_app.py'; -'contents/GUNICORN_APP_DIR' = '/etc/octavia'; diff --git a/features/octavia/management-network/config.pan b/features/octavia/management-network/config.pan index 70687cd..665affa 100644 --- a/features/octavia/management-network/config.pan +++ b/features/octavia/management-network/config.pan @@ -33,7 +33,8 @@ required = no variable OS_OCTAVIA_MGMT_NETWORK_MGMT_PORT_MAC ?= error( "%s\n%s", "You must define OS_OCTAVIA_MGMT_NETWORK_MGMT_PORT_MAC with the MAC address of the management port", - "on the management network as reported by the creation script. If it has not yet been created, use temporily 'ff:ff:ff:ff:ff:ff'", + "on the management network as reported by the creation script. If it has not yet been created, " + + "use temporily 'ff:ff:ff:ff:ff:ff'", ); @@ -101,16 +102,19 @@ prefix '/software/components/systemd/unit/octavia-interface/file/config/service' prefix '/software/components/metaconfig/services/{/etc/sysconfig/octavia-interface}'; 'module' = 'tiny'; 'daemons/octavia-interface' = 'restart'; +# panlint disable=LP006 bind '/software/components/metaconfig/services/{/etc/sysconfig/octavia-interface}/contents' = octavia_mgt_interface_service_config; 'contents/BRNAME' = openstack_add_if_defined(OS_OCTAVIA_MGMT_NETWORK_BRNAME); -'contents/HM_BIND_PORT' = OS_OCTAVIA_HEALTH_MANAGER_BIND_PORT; +'contents/HM_BIND_PORT' = OS_OCTAVIA_HEALTH_MANAGER_PORT; 'contents/MGMT_PORT_MAC' = openstack_add_if_defined(OS_OCTAVIA_MGMT_NETWORK_MGMT_PORT_MAC); 'contents/MGMT_VLAN_ID' = OS_OCTAVIA_MGMT_NETWORK_VLAN_ID; 'contents/VXLAN_DEVICE' = openstack_add_if_defined(OS_OCTAVIA_MGMT_NETWORK_VXLAN_DEVICE); # Create interface definition in network service when running on the Neutron server -include if ( OS_OCTAVIA_PUBLIC_HOST == OS_NEUTRON_PUBLIC_HOST ) 'features/octavia/management_network/add_systemd_interface'; +include if ( OS_OCTAVIA_PUBLIC_HOST == OS_NEUTRON_PUBLIC_HOST ) { + 'features/octavia/management_network/add_systemd_interface'; +}; # Configure DHCP client for management network # Note: before octavia-interface is fully configured, the service restart when the dhcp client diff --git a/features/octavia/management-network/octavia-only-interface.sh.templ b/features/octavia/management-network/octavia-only-interface.sh.templ index b360575..2d29174 100644 --- a/features/octavia/management-network/octavia-only-interface.sh.templ +++ b/features/octavia/management-network/octavia-only-interface.sh.templ @@ -34,8 +34,7 @@ if [ "$1" == "start" ]; then ip a show ${vxlan_if} >& /dev/null || exit_code=$? [[ ${exit_code} -eq 0 ]] && echo "Interface ${vxlan_if} already exists" && exit 0 ip link add ${vxlan_if} type vxlan id ${MGMT_VLAN_ID} group 224.0.0.1 dev ${VXLAN_DEVICE} srcport 0 0 dstport 8472 - ip link set dev ${vxlan_if} address $MGMT_PORT_MAC - ifconfig ${vxlan_if} up + ip link set dev ${vxlan_if} up address $MGMT_PORT_MAC iptables -I INPUT -i o-hm0 -p udp --dport ${HM_BIND_PORT} -j ACCEPT dhclient -v ${vxlan_if} -cf /etc/dhcp/octavia elif [ "$1" == "stop" ]; then diff --git a/features/octavia/nginx/config.pan b/features/octavia/nginx/config.pan new file mode 100644 index 0000000..e162f41 --- /dev/null +++ b/features/octavia/nginx/config.pan @@ -0,0 +1,26 @@ +# Add a Nginx VH for handling octavia https requests + +unique template features/octavia/nginx/config; + +variable OS_OCTAVIA_PUBLIC_HOST ?= error('OS_OCTAVIA_PUBLIC_HOST must be defined when using SSL with Octavia'); +variable OS_OCTAVIA_PUBLIC_PORT ?= error('OS_OCTAVIA_PUBLIC_PORT must be defined when using SSL with Octavia'); + +include 'types/openstack/core'; + +# Add Nginx and its base configuration +include 'features/nginx/openstack/config'; + +# Nginx proxy configuration for Octavia +include 'components/metaconfig/config'; +prefix '/software/components/metaconfig/services/{/etc/nginx/conf.d/octavia.conf}'; +'module' = 'openstack/nginx-proxy'; +'daemons/nginx' = 'restart'; +# panlint disable=LP006 +bind '/software/components/metaconfig/services/{/etc/nginx/conf.d/octavia.conf}/contents' = openstack_nginx_proxy_config; + +'contents/bind_port' = OS_OCTAVIA_PUBLIC_PORT; +'contents/proxy_host' = OS_OCTAVIA_CONTROLLER_HOST; +'contents/proxy_port' = OS_OCTAVIA_CONTROLLER_PORT; +'contents/server_name' = OS_OCTAVIA_PUBLIC_HOST; +'contents/service' = 'octavia'; +'contents/ssl' = openstack_load_ssl_config( true ); diff --git a/features/octavia/octavia_rc_script.pan b/features/octavia/octavia_rc_script.pan index e557a7f..ed8d98e 100644 --- a/features/octavia/octavia_rc_script.pan +++ b/features/octavia/octavia_rc_script.pan @@ -17,11 +17,11 @@ bind '/software/components/metaconfig/services/{/root/openstack-octavia-rc}/cont 'contents/config/OS_AUTH_URL' = format( '%s://%s:%s/v3', OS_KEYSTONE_CONTROLLER_PROTOCOL, - OS_KEYSTONE_PUBLIC_CONTROLLER_HOST, - OS_KEYSTONE_PUBLIC_CONTROLLER_PORT + OS_KEYSTONE_PUBLIC_HOST, + OS_KEYSTONE_PUBLIC_STANDARD_PORT ); -'contents/config/OS_PASSWORD' = OS_OCTAVIA_PASSWORD; -'contents/config/OS_PROJECT_DOMAIN_NAME' = 'Default'; -'contents/config/OS_PROJECT_NAME' = 'service'; -'contents/config/OS_USER_DOMAIN_NAME' = 'Default'; -'contents/config/OS_USERNAME' = OS_OCTAVIA_USERNAME; +'contents/config/OS_PASSWORD' = OS_OCTAVIA_PASSWORD; +'contents/config/OS_PROJECT_DOMAIN_NAME' = 'Default'; +'contents/config/OS_PROJECT_NAME' = 'service'; +'contents/config/OS_USER_DOMAIN_NAME' = 'Default'; +'contents/config/OS_USERNAME' = OS_OCTAVIA_USERNAME; diff --git a/features/octavia/uwsgi/config.pan b/features/octavia/uwsgi/config.pan new file mode 100644 index 0000000..e6983d4 --- /dev/null +++ b/features/octavia/uwsgi/config.pan @@ -0,0 +1,32 @@ +unique template features/octavia/uwsgi/config; + + +include 'features/uwsgi/openstack/config'; + +# Load TT file to configure uwsgi application +# Run metaconfig in case the TT file was modified and configuration must be regenerated +include 'components/filecopy/config'; +'/software/components/filecopy/dependencies/post' = openstack_add_component_dependency('metaconfig'); +prefix '/software/components/filecopy/services/{/usr/share/templates/quattor/metaconfig/openstack/octavia-api.tt}'; +'config' = file_contents('features/uwsgi/openstack/vassal-generic.ini.tt'); +'perms' = '0644'; + +# uwsgi configuration for Octavia API: no explicit restart needed, handled by uwsgi when config file changes +include 'components/metaconfig/config'; +prefix '/software/components/metaconfig/services/{/etc/uwsgi.d/octavia-api.ini}'; +'module' = 'openstack/octavia-api'; +# Owner/group must match the one used to run the application +'group' = OS_OCTAVIA_GROUP; +'owner' = OS_OCTAVIA_USERNAME; +bind '/software/components/metaconfig/services/{/etc/uwsgi.d/octavia-api.ini}/contents' = openstack_uwsgi_application_config; + +'contents/bind_host' = OS_OCTAVIA_CONTROLLER_HOST; +'contents/bind_port' = OS_OCTAVIA_API_PORT; +'contents/config_files' = list('/etc/octavia/octavia.conf'); +'contents/config_files' = list('/etc/octavia/octavia.conf'); +'contents/group' = OS_OCTAVIA_GROUP; +'contents/log_file' = format("%s/api.log", OS_OCTAVIA_LOG_DIR); +'contents/processes' = OS_OCTAVIA_API_PROCESSES; +'contents/threads' = 1; +'contents/user' = OS_OCTAVIA_USERNAME; +'contents/wsgi_file' = '/usr/bin/octavia-wsgi'; diff --git a/features/openldap/openstack/config.pan b/features/openldap/openstack/config.pan deleted file mode 100644 index 40d3d21..0000000 --- a/features/openldap/openstack/config.pan +++ /dev/null @@ -1,18 +0,0 @@ -unique template features/openldap/openstack/config; - -include 'features/openldap/openstack/rpms'; - -include 'components/systemd/config'; -prefix '/software/components/systemd/unit'; -'slapd/startstop' = true; - -# Configure a very basic DB_CONFIG -include 'components/metaconfig/config'; -include 'features/openldap/openstack/schema'; -prefix '/software/components/metaconfig/services/{/var/lib/ldap/DB_CONFIG}'; -'module' = 'general'; -bind '/software/components/metaconfig/services/{/var/lib/ldap/DB_CONFIG}/contents' = openstack_openldap_config; - -'contents/set_cachesize' = '0 268435456 1'; -'contents/set_lg_regionmax' = 262144; -'contents/set_lg_bsize' = 2097152; diff --git a/features/openldap/openstack/rpms.pan b/features/openldap/openstack/rpms.pan deleted file mode 100644 index 3c28faf..0000000 --- a/features/openldap/openstack/rpms.pan +++ /dev/null @@ -1,3 +0,0 @@ -unique template features/openldap/openstack/rpms; - -'/software/packages' = pkg_repl('openldap-servers'); diff --git a/features/openldap/openstack/schema.pan b/features/openldap/openstack/schema.pan deleted file mode 100644 index e63416d..0000000 --- a/features/openldap/openstack/schema.pan +++ /dev/null @@ -1,7 +0,0 @@ -declaration template features/openldap/openstack/schema; - -type openstack_openldap_config = { - 'set_cachesize' ? string - 'set_lg_bsize' ? long - 'set_lg_regionmax' ? long -}; diff --git a/features/openstack/base.pan b/features/openstack/base.pan index 3b5ac55..8c704e5 100644 --- a/features/openstack/base.pan +++ b/features/openstack/base.pan @@ -1,4 +1,4 @@ structure template features/openstack/base; 'auth_strategy' = 'keystone'; -'transport_url' = format('rabbit://%s:%s@%s//', OS_RABBITMQ_USERNAME, OS_RABBITMQ_PASSWORD, OS_RABBITMQ_HOST); +'transport_url' = format('rabbit://%s:%s@%s/', OS_RABBITMQ_USERNAME, OS_RABBITMQ_PASSWORD, OS_RABBITMQ_HOST); diff --git a/features/pci-passthrough/compute/config.pan b/features/pci-passthrough/compute/config.pan index c0244c2..8b36ead 100644 --- a/features/pci-passthrough/compute/config.pan +++ b/features/pci-passthrough/compute/config.pan @@ -1,12 +1,21 @@ unique template features/pci-passthrough/compute/config; -variable PCI_IDS = dict('vendor', '10de', 'product', '2204', 'name', 'rtx3090'); +variable PCI_IDS = dict('vendor', '10de', 'product', '2231', 'name', 'rtxA5000'); include 'components/metaconfig/config'; prefix '/software/components/metaconfig/services/{/etc/nova/nova.conf}/contents'; -'pci/passthrough_whitelist' = '{ "vendor_id": "' + PCI_IDS['vendor'] + '", "product_id": "' + PCI_IDS['product'] + '" }'; -'pci/alias' = '{ "vendor_id": "' + PCI_IDS['vendor'] + '", "product_id": "' + PCI_IDS['product'] + '", "name": "' + PCI_IDS['name'] + '" }'; +'pci/device_spec' = format( + '{ "vendor_id": "%s", "product_id": "%s" }', + PCI_IDS['vendor'], + PCI_IDS['product'], +); +'pci/alias' = format( + '{ "vendor_id": "%s", "product_id": "%s", "name": "%s" }', + PCI_IDS['vendor'], + PCI_IDS['product'], + PCI_IDS['name'], +); include 'components/grub/config'; @@ -16,7 +25,10 @@ prefix '/software/components/grub'; include 'components/modprobe/config'; prefix '/software/components/modprobe'; 'modules' = { - SELF[length(SELF)] = dict('name', 'vfio-pci', 'options', 'ids=' + PCI_IDS['vendor'] + ':' + PCI_IDS['product'] + ''); - SELF[length(SELF)] = dict('name', 'snd_hda_intel', 'blacklist', 'snd_hda_intel'); - SELF; + SELF[length(SELF)] = dict( + 'name', 'vfio-pci', + 'options', format('ids=%s:%s', PCI_IDS['vendor'], PCI_IDS['product']), + ); + SELF[length(SELF)] = dict('name', 'snd_hda_intel', 'blacklist', 'snd_hda_intel'); + SELF; }; diff --git a/features/placement/config.pan b/features/placement/config.pan index 554d326..bbf4cb8 100644 --- a/features/placement/config.pan +++ b/features/placement/config.pan @@ -2,6 +2,10 @@ unique template features/placement/config; variable OS_NODE_SERVICES = append('placement'); +variable OS_PLACEMENT_API_PROCESSES ?= 8; +variable OS_PLACEMENT_GROUP ?= OS_PLACEMENT_USERNAME; +variable OS_PLACEMENT_LOG_DIR ?= '/var/log/placement'; + # Load some useful functions include 'defaults/openstack/functions'; @@ -11,18 +15,18 @@ include 'types/openstack/placement'; # Include general openstack variables include 'defaults/openstack/config'; +# Include policy file if OS_PLACEMENT_POLICY is defined +include 'components/filecopy/config'; +'/software/components/filecopy/services' = openstack_load_policy('placement', OS_PLACEMENT_POLICY); + + # Install RPMs for placement include 'features/placement/rpms'; -# Configure httpd -include 'features/httpd/openstack/config'; -include 'features/placement/wsgi/config'; - # Configure placement section include 'components/metaconfig/config'; prefix '/software/components/metaconfig/services/{/etc/placement/placement.conf}'; 'module' = 'tiny'; -'daemons/httpd' = 'restart'; 'convert/joincomma' = true; 'convert/truefalse' = true; # Restart memcached to ensure considtency with service configuration changes @@ -44,4 +48,26 @@ bind '/software/components/metaconfig/services/{/etc/placement/placement.conf}/c 'contents/placement/randomize_allocation_candidates' = false; # [placement_database] section -'contents/placement_database/connection' = format('mysql+pymysql://%s:%s@%s/placement', OS_PLACEMENT_DB_USERNAME, OS_PLACEMENT_DB_PASSWORD, OS_PLACEMENT_DB_HOST); +'contents/placement_database/connection' = format( + 'mysql+pymysql://%s:%s@%s/placement', + OS_PLACEMENT_DB_USERNAME, + OS_PLACEMENT_DB_PASSWORD, + OS_PLACEMENT_DB_HOST +); + +#[oslo_messaging_rabbit] section +'contents/oslo_messaging_rabbit' = openstack_load_config('features/rabbitmq/openstack/client/base'); +'contents/oslo_messaging_rabbit/heartbeat_in_pthread' = false; + +################### +# Configure uSWGI # +################### +include 'features/placement/uwsgi/config'; + + +######################################### +# Configure SSL proxy if SSL is enabled # +######################################### +include if ( OS_PLACEMENT_PROTOCOL == 'https' ) 'features/placement/nginx/config'; + + diff --git a/features/placement/nginx/config.pan b/features/placement/nginx/config.pan new file mode 100644 index 0000000..a137570 --- /dev/null +++ b/features/placement/nginx/config.pan @@ -0,0 +1,26 @@ +# Add a Nginx VH for handling placement https requests + +unique template features/placement/nginx/config; + +variable OS_PLACEMENT_PUBLIC_HOST ?= error('OS_PLACEMENT_PUBLIC_HOST must be defined when using SSL with Placement'); +variable OS_PLACEMENT_PUBLIC_PORT ?= error('OS_PLACEMENT_PUBLIC_PORT must be defined when using SSL with Placement'); + +include 'types/openstack/core'; + +# Add Nginx and its base configuration +include 'features/nginx/openstack/config'; + +# Nginx proxy configuration for Placement +include 'components/metaconfig/config'; +prefix '/software/components/metaconfig/services/{/etc/nginx/conf.d/placement.conf}'; +'module' = 'openstack/nginx-proxy'; +'daemons/nginx' = 'restart'; +# panlint disable=LP006 +bind '/software/components/metaconfig/services/{/etc/nginx/conf.d/placement.conf}/contents' = openstack_nginx_proxy_config; + +'contents/bind_port' = OS_PLACEMENT_PUBLIC_PORT; +'contents/proxy_host' = OS_PLACEMENT_CONTROLLER_HOST; +'contents/proxy_port' = OS_PLACEMENT_CONTROLLER_PORT; +'contents/server_name' = OS_PLACEMENT_PUBLIC_HOST; +'contents/service' = 'placement'; +'contents/ssl' = openstack_load_ssl_config( true ); diff --git a/features/placement/rpms.pan b/features/placement/rpms.pan index 0cc610a..62963e3 100644 --- a/features/placement/rpms.pan +++ b/features/placement/rpms.pan @@ -3,7 +3,6 @@ unique template features/placement/rpms; '/software/packages' = { pkg_repl('openstack-placement-api'); pkg_repl('python3-osc-placement'); - openstack_add_httpd_packages( OS_PLACEMENT_CONTROLLER_PROTOCOL == 'https' ); SELF; }; diff --git a/features/placement/uwsgi/config.pan b/features/placement/uwsgi/config.pan new file mode 100644 index 0000000..860cb20 --- /dev/null +++ b/features/placement/uwsgi/config.pan @@ -0,0 +1,33 @@ +unique template features/placement/uwsgi/config; + + +include 'features/uwsgi/openstack/config'; + +# Load TT file to configure uwsgi application +# Run metaconfig in case the TT file was modified and configuration must be regenerated +include 'components/filecopy/config'; +'/software/components/filecopy/dependencies/post' = openstack_add_component_dependency('metaconfig'); +prefix '/software/components/filecopy/services/{/usr/share/templates/quattor/metaconfig/openstack/placement-api.tt}'; +'config' = file_contents('features/uwsgi/openstack/vassal-generic.ini.tt'); +'perms' = '0644'; + +# uwsgi configuration for Placement API: no explicit restart needed, handled by uwsgi when config file changes +include 'components/metaconfig/config'; +prefix '/software/components/metaconfig/services/{/etc/uwsgi.d/placement-api.ini}'; +'module' = 'openstack/placement-api'; +# Owner/group must match the one used to run the application +'group' = OS_PLACEMENT_GROUP; +'owner' = OS_PLACEMENT_USERNAME; +# panlint disable=LP006 +bind '/software/components/metaconfig/services/{/etc/uwsgi.d/placement-api.ini}/contents' = openstack_uwsgi_application_config; + +'contents/bind_host' = OS_PLACEMENT_CONTROLLER_HOST; +'contents/bind_port' = OS_PLACEMENT_CONTROLLER_PORT; +'contents/config_files' = list('/etc/placement/placement.conf'); +'contents/config_files' = list('/etc/placement/placement.conf'); +'contents/group' = OS_PLACEMENT_GROUP; +'contents/log_file' = format("%s/api.log", OS_PLACEMENT_LOG_DIR); +'contents/processes' = OS_PLACEMENT_API_PROCESSES; +'contents/threads' = 1; +'contents/user' = OS_PLACEMENT_USERNAME; +'contents/wsgi_file' = '/usr/bin/placement-api'; diff --git a/features/placement/wsgi/config.pan b/features/placement/wsgi/config.pan deleted file mode 100644 index ba8453d..0000000 --- a/features/placement/wsgi/config.pan +++ /dev/null @@ -1,24 +0,0 @@ -unique template features/placement/wsgi/config; - -include 'features/placement/wsgi/schema'; - -# WSGI configuration: overwrite the httpd conf file provided by the RPM -prefix '/software/components/metaconfig/services/{/etc/httpd/conf.d/00-placement-api.conf}'; -'module' = 'openstack/wsgi-placement'; -'daemons/httpd' = 'restart'; -bind '/software/components/metaconfig/services/{/etc/httpd/conf.d/00-placement-api.conf}/contents' = openstack_placement_httpd_config; - -'contents/port' = OS_PLACEMENT_CONTROLLER_PORT; -'contents/ssl' = openstack_load_ssl_config( OS_PLACEMENT_CONTROLLER_PROTOCOL == 'https' ); -'contents/ssl' ?= dict(); - - -# Load TT file to configure Placement virtual host -# Run metaconfig in case the TT file was modified and configuration must be regenerated -include 'components/filecopy/config'; -'/software/components/filecopy/dependencies/post' = openstack_add_component_dependency('metaconfig'); -prefix '/software/components/filecopy/services/{/usr/share/templates/quattor/metaconfig/openstack/wsgi-placement.tt}'; -'config' = file_contents('features/placement/wsgi/placement.tt'); -'perms' = '0644'; - - diff --git a/features/placement/wsgi/placement.tt b/features/placement/wsgi/placement.tt deleted file mode 100644 index e27fda1..0000000 --- a/features/placement/wsgi/placement.tt +++ /dev/null @@ -1,31 +0,0 @@ -Listen [% port %] - - - WSGIProcessGroup placement-api - WSGIApplicationGroup %{GLOBAL} - WSGIPassAuthorization On - WSGIDaemonProcess placement-api processes=3 threads=1 user=placement group=placement - - WSGIScriptAlias / /usr/bin/placement-api - - ErrorLogFormat "%M" - ErrorLog [% log_file %] - - SSLEngine On - SSLCertificateFile [% ssl.cert_file %] - SSLCertificateKeyFile [% ssl.key_file %] - - -Alias /placement-api /usr/bin/placement-api - - - SetHandler wsgi-script - Options +ExecCGI - WSGIProcessGroup placement-api - WSGIApplicationGroup %{GLOBAL} - WSGIPassAuthorization On - - - - Require all granted - diff --git a/features/placement/wsgi/schema.pan b/features/placement/wsgi/schema.pan deleted file mode 100644 index 4a929c8..0000000 --- a/features/placement/wsgi/schema.pan +++ /dev/null @@ -1,10 +0,0 @@ -declaration template features/placement/wsgi/schema; - -include 'types/openstack/core'; - - -type openstack_placement_httpd_config = { - 'log_file' : absolute_file_path = '/var/log/placement/placement-api.log' - 'port' : long(1..65535) = 8778 - 'ssl' : openstack_httpd_ssl_config -}; diff --git a/features/rabbitmq/config.pan b/features/rabbitmq/config.pan index 84c14cc..a65e08f 100644 --- a/features/rabbitmq/config.pan +++ b/features/rabbitmq/config.pan @@ -6,15 +6,29 @@ include 'components/systemd/config'; prefix '/software/components/systemd/unit'; 'rabbitmq-server/startstop' = true; +include 'components/metaconfig/config'; +prefix '/software/components/metaconfig/services/{/etc/rabbitmq/rabbitmq.conf}'; +'module' = 'tiny'; +'convert/truefalse' = true; +'daemons/rabbitmq-server' = 'restart'; + +'contents/heartbeat' = 120; +'contents/tcp_listen_options.backlog' = 4096; +'contents/tcp_listen_options.nodelay' = true; +'contents/tcp_listen_options.linger.on' = true; +'contents/tcp_listen_options.linger.timeout' = 0; +'contents/tcp_listen_options.exit_on_close' = false; + + # /var/run/rabbitmq is not created by RPMs include 'components/dirperm/config'; prefix '/software/components/dirperm'; 'paths' = { - SELF[length(SELF)] = dict( - 'path', '/var/run/rabbitmq', - 'owner', 'rabbitmq:rabbitmq', - 'type', 'd', - 'perm', '0755', - ); - SELF; + SELF[length(SELF)] = dict( + 'path', '/var/run/rabbitmq', + 'owner', 'rabbitmq:rabbitmq', + 'type', 'd', + 'perm', '0755', + ); + SELF; }; diff --git a/features/uwsgi/openstack/config.pan b/features/uwsgi/openstack/config.pan new file mode 100644 index 0000000..bc09b32 --- /dev/null +++ b/features/uwsgi/openstack/config.pan @@ -0,0 +1,28 @@ +unique template features/uwsgi/openstack/config; + +variable OS_UWSGI_BIN ?= '/usr/sbin/uwsgi'; + +# Add RPM +'/software/packages' = pkg_repl('uwsgi-plugin-python3'); + +# Create a systemd service for uwsgi +include 'components/systemd/config'; +'/software/components/systemd/skip/service' = false; + +'/software/components/systemd/unit/{uwsgi}/file/replace' = true; +'/software/components/systemd/unit/{uwsgi}/startstop' = true; + +prefix '/software/components/systemd/unit/{uwsgi}/file/config/unit'; +'Description' = 'uSWGI service'; +'After' = list('syslog.target', 'network.target'); + +prefix '/software/components/systemd/unit/{uwsgi}/file/config/install'; +'WantedBy' = list('multi-user.target'); + +prefix '/software/components/systemd/unit/{uwsgi}/file/config/service'; +'ExecStart' = format("%s --ini /etc/uwsgi.ini", OS_UWSGI_BIN); +'KillSignal' = 'SIGQUIT'; +'NotifyAccess' = 'all'; +'PrivateTmp' = true; +'Restart' = 'on-failure'; +'SyslogIdentifier' = 'uwsgi'; diff --git a/features/uwsgi/openstack/vassal-generic.ini.tt b/features/uwsgi/openstack/vassal-generic.ini.tt new file mode 100644 index 0000000..c763c02 --- /dev/null +++ b/features/uwsgi/openstack/vassal-generic.ini.tt @@ -0,0 +1,29 @@ +[uwsgi] +uid = [% user %] +gid = [% group %] + +wsgi-file = [% wsgi_file %] +touch-reload = [% wsgi_file %] +[%- IF config_files %] +[%- FOREACH file IN config_files %] +touch-reload = [% file %] +[%- END %] +[%- END %] +socket = [% bind_host %]:[% bind_port %] +protocol = http +plugin = python3 + +master = true +single-interpreter = true +enable-threads = true +processes = [% processes %] +threads = [% threads %] +exit-on-reload = true +die-on-term = true +lazy-apps = true +add-header = Connection: close +[%- IF buffer_size %] +buffer-size = [% buffer_size %] +[%- END %] +thunder-lock = true +logto = [% log_file %] diff --git a/features/uwsgi/openstack/vassal-paste_deploy.ini.tt b/features/uwsgi/openstack/vassal-paste_deploy.ini.tt new file mode 100644 index 0000000..d4706a0 --- /dev/null +++ b/features/uwsgi/openstack/vassal-paste_deploy.ini.tt @@ -0,0 +1,22 @@ +[uwsgi] +uid = [% user %] +gid = [% group %] +socket = [% bind_host %]:[% bind_port %] +protocol = http +processes = [% processes %] +lazy = true +vacuum = true +no-default-app = true +memory-report = true +plugins = python3 +paste = config:[% wsgi_file %] +touch-reload = [% wsgi_file %] +[%- IF config_files %] +[%- FOREACH file IN config_files %] +touch-reload = [% file %] +[%- END %] +[%- END %] +add-header = Connection: close +[%- IF buffer_size %] +buffer-size = [% buffer_size %] +[%- END %] diff --git a/personality/dashboard/config.pan b/personality/dashboard/config.pan index d9d2b25..972846a 100644 --- a/personality/dashboard/config.pan +++ b/personality/dashboard/config.pan @@ -2,4 +2,4 @@ unique template personality/dashboard/config; include 'features/memcache/config'; -include 'features/dashboard/config'; +include 'features/horizon/config'; diff --git a/types/openstack/barbican.pan b/types/openstack/barbican.pan index 42e7a56..2a63db6 100644 --- a/types/openstack/barbican.pan +++ b/types/openstack/barbican.pan @@ -13,6 +13,7 @@ type openstack_barbican_defaults = { include openstack_DEFAULTS 'host_href' : type_hostURI 'sql_connection': string + 'wsgi_default_pool_size': number }; @documentation { @@ -21,4 +22,5 @@ type openstack_barbican_defaults = { type openstack_barbican_config = { 'DEFAULT' : openstack_barbican_defaults 'keystone_authtoken' : openstack_keystone_authtoken + 'oslo_messaging_rabbit' ? openstack_oslo_messaging_rabbit }; diff --git a/types/openstack/cinder.pan b/types/openstack/cinder.pan index f7585ac..b5694fc 100644 --- a/types/openstack/cinder.pan +++ b/types/openstack/cinder.pan @@ -15,6 +15,7 @@ type openstack_cinder_defaults = { 'enable_v3_api' ? boolean 'enabled_backends' ? string[] 'glance_api_servers' : type_hostURI[] + 'osapi_volume_listen' ? type_hostname 'osapi_volume_listen_port' ? long(1..65535) 'public_endpoint' ? type_hostURI }; @@ -33,7 +34,7 @@ type openstack_cinder_backend_defaults = { 'rados_connect_timeout' ? long = -1 'rbd_ceph_conf' ? absolute_file_path = '/etc/ceph/ceph.conf' 'rbd_exclusive_cinder_pool' ? boolean = false - 'rbd_flatten_volume_from_snapshot' ? boolean + 'rbd_flatten_volume_from_snapshot' ? boolean 'rbd_max_clone_depth' ? long = 5 'rbd_pool' ? string = 'rbd' 'rbd_secret_uuid' ? string diff --git a/types/openstack/core.pan b/types/openstack/core.pan index cb4a141..c96a2bc 100644 --- a/types/openstack/core.pan +++ b/types/openstack/core.pan @@ -28,6 +28,7 @@ type openstack_DEFAULTS = { 'log_file' ? string 'my_ip' ? type_ip 'notifications' ? string + 'rpc_response_timeout' : long = 120 'transport_url' : type_hostURI }; @@ -103,11 +104,18 @@ type openstack_keystone_memcache = { } type openstack_nginx_proxy_config = { 'bind_port' : type_port - 'proxy_host' : type_hostname + # http_https_redirect forwards a plain http request received on a ssl port to https + # Normally not needed + 'http_https_redirect': boolean = false + 'proxy_buffers_number' : long = 16 + 'proxy_buffers_size' : long = 65535 + 'proxy_host' : type_hostname = '127.0.0.1' 'proxy_port' : type_port 'server_name' : type_hostname 'service' : string 'ssl' : openstack_httpd_ssl_config + # Set to true if proxying websocket connections where connection must not be closed + 'websocket' : boolean = false }; @@ -136,6 +144,9 @@ type openstack_oslo_messaging_notifications = { The configuration options in the oslo_messaging_rabbit section } type openstack_oslo_messaging_rabbit = { + 'heartbeat_in_pthread' ? boolean + 'heartbeat_timeout_threshold' : long = 120 + 'kombu_missing_consumer_retry_timeout' : long = 120 'rabbit_host' ? type_hostname 'rabbit_hosts' ? string # with match('*:*') 'rabbit_userid' ? string @@ -174,3 +185,20 @@ type openstack_trustee = { 'user_domain_id' ? string }; +@documentation { + Configuration for a uwsgi application +} +type openstack_uwsgi_application_config = { + 'bind_host' : type_hostname = '0.0.0.0' + 'bind_port' : type_port + 'buffer_size' ? long(256..) + 'config_files' ? absolute_file_path[] + 'group' : string + 'log_file' : absolute_file_path + 'processes' : long(1..) + 'threads' ? long(1..) + 'user' : string + 'wsgi_file' : absolute_file_path +}; + + diff --git a/types/openstack/glance.pan b/types/openstack/glance.pan index a4b469a..f00da66 100644 --- a/types/openstack/glance.pan +++ b/types/openstack/glance.pan @@ -12,6 +12,7 @@ include 'types/openstack/core'; type openstack_glance_defaults = { include openstack_DEFAULTS + 'bind_host' ? type_hostname 'bind_port' ? long(1..65535) 'enabled_backends' ? string[] 'location_strategy' ? choice('location_order', 'store_type') diff --git a/types/openstack/heat.pan b/types/openstack/heat.pan index 6d24690..6f0b2ee 100644 --- a/types/openstack/heat.pan +++ b/types/openstack/heat.pan @@ -21,6 +21,13 @@ type openstack_heat_defaults = { 'stack_user_domain_name' : string }; +@documentation { + [heat_api] section for Heat +}; +type openstack_heat_api_config = { + 'bind_port' ? type_port = 8004 +}; + @documentation { list of Heat configuration sections } @@ -29,6 +36,7 @@ type openstack_heat_config = { 'clients_keystone' : openstack_clients_keystone 'database' : openstack_database 'ec2authtoken' ? openstack_ec2authtoken + 'heat_api' ? openstack_heat_api_config 'keystone_authtoken' : openstack_keystone_authtoken 'oslo_messaging_notifications' ? openstack_oslo_messaging_notifications 'oslo_messaging_rabbit' ? openstack_oslo_messaging_rabbit diff --git a/types/openstack/httpd.pan b/types/openstack/httpd.pan new file mode 100644 index 0000000..2a5737a --- /dev/null +++ b/types/openstack/httpd.pan @@ -0,0 +1,45 @@ +declaration template types/openstack/httpd; + +@{ + WSGI parameters for vhost + All parameters are required to simplify the TT file + Default values are appropriate for Keystone +} +type openstack_httpd_wsgi_config = { + 'deadlock_timeout' : long = 60 + 'display_name' : string = '%(GROUP)' + 'eviction_timeout' : long = 0 + 'graceful_timeout' : long = 15 + 'group' : string = 'keystone' + 'inactivity_timeout' : long = 0 + 'listen_backlog' : long = 100 + 'maximum_requests' : long = 0 + 'process_group' : string + 'processes' : long = 15 + 'queue_timeout' : long = 45 + 'request_timeout' : long = 60 + 'script_name' : string + 'script_path' : absolute_file_path + 'threads' : long = 20 + 'user' : string = 'keystone' +}; + +@{ + Configuration of a httpd vhost +} +type openstack_httpd_vhost = { + 'bind_host' : type_hostname = '0.0.0.0' + 'port' : type_port + 'ssl' ? openstack_httpd_ssl_config + 'wsgi' ? openstack_httpd_wsgi_config +}; + +@{ + httpd configurtion +} +type openstack_httpd_config = { + 'listen' : type_port[] + 'oidc_enabled' : boolean = false + 'vhosts' : openstack_httpd_vhost[] +}; + diff --git a/types/openstack/neutron.pan b/types/openstack/neutron.pan index f2f0816..0a7aac9 100644 --- a/types/openstack/neutron.pan +++ b/types/openstack/neutron.pan @@ -14,6 +14,8 @@ type openstack_neutron_server_defaults_config = { 'allow_overlapping_ips': boolean = false 'api_workers' ? long 'base_mac' ? type_hwaddr + 'bind_host' : type_hostname + 'bind_port' : type_port 'core_plugin' ? string 'dns_domain' ? type_fqdn 'dvr_base_mac' ? type_hwaddr @@ -24,22 +26,31 @@ type openstack_neutron_server_defaults_config = { 'use_ssl' : boolean }; +@documentation { + parameters for neutron [experimental] section +} +type openstack_neutron_experimental = { + 'linuxbridge' ? boolean = false +}; + @documentation { list of common neutron configuration sections } type openstack_neutron_base_config = { - 'DEFAULT' : openstack_DEFAULTS + 'experimental' ? openstack_neutron_experimental 'keystone_authtoken' : openstack_keystone_authtoken 'oslo_concurrency': openstack_oslo_concurrency - 'oslo_messaging_rabbit' ? openstack_oslo_messaging_rabbit 'oslo_messaging_notifications' ? openstack_oslo_messaging_notifications + 'oslo_messaging_rabbit' ? openstack_oslo_messaging_rabbit }; @documentation { - list of neutron configuration sections + list of neutron compute configuration sections } type openstack_neutron_compute_config = { include openstack_neutron_base_config + + 'DEFAULT' : openstack_DEFAULTS }; @documentation { @@ -47,18 +58,18 @@ type openstack_neutron_compute_config = { } type openstack_neutron_network_config = { include openstack_neutron_base_config + + 'DEFAULT' : openstack_DEFAULTS }; @documentation { list of neutron server configuration sections } type openstack_neutron_server_config = { + include openstack_neutron_base_config + 'DEFAULT' : openstack_neutron_server_defaults_config 'database' : openstack_database - 'keystone_authtoken' : openstack_keystone_authtoken 'nova': openstack_keystone_authtoken - 'oslo_concurrency': openstack_oslo_concurrency - 'oslo_messaging_notifications' ? openstack_oslo_messaging_notifications - 'oslo_messaging_rabbit' ? openstack_oslo_messaging_rabbit 'ssl' ? openstack_httpd_ssl_config }; diff --git a/types/openstack/nova.pan b/types/openstack/nova.pan index 8e570f9..90220ac 100644 --- a/types/openstack/nova.pan +++ b/types/openstack/nova.pan @@ -8,7 +8,7 @@ include 'types/openstack/core'; @documentation { DEFAULT section for Nova -}; +} type openstack_nova_defaults = { include openstack_DEFAULTS @@ -24,6 +24,7 @@ type openstack_nova_defaults = { 'ram_allocation_ratio' ? double with SELF > 0 'initial_ram_allocation_ratio' ? double with SELF > 0 'resume_guests_state_on_host_boot' : boolean = false + 'rpc_response_timeout' ? long # Parameters related to SSL 'cert' ? absolute_file_path @@ -43,9 +44,26 @@ type openstack_nova_defaults = { 'compute_monitors' ? string[] 'enabled_apis' : string[] = list('osapi_compute', 'metadata') 'enabled_ssl_apis' : string[] = list() + 'osapi_compute_listen' ? type_hostname + 'osapi_compute_listen_port' ? type_port 'state_path' ? absolute_file_path }; +@documentation { + DEFAULT section for Nova compute +} +type openstack_nova_compute_defaults = { + include openstack_nova_defaults + + 'default_ephemeral_format' ? choice ( + 'ext2', + 'ext3', + 'ext4', + 'xfs', + 'ntfs' + ) +}; + @documentation { parameters for nova configuration [api] section } @@ -67,6 +85,13 @@ type openstack_nova_cinder = { 'os_region_name': string }; +@documentation { + parameters for nova compute configuration [workarounds] section +} +type openstack_nova_compute_workarounds = { + 'skip_cpu_compare_on_dest' ? boolean +}; + @documentation { parameters for nova configuration [filter_scheduler] section } @@ -94,6 +119,7 @@ type openstack_nova_glance = { } type openstack_nova_libvirt = { 'cpu_mode' ? string + 'hw_machine_type' ? string with length(SELF) > 0 && match(SELF, '^(\w+=\w+\s*)+$') 'disk_cachemodes' ? string[] 'hw_disk_discard' ? choice('ignore', 'unmap') 'images_rbd_ceph_conf' ? string @@ -106,6 +132,7 @@ type openstack_nova_libvirt = { 'inject_partition' ? long with SELF >= -2 'live_migration_permit_auto_converge' ? boolean 'live_migration_permit_post_copy' ? boolean + 'num_pcie_ports' ? long with SELF >= 0 && SELF <= 28 'virt_type' : choice('kvm', 'lxc', 'qemu', 'uml', 'parallels', 'xen') }; @@ -153,7 +180,8 @@ type openstack_nova_pci = { # Unfortunately it is not possible to use openstack_nova_pci_alias as a dict is not rendered # properly by metaconfig tiny module 'alias' ? string - 'passthrough_whitelist' ? string + 'device_spec' ? string + 'report_in_placement' ? boolean }; @documentation { @@ -205,20 +233,27 @@ type openstack_nova_wsgi = { }; @documentation { - parameters for nova configuration [vnc] section + parameters for nova configuration [vnc] section for compute } -type openstack_nova_vnc = { +type openstack_nova_compute_vnc = { 'enabled' : boolean = true 'novncproxy_base_url' ? type_hostURI 'server_listen' ? string with is_ipv4(SELF) || is_hostname(SELF) 'server_proxyclient_address' ? string with is_ipv4(SELF) || is_hostname(SELF) }; +@documentation { + parameters for nova configuration [vnc] section for server +} +type openstack_nova_server_vnc = { + 'novncproxy_host' : type_hostname + 'novncproxy_port' : type_port +}; + @documentation { list of nova configuration sections common to server and compute } type openstack_nova_common_config = { - 'DEFAULT' : openstack_nova_defaults 'glance' ? openstack_nova_glance 'keystone_authtoken' : openstack_keystone_authtoken 'neutron' ? openstack_nova_neutron @@ -228,7 +263,6 @@ type openstack_nova_common_config = { 'placement' ? openstack_nova_placement 'service_user' : openstack_nova_service_user 'upgrade_levels' ? openstack_nova_upgrade_levels - 'vnc' ? openstack_nova_vnc }; @documentation { @@ -236,12 +270,14 @@ type openstack_nova_common_config = { } type openstack_nova_server_config = { include openstack_nova_common_config + 'DEFAULT' : openstack_nova_defaults 'api' : openstack_nova_api 'api_database' : openstack_nova_api_database 'database' : openstack_database 'filter_scheduler' : openstack_nova_filter_scheduler 'pci' ? openstack_nova_pci - 'wsgi' : openstack_nova_wsgi + 'vnc' ? openstack_nova_server_vnc + 'wsgi' ? openstack_nova_wsgi }; @documentation { @@ -249,8 +285,22 @@ type openstack_nova_server_config = { } type openstack_nova_compute_config = { include openstack_nova_common_config + 'DEFAULT' : openstack_nova_compute_defaults 'cinder' ? openstack_nova_cinder 'libvirt' ? openstack_nova_libvirt 'notifications' ? openstack_nova_notifications 'pci' ? openstack_nova_pci + 'vnc' ? openstack_nova_compute_vnc + 'workarounds' ? openstack_nova_compute_workarounds }; + + +@documentation { + list of libvirt proxyd configuration options +} +type openstack_nova_libvirt_proxyd = { + 'listen_tls' ? boolean + 'listen_tcp' ? boolean + 'auth_tcp' ? choice('none', 'polkit', 'sasl') +}; + diff --git a/types/openstack/octavia.pan b/types/openstack/octavia.pan index 0e9e7ec..4f65a04 100644 --- a/types/openstack/octavia.pan +++ b/types/openstack/octavia.pan @@ -76,6 +76,7 @@ type openstack_octavia_config = { 'keystone_authtoken' : openstack_keystone_authtoken 'oslo_messaging' : openstack_oslo_messaging 'oslo_messaging_notifications' : openstack_oslo_messaging_notifications + 'oslo_messaging_rabbit' ? openstack_oslo_messaging_rabbit 'service_auth' : openstack_keystone_authtoken }; diff --git a/types/openstack/placement.pan b/types/openstack/placement.pan index 9b0c89c..3574098 100644 --- a/types/openstack/placement.pan +++ b/types/openstack/placement.pan @@ -30,6 +30,7 @@ type openstack_placement_config = { 'api' : openstack_placement_api 'keystone_authtoken' : openstack_keystone_authtoken 'oslo_messaging_notifications' ? openstack_oslo_messaging_notifications + 'oslo_messaging_rabbit' ? openstack_oslo_messaging_rabbit 'placement' ? openstack_placement_placement 'placement_database' : openstack_database };