heat_template_version: wallaby description: > OpenStack containerized swift proxy service parameters: ContainerSwiftProxyImage: description: image type: string tags: - role_specific ContainerSwiftConfigImage: description: The container image to use for the swift config_volume type: string tags: - role_specific EndpointMap: default: {} description: Mapping of service endpoint -> protocol. Typically set via parameter_defaults in the resource registry. type: json ServiceData: default: {} description: Dictionary packing service data type: json ServiceNetMap: default: {} description: Mapping of service_name -> network name. Typically set via parameter_defaults in the resource registry. Use parameter_merge_strategies to merge it with the defaults. type: json RoleName: default: '' description: Role name on which the service is applied type: string RoleParameters: default: {} description: Parameters specific to the role type: json SwiftEncryptionEnabled: description: Set to True to enable data-at-rest encryption in Swift default: false type: boolean DeployIdentifier: default: '' type: string description: > Setting this to a unique value will re-run any deployment tasks which perform configuration on a Heat stack-update. SwiftPassword: description: The password for the swift service account type: string hidden: true SwiftProxyNodeTimeout: default: 60 description: Timeout for requests going from swift-proxy to swift a/c/o services. type: number SwiftProxyRecoverableNodeTimeout: default: 30 description: Timeout for GET/HEAD requests going from swift-proxy to swift a/c/o services. type: number SwiftWorkers: default: 0 description: Number of workers for Swift service. type: string KeystoneRegion: type: string default: 'regionOne' description: Keystone region for endpoint MonitoringSubscriptionSwiftProxy: default: 'overcloud-swift-proxy' type: string SwiftCeilometerPipelineEnabled: description: Set to False to disable the swift proxy ceilometer pipeline. default: false type: boolean SwiftCeilometerIgnoreProjects: default: ['service'] description: Comma-seperated list of project names to ignore. type: comma_delimited_list EnableInternalTLS: type: boolean default: false MemcachedTLS: default: false description: Set to True to enable TLS on Memcached service. Because not all services support Memcached TLS, during the migration period, Memcached will listen on 2 ports - on the port set with MemcachedPort parameter (above) and on 11211, without TLS. type: boolean SwiftCorsAllowedOrigin: type: string default: '' description: Indicate whether this resource may be shared with the domain received in the request "origin" header. EnforceSecureRbac: type: boolean default: false description: >- Setting this option to True will configure each OpenStack service to enforce Secure RBAC by setting `[oslo_policy] enforce_new_defaults` and `[oslo_policy] enforce_scope` to True. This introduces a consistent set of RBAC personas across OpenStack services that include support for system and project scope, as well as keystone's default roles, admin, member, and reader. Do not enable this functionality until all services in your deployment actually support secure RBAC. conditions: internal_tls_enabled: {equals: [{get_param: EnableInternalTLS}, true]} swift_encryption_enabled: {equals : [{get_param: SwiftEncryptionEnabled}, true]} ceilometer_pipeline_enabled: {equals : [{get_param: SwiftCeilometerPipelineEnabled}, true]} use_tls_proxy: {equals : [{get_param: EnableInternalTLS}, true]} cors_allowed_origin_unset: {equals : [{get_param: SwiftCorsAllowedOrigin}, '']} swift_workers_zero: {equals : [{get_param: SwiftWorkers}, '0']} resources: ContainersCommon: type: ../containers-common.yaml SwiftBase: type: ./swift-base.yaml properties: EndpointMap: {get_param: EndpointMap} ServiceData: {get_param: ServiceData} ServiceNetMap: {get_param: ServiceNetMap} RoleName: {get_param: RoleName} RoleParameters: {get_param: RoleParameters} TLSProxyBase: type: OS::TripleO::Services::TLSProxyBase properties: ServiceData: {get_param: ServiceData} ServiceNetMap: {get_param: ServiceNetMap} EndpointMap: {get_param: EndpointMap} RoleName: {get_param: RoleName} RoleParameters: {get_param: RoleParameters} EnableInternalTLS: {get_param: EnableInternalTLS} RoleParametersValue: type: OS::Heat::Value properties: type: json value: map_replace: - map_replace: - ContainerSwiftProxyImage: ContainerSwiftProxyImage ContainerSwiftConfigImage: ContainerSwiftConfigImage - values: {get_param: [RoleParameters]} - values: ContainerSwiftProxyImage: {get_param: ContainerSwiftProxyImage} ContainerSwiftConfigImage: {get_param: ContainerSwiftConfigImage} outputs: role_data: description: Role data for the swift proxy. value: service_name: swift_proxy firewall_rules: '122 swift proxy': dport: - 8080 firewall_frontend_rules: '100 swift_proxy_server_haproxy_frontend': dport: - 8080 firewall_ssl_frontend_rules: '100 swift_proxy_server_haproxy_frontend_ssl': dport: - 13808 keystone_resources: swift: endpoints: public: {get_param: [EndpointMap, SwiftPublic, uri]} internal: {get_param: [EndpointMap, SwiftInternal, uri]} admin: {get_param: [EndpointMap, SwiftAdmin, uri]} users: swift: password: {get_param: SwiftPassword} region: {get_param: KeystoneRegion} service: 'object-store' roles: - swiftoperator - ResellerAdmin monitoring_subscription: {get_param: MonitoringSubscriptionSwiftProxy} config_settings: map_merge: - get_attr: [SwiftBase, role_data, config_settings] - get_attr: [TLSProxyBase, role_data, config_settings] - if: - cors_allowed_origin_unset - {} - swift::proxy::cors_allow_origin: {get_param: SwiftCorsAllowedOrigin} - swift::proxy::authtoken::www_authenticate_uri: {get_param: [EndpointMap, KeystonePublic, uri_no_suffix]} swift::proxy::authtoken::auth_url: {get_param: [EndpointMap, KeystoneInternal, uri_no_suffix]} swift::proxy::authtoken::password: {get_param: SwiftPassword} swift::proxy::authtoken::project_name: 'service' swift::proxy::authtoken::region_name: {get_param: KeystoneRegion} swift::proxy::authtoken::interface: 'internal' swift::proxy::s3token::auth_uri: {get_param: [EndpointMap, KeystoneV3Internal, uri]} swift::proxy::node_timeout: {get_param: SwiftProxyNodeTimeout} swift::proxy::recoverable_node_timeout: {get_param: SwiftProxyRecoverableNodeTimeout} - if: - swift_workers_zero - {} - swift::proxy::workers: {get_param: SwiftWorkers} - if: - ceilometer_pipeline_enabled - swift::proxy::ceilometer::auth_url: {get_param: [EndpointMap, KeystoneInternal, uri_no_suffix]} swift::proxy::ceilometer::password: {get_param: SwiftPassword} swift::proxy::ceilometer::project_name: 'service' swift::proxy::ceilometer::region_name: {get_param: KeystoneRegion} swift::proxy::ceilometer::ignore_projects: {get_param: SwiftCeilometerIgnoreProjects} swift::proxy::ceilometer::nonblocking_notify: true swift::proxy::ceilometer::rabbit_heartbeat_in_pthread: false - {} - swift::proxy::staticweb::url_base: {get_param: [EndpointMap, SwiftPublic, uri_no_suffix]} tripleo::profile::base::swift::proxy::ceilometer_enabled: {get_param: SwiftCeilometerPipelineEnabled} swift::proxy::keystone::operator_roles: - admin - swiftoperator - ResellerAdmin swift::proxy::versioned_writes::allow_versioned_writes: true - if: - {get_param: EnforceSecureRbac} - swift::proxy::keystone::project_reader_roles: ['SwiftProjectReader'] - swift::proxy::keystone::system_reader_roles: ['SwiftSystemReader'] - if: - swift_encryption_enabled - swift::keymaster::key_id: 'test_id' swift::keymaster::username: 'swift' swift::keymaster::password: {get_param: SwiftPassword} swift::keymaster::project_name: 'service' swift::keymaster::project_domain_id: 'default' swift::keymaster::user_domain_id: 'default' swift::keymaster::auth_endpoint: {get_param: [EndpointMap, KeystoneInternal, uri]} - {} - swift::proxy::pipeline: list_concat: - - 'catch_errors' - 'gatekeeper' - 'healthcheck' - 'proxy-logging' - 'cache' - 'listing_formats' - 'ratelimit' - 'bulk' - 'tempurl' - 'formpost' - 'authtoken' - 's3api' - 's3token' - 'keystone' - 'staticweb' - 'copy' - 'container_quotas' - 'account_quotas' - 'slo' - 'dlo' - 'versioned_writes' - if: - ceilometer_pipeline_enabled - - 'ceilometer' - [] - if: - swift_encryption_enabled - - 'kms_keymaster' - 'encryption' - [] - - 'proxy-logging' - 'proxy-server' swift::proxy::account_autocreate: true # NOTE: bind IP is found in hiera replacing the network name with the # local node IP for the given network; replacement examples # (eg. for internal_api): # internal_api -> IP # internal_api_uri -> [IP] # internal_api_subnet - > IP/CIDR tripleo::profile::base::swift::proxy::tls_proxy_bind_ip: str_replace: template: "%{hiera('$NETWORK')}" params: $NETWORK: {get_param: [ServiceNetMap, SwiftProxyNetwork]} tripleo::profile::base::swift::proxy::tls_proxy_fqdn: str_replace: template: "%{hiera('fqdn_$NETWORK')}" params: $NETWORK: {get_param: [ServiceNetMap, SwiftProxyNetwork]} tripleo::profile::base::swift::proxy::tls_proxy_port: get_param: [EndpointMap, SwiftInternal, port] swift::proxy::port: {get_param: [EndpointMap, SwiftInternal, port]} swift::proxy::proxy_local_net_ip: if: - use_tls_proxy - "%{hiera('localhost_address')}" - str_replace: template: "%{hiera('$NETWORK')}" params: $NETWORK: {get_param: [ServiceNetMap, SwiftProxyNetwork]} swift::proxy::cache::tls_enabled: {get_param: MemcachedTLS} # BEGIN DOCKER SETTINGS puppet_config: config_volume: swift puppet_tags: swift_config,swift_proxy_config,swift_keymaster_config step_config: | include tripleo::profile::base::swift::proxy config_image: {get_attr: [RoleParametersValue, value, ContainerSwiftConfigImage]} kolla_config: /var/lib/kolla/config_files/swift_proxy.json: command: /usr/bin/swift-proxy-server /etc/swift/proxy-server.conf config_files: - source: "/var/lib/kolla/config_files/src/*" dest: "/" merge: true preserve_properties: true /var/lib/kolla/config_files/swift_proxy_tls_proxy.json: command: /usr/sbin/httpd -DFOREGROUND config_files: - source: "/var/lib/kolla/config_files/src/etc/httpd/conf.d" dest: "/etc/httpd/conf.d" merge: false preserve_properties: true - source: "/var/lib/kolla/config_files/src/etc/httpd/conf.modules.d" dest: "/etc/httpd/conf.modules.d" merge: false preserve_properties: true - source: "/var/lib/kolla/config_files/src/*" dest: "/" merge: true preserve_properties: true container_config_scripts: create_swift_secret.sh: mode: "0700" content: | #!/bin/bash export OS_PROJECT_DOMAIN_ID=$(crudini --get /etc/swift/keymaster.conf kms_keymaster project_domain_id) export OS_USER_DOMAIN_ID=$(crudini --get /etc/swift/keymaster.conf kms_keymaster user_domain_id) export OS_PROJECT_NAME=$(crudini --get /etc/swift/keymaster.conf kms_keymaster project_name) export OS_USERNAME=$(crudini --get /etc/swift/keymaster.conf kms_keymaster username) export OS_PASSWORD=$(crudini --get /etc/swift/keymaster.conf kms_keymaster password) export OS_AUTH_URL=$(crudini --get /etc/swift/keymaster.conf kms_keymaster auth_endpoint) export OS_AUTH_TYPE=password export OS_IDENTITY_API_VERSION=3 echo "Check if secret already exists" secret_href=$(openstack secret list --name swift_root_secret_uuid) rc=$? if [[ $rc != 0 ]]; then echo "Failed to check secrets, check if Barbican in enabled and responding properly" exit $rc; fi if [ -z "$secret_href" ]; then echo "Create new secret" order_href=$(openstack secret order create --name swift_root_secret_uuid --payload-content-type="application/octet-stream" --algorithm aes --bit-length 256 --mode ctr key -f value -c "Order href") fi set_swift_keymaster_key_id.sh: mode: "0700" content: | #!/bin/bash export OS_PROJECT_DOMAIN_ID=$(crudini --get /etc/swift/keymaster.conf kms_keymaster project_domain_id) export OS_USER_DOMAIN_ID=$(crudini --get /etc/swift/keymaster.conf kms_keymaster user_domain_id) export OS_PROJECT_NAME=$(crudini --get /etc/swift/keymaster.conf kms_keymaster project_name) export OS_USERNAME=$(crudini --get /etc/swift/keymaster.conf kms_keymaster username) export OS_PASSWORD=$(crudini --get /etc/swift/keymaster.conf kms_keymaster password) export OS_AUTH_URL=$(crudini --get /etc/swift/keymaster.conf kms_keymaster auth_endpoint) export OS_AUTH_TYPE=password export OS_IDENTITY_API_VERSION=3 echo "retrieve key_id" loop_wait=2 for i in {0..5}; do #TODO update uuid from mistral here too secret_href=$(openstack secret list --name swift_root_secret_uuid) if [ "$secret_href" ]; then echo "set key_id in keymaster.conf" secret_href=$(openstack secret list --name swift_root_secret_uuid -f value -c "Secret href") crudini --set /etc/swift/keymaster.conf kms_keymaster key_id ${secret_href##*/} exit 0 else echo "no key, wait for $loop_wait and check again" sleep $loop_wait ((loop_wait++)) fi done echo "Failed to set secret in keymaster.conf, check if Barbican is enabled and responding properly" exit 1 docker_config: step_4: map_merge: - if: - swift_encryption_enabled - create_swift_secret: # NOTE: Barbican should be started before creating secrets start_order: 0 image: &swift_proxy_image {get_attr: [RoleParametersValue, value, ContainerSwiftProxyImage]} net: host detach: false volumes: list_concat: - {get_attr: [ContainersCommon, volumes]} - - /var/lib/config-data/puppet-generated/swift/etc/swift:/etc/swift:ro - /var/lib/container-config-scripts/create_swift_secret.sh:/create_swift_secret.sh:ro user: root command: "/usr/bin/bootstrap_host_exec swift_proxy /create_swift_secret.sh" - {} - if: - swift_encryption_enabled - set_swift_secret: start_order: 1 image: *swift_proxy_image net: host detach: false volumes: list_concat: - {get_attr: [ContainersCommon, volumes]} - - /var/lib/config-data/puppet-generated/swift/etc/swift:/etc/swift:rw,z - /var/lib/container-config-scripts/set_swift_keymaster_key_id.sh:/set_swift_keymaster_key_id.sh:ro user: root command: "/set_swift_keymaster_key_id.sh" environment: # NOTE: this should force this container to re-run on each # update (scale-out, etc.) TRIPLEO_DEPLOY_IDENTIFIER: {get_param: DeployIdentifier} - {} - swift_proxy: image: *swift_proxy_image start_order: 2 net: host user: swift restart: always healthcheck: test: /openstack/healthcheck volumes: list_concat: - {get_attr: [ContainersCommon, volumes]} - - /var/lib/kolla/config_files/swift_proxy.json:/var/lib/kolla/config_files/config.json:ro - /var/lib/config-data/puppet-generated/swift:/var/lib/kolla/config_files/src:ro - /srv/node:/srv/node - /dev:/dev - /var/log/containers/swift:/var/log/swift:z environment: KOLLA_CONFIG_STRATEGY: COPY_ALWAYS - if: - internal_tls_enabled - swift_proxy_tls_proxy: start_order: 3 image: *swift_proxy_image net: host user: root restart: always volumes: list_concat: - {get_attr: [ContainersCommon, volumes]} - - /var/lib/kolla/config_files/swift_proxy_tls_proxy.json:/var/lib/kolla/config_files/config.json:ro - /var/lib/config-data/puppet-generated/swift:/var/lib/kolla/config_files/src:ro - /etc/pki/tls/certs/httpd:/etc/pki/tls/certs/httpd:ro - /etc/pki/tls/private/httpd:/etc/pki/tls/private/httpd:ro environment: KOLLA_CONFIG_STRATEGY: COPY_ALWAYS - {} host_prep_tasks: - name: create persistent directories file: path: "{{ item.path }}" state: directory setype: "{{ item.setype }}" mode: "{{ item.mode|default(omit) }}" with_items: - { 'path': /srv/node, 'setype': container_file_t } - { 'path': /var/log/swift, 'setype': container_file_t } - { 'path': /var/log/containers/swift, 'setype': container_file_t, 'mode': '0750' } deploy_steps_tasks: - name: Configure rsyslog for swift when: - step|int == 1 block: - name: Check if rsyslog exists shell: systemctl is-active rsyslog register: swift_rsyslog_config - name: Forward logging to swift.log file copy: content: | # Fix for https://bugs.launchpad.net/tripleo/+bug/1776180 local2.* /var/log/containers/swift/swift.log & stop dest: /etc/rsyslog.d/openstack-swift.conf register: swift_logconfig when: - swift_rsyslog_config is defined - swift_rsyslog_config.rc == 0 - name: Restart rsyslogd service after logging conf change service: name: rsyslog state: restarted when: - swift_logconfig is defined - swift_logconfig is changed - name: Run kolla_set_configs to copy ring files when: step|int == 5 shell: "{{ container_cli }} exec -u root {{ item }} /usr/local/bin/kolla_set_configs " become: true register: kolla_set_configs_result failed_when: - kolla_set_configs_result.rc is defined # do not fail in dry run mode - kolla_set_configs_result.rc not in [0, 125] # ignore containers that are not running with_items: - swift_proxy update_tasks: - name: Check swift containers log folder/symlink exists stat: path: /var/log/containers/swift register: swift_log_link - name: Delete if symlink file: path: /var/log/containers/swift state: absent when: swift_log_link.stat.islnk is defined and swift_log_link.stat.islnk metadata_settings: get_attr: [TLSProxyBase, role_data, metadata_settings]