heat_template_version: rocky

description: >
  OpenStack containerized Cinder Volume service

parameters:
  ContainerCinderVolumeImage:
    description: image
    type: string
  ContainerCinderConfigImage:
    description: The container image to use for the cinder config_volume
    type: string
  DockerCinderVolumeUlimit:
    default: ['nofile=131072']
    description: ulimit for Cinder Volume Container
    type: comma_delimited_list
  CinderVolumeLoggingSource:
    type: json
    default:
      tag: openstack.cinder.volume
      file: /var/log/containers/cinder/cinder-volume.log
  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
  DefaultPasswords:
    default: {}
    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
  CephClientUserName:
    default: openstack
    type: string
  CephClusterName:
    type: string
    default: ceph
    description: The Ceph cluster name.
    constraints:
    - allowed_pattern: "[a-zA-Z0-9]+"
      description: >
        The Ceph cluster name must be at least 1 character and contain only
        letters and numbers.
  CinderVolumeCluster:
    default: ''
    description: >
      The cluster name used for deploying the cinder-volume service in an
      active-active (A/A) configuration. This configuration requires the
      Cinder backend drivers support A/A, and the cinder-volume service not
      be managed by pacemaker. If these criteria are not met then the cluster
      name must be left blank.
    type: string
  CinderEnableNfsBackend:
    default: false
    description: Whether to enable or not the NFS backend for Cinder
    type: boolean
  CinderEnableIscsiBackend:
    default: true
    description: Whether to enable or not the Iscsi backend for Cinder
    type: boolean
  CinderEnableRbdBackend:
    default: false
    description: Whether to enable or not the Rbd backend for Cinder
    type: boolean
  CinderISCSIAvailabilityZone:
    default: ''
    description: >
      The availability zone of the Iscsi Cinder backend.
      When set, it overrides the default CinderStorageAvailabilityZone.
    type: string
  CinderISCSIHelper:
    default: lioadm
    description: The iSCSI helper to use with cinder.
    type: string
  CinderISCSIProtocol:
    default: iscsi
    description: Whether to use TCP ('iscsi') or iSER RDMA ('iser') for iSCSI
    type: string
  CinderLVMLoopDeviceSize:
    default: 10280
    description: The size of the loopback file used by the cinder LVM driver.
    type: number
  CinderNfsAvailabilityZone:
    default: ''
    description: >
      The availability zone of the NFS Cinder backend.
      When set, it overrides the default CinderStorageAvailabilityZone.
    type: string
  CinderNfsMountOptions:
    default: ''
    description: >
      Mount options for NFS mounts used by Cinder NFS backend. Effective
      when CinderEnableNfsBackend is true.
    type: string
  CinderNfsServers:
    default: ''
    description: >
      NFS servers used by Cinder NFS backend. Effective when
      CinderEnableNfsBackend is true.
    type: comma_delimited_list
  CinderNfsSnapshotSupport:
    default: true
    description: >
      Whether to enable support for snapshots in the NFS driver. Effective
      when CinderEnableNfsBackend is true.
    type: boolean
  CinderNasSecureFileOperations:
    default: false
    description: >
      Controls whether security enhanced NFS file operations are enabled.
      Valid values are 'auto', 'true' or 'false'. Effective when
      CinderEnableNfsBackend is true.
    type: string
  CinderNasSecureFilePermissions:
    default: false
    description: >
      Controls whether security enhanced NFS file permissions are enabled.
      Valid values are 'auto', 'true' or 'false'. Effective when
      CinderEnableNfsBackend is true.
    type: string
  CinderRbdAvailabilityZone:
    default: ''
    description: >
      The availability zone of the RBD Cinder backend.
      When set, it overrides the default CinderStorageAvailabilityZone.
    type: string
  CinderRbdPoolName:
    default: volumes
    type: string
  CinderRbdExtraPools:
    default: []
    description: >
      List of extra Ceph pools for use with RBD backends for Cinder. An
      extra Cinder RBD backend driver is created for each pool in the
      list. This is in addition to the standard RBD backend driver
      associated with the CinderRbdPoolName.
    type: comma_delimited_list

  CinderRbdFlattenVolumeFromSnapshot:
    default: false
    description: >
      Whether RBD volumes created from a snapshot should be flattened
      in order to remove a dependency on the snapshot.
    type: boolean
  CephClusterFSID:
    type: string
    description: The Ceph cluster FSID. Must be a UUID.
  MonitoringSubscriptionCinderVolume:
    default: 'overcloud-cinder-volume'
    type: string
  CinderEtcdLocalConnect:
    default: false
    type: boolean
    description: When running Cinder A/A, whether to connect to Etcd
      via the local IP for the Etcd network. If set to true, the ip
      on the local node will be used. If set to false, the VIP on the Etcd
      network will be used instead. Defaults to false.

resources:

  ContainersCommon:
    type: ../containers-common.yaml

  MySQLClient:
    type: ../database/mysql-client.yaml

  CinderBase:
    type: ./cinder-base.yaml
    properties:
      EndpointMap: {get_param: EndpointMap}
      ServiceData: {get_param: ServiceData}
      ServiceNetMap: {get_param: ServiceNetMap}
      DefaultPasswords: {get_param: DefaultPasswords}
      RoleName: {get_param: RoleName}
      RoleParameters: {get_param: RoleParameters}

  CinderCommon:
    type: ./cinder-common-container-puppet.yaml

outputs:
  role_data:
    description: Role data for the Cinder Volume role.
    value:
      service_name: cinder_volume
      firewall_rules:
        '120 iscsi initiator':
          dport: 3260
      monitoring_subscription: {get_param: MonitoringSubscriptionCinderVolume}
      config_settings:
        map_merge:
          - get_attr: [CinderBase, role_data, config_settings]
          - tripleo::profile::base::lvm::enable_udev: false
          - tripleo::profile::base::cinder::volume::cinder_enable_iscsi_backend: {get_param: CinderEnableIscsiBackend}
            tripleo::profile::base::cinder::volume::cinder_enable_nfs_backend: {get_param: CinderEnableNfsBackend}
            tripleo::profile::base::cinder::volume::cinder_enable_rbd_backend: {get_param: CinderEnableRbdBackend}
            tripleo::profile::base::cinder::volume::cinder_volume_cluster: {get_param: CinderVolumeCluster}
            tripleo::profile::base::cinder::volume::nfs::cinder_nfs_mount_options: {get_param: CinderNfsMountOptions}
            tripleo::profile::base::cinder::volume::nfs::cinder_nfs_servers: {get_param: CinderNfsServers}
            tripleo::profile::base::cinder::volume::nfs::cinder_nfs_snapshot_support: {get_param: CinderNfsSnapshotSupport}
            tripleo::profile::base::cinder::volume::nfs::cinder_nas_secure_file_operations: {get_param: CinderNasSecureFileOperations}
            tripleo::profile::base::cinder::volume::nfs::cinder_nas_secure_file_permissions: {get_param: CinderNasSecureFilePermissions}
            tripleo::profile::base::cinder::volume::iscsi::cinder_lvm_loop_device_size: {get_param: CinderLVMLoopDeviceSize}
            tripleo::profile::base::cinder::volume::iscsi::cinder_iscsi_helper: {get_param: CinderISCSIHelper}
            tripleo::profile::base::cinder::volume::iscsi::cinder_iscsi_protocol: {get_param: CinderISCSIProtocol}
            tripleo::profile::base::cinder::volume::rbd::cinder_rbd_ceph_conf:
              list_join:
              - ''
              - - '/etc/ceph/'
                - {get_param: CephClusterName}
                - '.conf'
            tripleo::profile::base::cinder::volume::rbd::cinder_rbd_pool_name: {get_param: CinderRbdPoolName}
            tripleo::profile::base::cinder::volume::rbd::cinder_rbd_extra_pools: {get_param: CinderRbdExtraPools}
            tripleo::profile::base::cinder::volume::rbd::cinder_rbd_secret_uuid: {get_param: CephClusterFSID}
            tripleo::profile::base::cinder::volume::rbd::cinder_rbd_user_name: {get_param: CephClientUserName}
            tripleo::profile::base::cinder::volume::rbd::cinder_rbd_flatten_volume_from_snapshot: {get_param: CinderRbdFlattenVolumeFromSnapshot}
            # 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::cinder::volume::iscsi::cinder_iscsi_address:
              str_replace:
                template:
                  "%{hiera('$NETWORK')}"
                params:
                  $NETWORK: {get_param: [ServiceNetMap, CinderIscsiNetwork]}
          -
            if:
            - {equals : [{get_param: CinderISCSIAvailabilityZone}, '']}
            - {}
            - tripleo::profile::base::cinder::volume::iscsi::backend_availability_zone: {get_param: CinderISCSIAvailabilityZone}
          -
            if:
            - {equals : [{get_param: CinderNfsAvailabilityZone}, '']}
            - {}
            - tripleo::profile::base::cinder::volume::nfs::backend_availability_zone: {get_param: CinderNfsAvailabilityZone}
          -
            if:
            - {equals : [{get_param: CinderRbdAvailabilityZone}, '']}
            - {}
            - tripleo::profile::base::cinder::volume::rbd::backend_availability_zone: {get_param: CinderRbdAvailabilityZone}
          -
            if:
            - {equals : [{get_param: CinderEtcdLocalConnect}, true]}
            - tripleo::profile::base::cinder::volume::etcd_host:
                str_replace:
                  template:
                    "%{hiera('$NETWORK')}"
                  params:
                    $NETWORK: {get_param: [ServiceNetMap, EtcdNetwork]}
            - {}
      service_config_settings:
        map_merge:
          - get_attr: [CinderBase, role_data, service_config_settings]
          - rsyslog:
              tripleo_logging_sources_cinder_volume:
                - {get_param: CinderVolumeLoggingSource}
      # BEGIN DOCKER SETTINGS
      puppet_config:
        config_volume: cinder
        puppet_tags: cinder_config,file,concat,file_line
        step_config:
          list_join:
            - "\n"
            - - "include ::tripleo::profile::base::lvm"
              - "include ::tripleo::profile::base::cinder::volume"
              - get_attr: [MySQLClient, role_data, step_config]
        config_image: {get_param: ContainerCinderConfigImage}
      kolla_config:
        /var/lib/kolla/config_files/cinder_volume.json:
          command: /usr/bin/cinder-volume --config-file /usr/share/cinder/cinder-dist.conf --config-file /etc/cinder/cinder.conf
          config_files:
            - source: "/var/lib/kolla/config_files/src/*"
              dest: "/"
              merge: true
              preserve_properties: true
            - source: "/var/lib/kolla/config_files/src-ceph/"
              dest: "/etc/ceph/"
              merge: true
              preserve_properties: true
            - source: "/var/lib/kolla/config_files/src-iscsid/*"
              dest: "/etc/iscsi/"
              merge: true
              preserve_properties: true
          permissions:
            - path: /var/log/cinder
              owner: cinder:cinder
              recurse: true
            - path:
                str_replace:
                  template: /etc/ceph/CLUSTER.client.USER.keyring
                  params:
                    CLUSTER: {get_param: CephClusterName}
                    USER: {get_param: CephClientUserName}
              owner: cinder:cinder
              perm: '0600'
      docker_config:
        step_3:
          cinder_volume_init_logs:
            start_order: 0
            image: &cinder_volume_image {get_param: ContainerCinderVolumeImage}
            net: none
            privileged: false
            user: root
            volumes:
              - /var/log/containers/cinder:/var/log/cinder:z
            command: ['/bin/bash', '-c', 'chown -R cinder:cinder /var/log/cinder']
        step_4:
          cinder_volume:
            image: *cinder_volume_image
            ulimit: {get_param: DockerCinderVolumeUlimit}
            ipc: host
            net: host
            privileged: true
            restart: always
            healthcheck: {get_attr: [ContainersCommon, healthcheck_rpc_port]}
            volumes: {get_attr: [CinderCommon, cinder_volume_volumes]}
            environment: {get_attr: [CinderCommon, cinder_volume_environment]}
      host_prep_tasks: {get_attr: [CinderCommon, cinder_volume_host_prep_tasks]}
      fast_forward_upgrade_tasks:
        - when:
            - step|int == 0
            - release == 'ocata'
          block:
            - name: Check if cinder_volume is deployed
              command: systemctl is-enabled --quiet openstack-cinder-volume
              ignore_errors: True
              register: cinder_volume_enabled_result
            - name: Set fact cinder_volume_enabled
              set_fact:
                cinder_volume_enabled: "{{ cinder_volume_enabled_result.rc == 0 }}"
        - name: Stop openstack-cinder-volume
          service: name=openstack-cinder-volume state=stopped enabled=no
          when:
            - step|int == 1
            - release == 'ocata'
            - cinder_volume_enabled|bool
