heat_template_version: wallaby description: > OpenStack containerized swift proxy service parameters: ContainerSwiftProxyImage: description: image type: string ContainerSwiftConfigImage: description: The container image to use for the swift config_volume type: string 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. This mapping overrides those in ServiceNetMapDefaults. 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 RpcUseSSL: default: false description: > Messaging client subscriber parameter to specify an SSL connection to the messaging host. type: string 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. 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} EnableInternalTLS: {get_param: EnableInternalTLS} outputs: role_data: description: Role data for the swift proxy. value: service_name: swift_proxy firewall_rules: '122 swift proxy': dport: - 8080 - 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, KeystoneInternal, 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::staticweb::url_base: {get_param: [EndpointMap, SwiftPublic, uri_no_suffix]} tripleo::profile::base::swift::proxy::ceilometer_messaging_use_ssl: {get_param: RpcUseSSL} 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: - 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_param: 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" # TODO(emilien) remove optional flag once we get a promotion # https://launchpad.net/bugs/1884115 optional: true 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_param: 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-proxy when: - step|int == 1 - swift_logconfig is not defined - swift_rsyslog_config is not defined block: - name: Check if rsyslog exists systemd: name: rsyslog register: swift_rsyslog_config - block: - 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 - name: Restart rsyslogd service after logging conf change service: name: rsyslog state: restarted when: - swift_logconfig is changed when: - swift_rsyslog_config is defined - swift_rsyslog_config.status is defined - swift_rsyslog_config.status.ActiveState == 'active' - 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]