Docker Registry Keystone Authentication
This commit adds functionality for Docker registry to authenticate using Keystone. First, this commit contains puppet changes which are required to manage the new token server required for Keystone authentication. Second, with proper authentication now implemented, we are removing the "insecure" flag for the controller registry in the "daemon.json" file in "/etc/docker". With the "insecure" flag removed, Docker will start complaining about certificate issues. This commit also includes generation of default certificates suitable for use by Docker registry as well as a sysinv command "system certificate-install -m docker_registry" to update the certificate. Docker registry token server works only with PKCS1 style keys while we would like to use PKCS8 keys by default. This is why our default certificate and installed certificate create both a PKCS1 style key as well as a PKCS8 style key. The keys are installed to "/etc/ssl/private/" as registry-cert.crt, registry-cert.key, and registry-cert-pkcs1.key. Story: 2002840 Task: 22783 Depends-On: https://review.openstack.org/#/c/626354/ Change-Id: I0127bd5f10f3950739678929b92eb1b77e2119db Signed-off-by: Jerry Sun <jerry.sun@windriver.com>
This commit is contained in:
parent
6b898c16e8
commit
158e300d54
@ -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
|
||||
|
@ -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
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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)':
|
||||
|
@ -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
|
||||
|
@ -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 %>
|
@ -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
|
@ -69,7 +69,8 @@ def do_certificate_list(cc, args):
|
||||
help='The passphrase for the PEM file')
|
||||
@utils.arg('-m', '--mode',
|
||||
metavar='<mode>',
|
||||
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."""
|
||||
|
@ -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
|
||||
|
@ -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."
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
||||
|
19
sysinv/sysinv/sysinv/sysinv/puppet/dockerdistribution.py
Normal file
19
sysinv/sysinv/sysinv/sysinv/puppet/dockerdistribution.py
Normal file
@ -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
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user