diff --git a/controllerconfig/controllerconfig/scripts/controller_config b/controllerconfig/controllerconfig/scripts/controller_config index 33739c793b..89857f6539 100755 --- a/controllerconfig/controllerconfig/scripts/controller_config +++ b/controllerconfig/controllerconfig/scripts/controller_config @@ -262,6 +262,43 @@ start() fi fi + if [ -e $CONFIG_DIR/registry-cert-pkcs1.key ] + then + cp $CONFIG_DIR/registry-cert-pkcs1.key /etc/ssl/private/registry-cert-pkcs1.key + if [ $? -ne 0 ] + then + fatal_error "Unable to copy $CONFIG_DIR/registry-cert-pkcs1.key" + fi + fi + + if [ -e $CONFIG_DIR/registry-cert.key ] + then + cp $CONFIG_DIR/registry-cert.key /etc/ssl/private/registry-cert.key + if [ $? -ne 0 ] + then + fatal_error "Unable to copy $CONFIG_DIR/registry-cert.key" + fi + fi + + if [ -e $CONFIG_DIR/registry-cert.crt ] + then + cp $CONFIG_DIR/registry-cert.crt /etc/ssl/private/registry-cert.crt + if [ $? -ne 0 ] + then + fatal_error "Unable to copy $CONFIG_DIR/registry-cert.crt to certificates dir" + fi + + # this is management network for now + REGISTRY_IP=$(get_ip controller) + mkdir -p /etc/docker/certs.d/$REGISTRY_IP:9001/ + chmod 700 /etc/docker/certs.d/$REGISTRY_IP:9001/ + cp $CONFIG_DIR/registry-cert.crt /etc/docker/certs.d/$REGISTRY_IP:9001/registry-cert.crt + if [ $? -ne 0 ] + then + fatal_error "Unable to copy $CONFIG_DIR/registry-cert.crt to docker dir" + fi + fi + if [ -e $CONFIG_DIR/iptables.rules ] then cp $CONFIG_DIR/iptables.rules /etc/platform/iptables.rules diff --git a/puppet-manifests/src/modules/platform/files/registry-token-server b/puppet-manifests/src/modules/platform/files/registry-token-server new file mode 100644 index 0000000000..5cfe82a881 --- /dev/null +++ b/puppet-manifests/src/modules/platform/files/registry-token-server @@ -0,0 +1,90 @@ +#!/bin/bash +# +# SPDX-License-Identifier: Apache-2.0 +# +# Startup script for registry-token-server +# + + +DESC="Docker Registry Token Server" +SERVICE="registry-token-server.service" +PIDFILE="/var/run/registry-token-server.pid" + + +status() +{ + if [ "`systemctl is-active registry-token-server.service`" = "active" ]; then + RETVAL=0 + echo "$DESC is running" + return + else + echo "$DESC is Not running" + RETVAL=1 + fi +} + +start() +{ + if [ -e $PIDFILE ]; then + PIDDIR=/proc/$(cat $PIDFILE) + if [ -d $PIDDIR ]; then + echo "$DESC already running." + return + else + echo "Removing stale PID file $PIDFILE" + rm -f $PIDFILE + fi + fi + + echo "Starting $SERVICE..." + + systemctl start $SERVICE + + if [ $? -eq 0 ]; then + echo "Started $SERVICE successfully" + RETVAL=0 + else + echo "$SERVICE failed!" + RETVAL=1 + fi + +} + +stop() +{ + echo -n "Stopping $SERVICE..." + systemctl stop $SERVICE + if [ $? -eq 0 ]; then + echo "$SERVICE stopped." + else + echo "failed to stop $SERVICE!" + fi + + if [ -e $PIDFILE ]; then + echo "Removing stale PID file $PIDFILE" + rm -f $PIDFILE + fi +} + + +case "$1" in + start) + start + ;; + stop) + stop + ;; + status) + status + ;; + restart) + stop + start + ;; + *) + echo "Usage: $0 {start|stop|status|restart}" + exit 1 + ;; +esac + +exit $RETVAL diff --git a/puppet-manifests/src/modules/platform/manifests/dockerdistribution.pp b/puppet-manifests/src/modules/platform/manifests/dockerdistribution.pp index 5368cfe635..474dabab74 100644 --- a/puppet-manifests/src/modules/platform/manifests/dockerdistribution.pp +++ b/puppet-manifests/src/modules/platform/manifests/dockerdistribution.pp @@ -1,8 +1,11 @@ class platform::dockerdistribution::params ( + $registry_ks_endpoint = undef, ) {} class platform::dockerdistribution::config inherits ::platform::dockerdistribution::params { + include ::platform::params + include ::platform::kubernetes::params include ::platform::network::mgmt::params include ::platform::docker::params @@ -12,13 +15,12 @@ class platform::dockerdistribution::config # check insecure registries if $::platform::docker::params::insecure_registry { # insecure registry is true means unified registry was set - $insecure_registries = "\"${::platform::docker::params::k8s_registry}\", \"${docker_registry_ip}:9001\"" + $insecure_registries = "\"${::platform::docker::params::k8s_registry}\"" } else { - $insecure_registries = "\"${docker_registry_ip}:9001\"" + $insecure_registries = '' } - # currently docker registry is running insecure mode - # when proper authentication is implemented, this would go away + # for external docker registry running insecure mode file { '/etc/docker': ensure => 'directory', owner => 'root', @@ -33,7 +35,7 @@ class platform::dockerdistribution::config content => template('platform/insecuredockerregistry.conf.erb'), } - -> file { '/etc/docker-distribution/registry/config.yml': + file { '/etc/docker-distribution/registry/config.yml': ensure => present, owner => 'root', group => 'root', @@ -41,6 +43,14 @@ class platform::dockerdistribution::config content => template('platform/dockerdistribution.conf.erb'), } + file { '/etc/docker-distribution/registry/token_server.conf': + ensure => present, + owner => 'root', + group => 'root', + mode => '0644', + content => template('platform/registry-token-server.conf.erb'), + } + # copy the startup script to where it is supposed to be file {'docker_distribution_initd_script': ensure => 'present', @@ -48,27 +58,146 @@ class platform::dockerdistribution::config mode => '0755', source => "puppet:///modules/${module_name}/docker-distribution" } + + file {'registry_token_server_initd_script': + ensure => 'present', + path => '/etc/init.d/registry-token-server', + mode => '0755', + source => "puppet:///modules/${module_name}/registry-token-server" + } + + # self-signed certificate for registry use + # this needs to be generated here because the certificate + # need to know the registry ip address for SANs + if str2bool($::is_initial_config_primary) { + $shared_dir = $::platform::params::config_path + $certs_dir = '/etc/ssl/private' + + # create the certificate files + file { "${certs_dir}/registry-cert-extfile.cnf": + ensure => present, + owner => 'root', + group => 'root', + mode => '0400', + content => template('platform/registry-cert-extfile.erb'), + } + + -> exec { 'docker-registry-generate-cert': + command => "openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 \ + -keyout ${certs_dir}/registry-cert.key \ + -out ${certs_dir}/registry-cert.crt \ + -config ${certs_dir}/registry-cert-extfile.cnf", + logoutput => true + } + + -> exec { 'docker-registry-generate-pkcs1-cert-from-pkcs8': + command => "openssl rsa -in ${certs_dir}/registry-cert.key \ + -out ${certs_dir}/registry-cert-pkcs1.key", + logoutput => true + } + + # ensure permissions are set correctly + -> file { "${certs_dir}/registry-cert-pkcs1.key": + ensure => 'file', + owner => 'root', + group => 'root', + mode => '0400', + } + + -> file { "${certs_dir}/registry-cert.key": + ensure => 'file', + owner => 'root', + group => 'root', + mode => '0400', + } + + -> file { "${certs_dir}/registry-cert.crt": + ensure => 'file', + owner => 'root', + group => 'root', + mode => '0400', + } + + # delete the extfile used in certificate generation + -> exec { 'remove-registry-cert-extfile': + command => "rm ${certs_dir}/registry-cert-extfile.cnf" + } + + # copy certificates and keys to shared directory for second controller + # we do not need to worry about second controller being up at this point, + # since we have a is_initial_config_primary check + -> file { "${shared_dir}/registry-cert-pkcs1.key": + ensure => 'file', + owner => 'root', + group => 'root', + mode => '0400', + source => "${certs_dir}/registry-cert-pkcs1.key", + } + + -> file { "${shared_dir}/registry-cert.key": + ensure => 'file', + owner => 'root', + group => 'root', + mode => '0400', + source => "${certs_dir}/registry-cert.key", + } + + -> file { "${shared_dir}/registry-cert.crt": + ensure => 'file', + owner => 'root', + group => 'root', + mode => '0400', + source => "${certs_dir}/registry-cert.crt", + } + + # copy the certificate to docker certificates directory, + # which makes docker trust that specific certificate + # this is required for self-signed and also if the user does + # not have a certificate signed by a "default" CA + + -> file { '/etc/docker/certs.d': + ensure => 'directory', + owner => 'root', + group => 'root', + mode => '0700', + } + + -> file { "/etc/docker/certs.d/${docker_registry_ip}:9001": + ensure => 'directory', + owner => 'root', + group => 'root', + mode => '0700', + } + + -> file { "/etc/docker/certs.d/${docker_registry_ip}:9001/registry-cert.crt": + ensure => 'file', + owner => 'root', + group => 'root', + mode => '0400', + source => "${certs_dir}/registry-cert.crt", + } + } + } # compute also needs the "insecure" flag in order to deploy images from -# the registry. This will go away when proper authentication is implemented +# the registry. This is needed for insecure external registry class platform::dockerdistribution::compute inherits ::platform::dockerdistribution::params { + include ::platform::kubernetes::params + include ::platform::network::mgmt::params include ::platform::docker::params - $docker_registry_ip = $::platform::network::mgmt::params::controller_address - # check insecure registries if $::platform::docker::params::insecure_registry { # insecure registry is true means unified registry was set - $insecure_registries = "\"${::platform::docker::params::k8s_registry}\", \"${docker_registry_ip}:9001\"" + $insecure_registries = "\"${::platform::docker::params::k8s_registry}\"" } else { - $insecure_registries = "\"${docker_registry_ip}:9001\"" + $insecure_registries = '' } - # currently docker registry is running insecure mode - # when proper authentication is implemented, this would go away + # for external docker registry running insecure mode file { '/etc/docker': ensure => 'directory', owner => 'root', @@ -86,8 +215,23 @@ class platform::dockerdistribution::compute class platform::dockerdistribution inherits ::platform::dockerdistribution::params { + include ::platform::kubernetes::params include platform::dockerdistribution::config Class['::platform::docker::config'] -> Class[$name] } + +class platform::dockerdistribution::reload { + platform::sm::restart {'registry-token-server': } + platform::sm::restart {'docker-distribution': } +} + +# this does not update the config right now +# the run time is only used to restart the token server and registry +class platform::dockerdistribution::runtime { + + class {'::platform::dockerdistribution::reload': + stage => post + } +} diff --git a/puppet-manifests/src/modules/platform/manifests/sm.pp b/puppet-manifests/src/modules/platform/manifests/sm.pp index 64404fdb5d..47f114164e 100644 --- a/puppet-manifests/src/modules/platform/manifests/sm.pp +++ b/puppet-manifests/src/modules/platform/manifests/sm.pp @@ -1046,6 +1046,11 @@ class platform::sm command => "sm-configure service_instance docker-distribution docker-distribution \"\"", } + # Docker Registry Token Server + exec { 'Configure Docker Registry Token Server': + command => "sm-configure service_instance registry-token-server registry-token-server \"\"", + } + if $system_mode == 'duplex-direct' or $system_mode == 'simplex' { exec { 'Configure Platform NFS': command => "sm-configure service_instance platform-nfs-ip platform-nfs-ip \"ip=${platform_nfs_ip_param_ip},cidr_netmask=${platform_nfs_ip_param_mask},nic=${mgmt_ip_interface},arp_count=7,dc=yes\"", @@ -1188,6 +1193,14 @@ class platform::sm command => 'sm-provision service docker-distribution', } + # Configure Docker Registry Token Server + exec { 'Provision Docker Registry Token Server (service-group-member)': + command => 'sm-provision service-group-member controller-services registry-token-server', + } + -> exec { 'Provision Docker Registry Token Server (service)': + command => 'sm-provision service registry-token-server', + } + # Barbican if $barbican_enabled { exec { 'Provision OpenStack - Barbican API (service-group-member)': diff --git a/puppet-manifests/src/modules/platform/templates/dockerdistribution.conf.erb b/puppet-manifests/src/modules/platform/templates/dockerdistribution.conf.erb index 6fd11227af..625e18602b 100644 --- a/puppet-manifests/src/modules/platform/templates/dockerdistribution.conf.erb +++ b/puppet-manifests/src/modules/platform/templates/dockerdistribution.conf.erb @@ -10,8 +10,8 @@ storage: http: addr: <%= @docker_registry_ip %>:9001 tls: - certificate: /etc/ssl/private/self-signed-server-cert.pem - key: /etc/ssl/private/self-signed-server-cert.pem + certificate: /etc/ssl/private/registry-cert.crt + key: /etc/ssl/private/registry-cert.key headers: X-Content-Type-Options: [nosniff] health: @@ -19,3 +19,9 @@ health: enabled: true interval: 10s threshold: 3 +auth: + token: + realm: https://<%= @docker_registry_ip %>:9002/token/ + service: <%= @docker_registry_ip %>:9001 + issuer: bird-token-server + rootcertbundle: /etc/ssl/private/registry-cert.crt diff --git a/puppet-manifests/src/modules/platform/templates/registry-cert-extfile.erb b/puppet-manifests/src/modules/platform/templates/registry-cert-extfile.erb new file mode 100644 index 0000000000..c7b85d28e4 --- /dev/null +++ b/puppet-manifests/src/modules/platform/templates/registry-cert-extfile.erb @@ -0,0 +1,10 @@ +[req] +prompt = no +x509_extensions = v3_req +distinguished_name = dn +[dn] +CN = <%= @docker_registry_ip %> +[v3_req] +subjectAltName = @alt_names +[alt_names] +IP = <%= @docker_registry_ip %> diff --git a/puppet-manifests/src/modules/platform/templates/registry-token-server.conf.erb b/puppet-manifests/src/modules/platform/templates/registry-token-server.conf.erb new file mode 100644 index 0000000000..610d6ac0d4 --- /dev/null +++ b/puppet-manifests/src/modules/platform/templates/registry-token-server.conf.erb @@ -0,0 +1,7 @@ +REGISTRY_TOKEN_SERVER_ADDR=<%= @docker_registry_ip %>:9002 +REGISTRY_TOKEN_SERVER_ISSUER=bird-token-server +REGISTRY_TOKEN_SERVER_KS_ENDPOINT=<%= @registry_ks_endpoint %> +REGISTRY_TOKEN_SERVER_TLSCERT=/etc/ssl/private/registry-cert.crt +REGISTRY_TOKEN_SERVER_TLSKEY=/etc/ssl/private/registry-cert.key +REGISTRY_TOKEN_SERVER_REALM=https://<%= @docker_registry_ip %>:9002/token/ +REGISTRY_TOKEN_SERVER_KEY=/etc/ssl/private/registry-cert-pkcs1.key diff --git a/sysinv/cgts-client/cgts-client/cgtsclient/v1/certificate_shell.py b/sysinv/cgts-client/cgts-client/cgtsclient/v1/certificate_shell.py index b71bc2f2fd..8f97fb3f83 100644 --- a/sysinv/cgts-client/cgts-client/cgtsclient/v1/certificate_shell.py +++ b/sysinv/cgts-client/cgts-client/cgtsclient/v1/certificate_shell.py @@ -69,7 +69,8 @@ def do_certificate_list(cc, args): help='The passphrase for the PEM file') @utils.arg('-m', '--mode', metavar='', - help="optional mode: 'tpm_mode', 'murano', 'murano_ca'. " + help="optional mode: 'tpm_mode', 'murano', 'murano_ca'," + "'docker_registry'. " "Default is 'ssl'.") def do_certificate_install(cc, args): """Install certificate.""" diff --git a/sysinv/sysinv/sysinv/setup.cfg b/sysinv/sysinv/sysinv/setup.cfg index f4188b65fe..b59f8846c2 100644 --- a/sysinv/sysinv/sysinv/setup.cfg +++ b/sysinv/sysinv/sysinv/setup.cfg @@ -70,8 +70,9 @@ systemconfig.puppet_plugins = 030_smapi = sysinv.puppet.smapi:SmPuppet 031_fm = sysinv.puppet.fm:FmPuppet 032_swift = sysinv.puppet.swift:SwiftPuppet - 033_service_parameter = sysinv.puppet.service_parameter:ServiceParamPuppet - 034_barbican = sysinv.puppet.barbican:BarbicanPuppet + 033_barbican = sysinv.puppet.barbican:BarbicanPuppet + 034_dockerdistribution = sysinv.puppet.dockerdistribution:DockerDistributionPuppet + 099_service_parameter = sysinv.puppet.service_parameter:ServiceParamPuppet systemconfig.helm_plugins = aodh = sysinv.helm.aodh:AodhHelm diff --git a/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/certificate.py b/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/certificate.py index 372fe59f23..f6e39b82e9 100644 --- a/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/certificate.py +++ b/sysinv/sysinv/sysinv/sysinv/api/controllers/v1/certificate.py @@ -268,6 +268,7 @@ class CertificateController(rest.RestController): tpm_mode: install certificate to tpm devices for ssl murano: install certificate for rabbit-murano murano_ca: install ca certificate for rabbit-murano + docker_registry: install certificate for docker registry """ log_start = cutils.timestamped("certificate_do_post_start") @@ -297,7 +298,8 @@ class CertificateController(rest.RestController): system = pecan.request.dbapi.isystem_get_one() capabilities = system.capabilities - if not mode.startswith(constants.CERT_MODE_MURANO): + if not mode.startswith(constants.CERT_MODE_MURANO) and \ + mode != constants.CERT_MODE_DOCKER_REGISTRY: system_https_enabled = capabilities.get('https_enabled', False) if system_https_enabled is False or system_https_enabled == 'n': msg = "No certificates have been added, https is not enabled." diff --git a/sysinv/sysinv/sysinv/sysinv/common/constants.py b/sysinv/sysinv/sysinv/sysinv/common/constants.py index 197ab938e9..2e19a4a7e3 100644 --- a/sysinv/sysinv/sysinv/sysinv/common/constants.py +++ b/sysinv/sysinv/sysinv/sysinv/common/constants.py @@ -1329,6 +1329,17 @@ MURANO_CERT_KEY_FILE = os.path.join(CERT_MURANO_DIR, CERT_KEY_FILE) MURANO_CERT_FILE = os.path.join(CERT_MURANO_DIR, CERT_FILE) MURANO_CERT_CA_FILE = os.path.join(CERT_MURANO_DIR, CERT_CA_FILE) +DOCKER_REGISTRY_CERT_FILE = os.path.join(SSL_CERT_DIR, "registry-cert.crt") +DOCKER_REGISTRY_KEY_FILE = os.path.join(SSL_CERT_DIR, "registry-cert.key") +DOCKER_REGISTRY_PKCS1_KEY_FILE = os.path.join(SSL_CERT_DIR, + "registry-cert-pkcs1.key") +DOCKER_REGISTRY_CERT_FILE_SHARED = os.path.join(tsc.CONFIG_PATH, + "registry-cert.crt") +DOCKER_REGISTRY_KEY_FILE_SHARED = os.path.join(tsc.CONFIG_PATH, + "registry-cert.key") +DOCKER_REGISTRY_PKCS1_KEY_FILE_SHARED = os.path.join(tsc.CONFIG_PATH, + "registry-cert-pkcs1.key") + SSL_CERT_CA_DIR = "/etc/ssl/certs/" SSL_CERT_CA_FILE = os.path.join(SSL_CERT_CA_DIR, CERT_CA_FILE) SSL_CERT_CA_FILE_SHARED = os.path.join(tsc.CONFIG_PATH, CERT_CA_FILE) @@ -1338,11 +1349,13 @@ CERT_MODE_SSL_CA = 'ssl_ca' CERT_MODE_TPM = 'tpm_mode' CERT_MODE_MURANO = 'murano' CERT_MODE_MURANO_CA = 'murano_ca' +CERT_MODE_DOCKER_REGISTRY = 'docker_registry' CERT_MODES_SUPPORTED = [CERT_MODE_SSL, CERT_MODE_SSL_CA, CERT_MODE_TPM, CERT_MODE_MURANO, - CERT_MODE_MURANO_CA] + CERT_MODE_MURANO_CA, + CERT_MODE_DOCKER_REGISTRY] # CONFIG file permissions CONFIG_FILE_PERMISSION_ROOT_READ_ONLY = 0o400 diff --git a/sysinv/sysinv/sysinv/sysinv/conductor/manager.py b/sysinv/sysinv/sysinv/sysinv/conductor/manager.py index bfce9b634f..2c28ec858e 100644 --- a/sysinv/sysinv/sysinv/sysinv/conductor/manager.py +++ b/sysinv/sysinv/sysinv/sysinv/conductor/manager.py @@ -94,6 +94,7 @@ from sysinv.openstack.common.gettextutils import _ from sysinv.puppet import common as puppet_common from sysinv.puppet import puppet from sysinv.helm import helm +from sysinv.helm import common as helm_common MANAGER_TOPIC = 'sysinv.conductor_manager' @@ -10154,11 +10155,14 @@ class ConductorManager(service.PeriodicService): alarm.entity_instance_id) @staticmethod - def _extract_keys_from_pem(mode, pem_contents, passphrase=None): + def _extract_keys_from_pem(mode, pem_contents, cert_format, + passphrase=None): """Extract keys from the pem contents - :param mode: mode one of: ssl, tpm_mode, murano, murano_ca + :param mode: mode one of: ssl, tpm_mode, murano, murano_ca, + docker_registry :param pem_contents: pem_contents + :param cert_format: serialization.PrivateFormat :param passphrase: passphrase for PEM file :returns: private_bytes, public_bytes, signature @@ -10178,6 +10182,7 @@ class ConductorManager(service.PeriodicService): if mode in [constants.CERT_MODE_SSL, constants.CERT_MODE_TPM, constants.CERT_MODE_MURANO, + constants.CERT_MODE_DOCKER_REGISTRY, ]: private_mode = True @@ -10205,7 +10210,7 @@ class ConductorManager(service.PeriodicService): private_bytes = private_key.private_bytes( encoding=serialization.Encoding.PEM, - format=serialization.PrivateFormat.PKCS8, + format=cert_format, encryption_algorithm=serialization.NoEncryption()) signature = mode + '_' + str(cert.serial_number) @@ -10265,6 +10270,16 @@ class ConductorManager(service.PeriodicService): except OSError: pass + def _get_registry_floating_address(self): + """gets the registry floating address. Currently this is mgmt + """ + registry_network = self.dbapi.network_get_by_type( + constants.NETWORK_TYPE_MGMT) + registry_network_addr_pool = self.dbapi.address_pool_get( + registry_network.pool_uuid) + addr = registry_network_addr_pool.floating_address + return addr + def config_certificate(self, context, pem_contents, config_dict): """Configure certificate with the supplied data. @@ -10285,7 +10300,9 @@ class ConductorManager(service.PeriodicService): LOG.info("config_certificate mode=%s file=%s" % (mode, certificate_file)) private_bytes, public_bytes, signature = \ - self._extract_keys_from_pem(mode, pem_contents, passphrase) + self._extract_keys_from_pem(mode, pem_contents, + serialization.PrivateFormat.PKCS8, + passphrase) personalities = [constants.CONTROLLER] tpm = None @@ -10396,6 +10413,77 @@ class ConductorManager(service.PeriodicService): 'permissions': constants.CONFIG_FILE_PERMISSION_DEFAULT, } self._config_update_file(context, config_uuid, config_dict) + elif mode == constants.CERT_MODE_DOCKER_REGISTRY: + LOG.info("Docker registry certificate install") + # docker registry requires a PKCS1 key for the token server + pkcs1_private_bytes, pkcs1_public_bytes, pkcs1_signature = \ + self._extract_keys_from_pem(mode, pem_contents, + serialization.PrivateFormat + .TraditionalOpenSSL, passphrase) + + # install certificate, key, and pkcs1 key to controllers + config_uuid = self._config_update_hosts(context, personalities) + key_path = constants.DOCKER_REGISTRY_KEY_FILE + cert_path = constants.DOCKER_REGISTRY_CERT_FILE + pkcs1_key_path = constants.DOCKER_REGISTRY_PKCS1_KEY_FILE + + config_dict = { + 'personalities': personalities, + 'file_names': [key_path, cert_path, pkcs1_key_path], + 'file_content': {key_path: private_bytes, + cert_path: public_bytes, + pkcs1_key_path: pkcs1_private_bytes}, + 'nobackup': True, + 'permissions': constants.CONFIG_FILE_PERMISSION_ROOT_READ_ONLY, + } + self._config_update_file(context, config_uuid, config_dict) + + # copy certificate to shared directory + with os.fdopen(os.open(constants.DOCKER_REGISTRY_CERT_FILE_SHARED, + os.O_CREAT | os.O_WRONLY, + constants.CONFIG_FILE_PERMISSION_ROOT_READ_ONLY), + 'wb') as f: + f.write(public_bytes) + with os.fdopen(os.open(constants.DOCKER_REGISTRY_KEY_FILE_SHARED, + os.O_CREAT | os.O_WRONLY, + constants.CONFIG_FILE_PERMISSION_ROOT_READ_ONLY), + 'wb') as f: + f.write(private_bytes) + with os.fdopen(os.open(constants.DOCKER_REGISTRY_PKCS1_KEY_FILE_SHARED, + os.O_CREAT | os.O_WRONLY, + constants.CONFIG_FILE_PERMISSION_ROOT_READ_ONLY), + 'wb') as f: + f.write(pkcs1_private_bytes) + + config_uuid = self._config_update_hosts(context, personalities) + config_dict = { + "personalities": personalities, + "classes": ['platform::dockerdistribution::runtime'] + } + self._config_apply_runtime_manifest(context, + config_uuid, + config_dict) + + self._remove_certificate_file(mode, certificate_file) + + # install docker certificate on controllers and workers + registry_full_address = self._get_registry_floating_address() + ":" + helm_common.REGISTRY_PORT + docker_cert_path = os.path.join("/etc/docker/certs.d", + registry_full_address, + "registry-cert.crt") + + personalities = [constants.CONTROLLER, + constants.WORKER] + config_uuid = self._config_update_hosts(context, + personalities) + config_dict = { + 'personalities': personalities, + 'file_names': [docker_cert_path], + 'file_content': public_bytes, + 'nobackup': True, + 'permissions': constants.CONFIG_FILE_PERMISSION_ROOT_READ_ONLY, + } + self._config_update_file(context, config_uuid, config_dict) else: msg = "config_certificate unexpected mode=%s" % mode LOG.warn(msg) @@ -10422,7 +10510,9 @@ class ConductorManager(service.PeriodicService): LOG.info("_config_selfsigned_certificate mode=%s file=%s" % (mode, certificate_file)) private_bytes, public_bytes, signature = \ - self._extract_keys_from_pem(mode, pem_contents, passphrase) + self._extract_keys_from_pem(mode, pem_contents, + serialization.PrivateFormat.PKCS8, + passphrase) personalities = [constants.CONTROLLER] diff --git a/sysinv/sysinv/sysinv/sysinv/puppet/dockerdistribution.py b/sysinv/sysinv/sysinv/sysinv/puppet/dockerdistribution.py new file mode 100644 index 0000000000..ae5a1970d3 --- /dev/null +++ b/sysinv/sysinv/sysinv/sysinv/puppet/dockerdistribution.py @@ -0,0 +1,19 @@ +# +# Copyright (c) 2019 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +from sysinv.puppet import base + + +class DockerDistributionPuppet(base.BasePuppet): + """Class to encapsulate puppet operations for docker distribution""" + + def get_system_config(self): + config = { + 'platform::dockerdistribution::params::registry_ks_endpoint': + self._operator.keystone.get_auth_uri() + '/v3', + } + + return config diff --git a/workerconfig/workerconfig/worker_config b/workerconfig/workerconfig/worker_config index 9814cc5ec1..83dd28eccc 100644 --- a/workerconfig/workerconfig/worker_config +++ b/workerconfig/workerconfig/worker_config @@ -249,6 +249,17 @@ start() then fatal_error "This node is running a different load than the active controller and must be reinstalled" fi + + # Install docker certificate if required + # this is management network for now + REGISTRY_IP=$(get_ip controller) + mkdir -p /etc/docker/certs.d/$REGISTRY_IP:9001/ + chmod 700 /etc/docker/certs.d/$REGISTRY_IP:9001/ + cp $CONFIG_DIR/registry-cert.crt /etc/docker/certs.d/$REGISTRY_IP:9001/registry-cert.crt + if [ $? -ne 0 ] + then + fatal_error "Unable to copy $CONFIG_DIR/registry-cert.crt to docker dir" + fi fi # banner customization always returns 0, success: