Create trust_id for bay

All bays use the same trustee_user and different trust. A trust is
created for a bay when the bay is created, and is deleted when the
bay is deleted.

Partially-Implements: blueprint registryv2-in-master
Change-Id: Iab2037677f683fe4c562915b98303da02c59c299
changes/40/252240/9
Hua Wang 7 years ago
parent 554af35b74
commit 8074f6f4ce

@ -142,6 +142,10 @@
# (string value)
#instance_uuid_format = "[instance: %(uuid)s] "
# Format string for user_identity field of the
# logging_context_format_string (string value)
#logging_user_identity_format = %(user)s %(tenant)s %(domain)s %(user_domain)s %(project_domain)s
# Enables or disables fatal status of deprecations. (boolean value)
#fatal_deprecations = false
@ -194,6 +198,16 @@
# Shows whether zmq-messaging uses broker or not. (boolean value)
#zmq_use_broker = true
# Minimal port number for random ports range. (integer value)
#rpc_zmq_min_port = 49152
# Maximal port number for random ports range. (integer value)
#rpc_zmq_max_port = 65536
# Number of retries to find free port number before fail with
# ZMQBindError. (integer value)
#rpc_zmq_bind_port_retries = 100
# Host to locate redis. (string value)
#host = 127.0.0.1
@ -211,6 +225,11 @@
# messaging, messagingv2, routing, log, test, noop (multi valued)
#notification_driver =
# A URL representing the messaging driver to use for notifications. If
# not set, we fall back to the same configuration used for RPC.
# (string value)
#notification_transport_url = <None>
# AMQP topic used for OpenStack notifications. (list value)
# Deprecated group/name - [rpc_notifier2]/topics
#notification_topics = notifications
@ -259,7 +278,7 @@
# Specify a timeout after which a gracefully shutdown server will
# exit. Zero value means endless wait. (integer value)
#graceful_shutdown_timeout = 0
#graceful_shutdown_timeout = 60
[api]
@ -320,7 +339,7 @@
# Location of template to build a swarm cluster on atomic. (string
# value)
#swarm_atomic_template_path = $pybasedir/templates/swarm/swarm.yaml
#swarm_atomic_template_path = $pybasedir/templates/swarm/swarmcluster.yaml
# Location of template to build a Mesos cluster on Ubuntu. (string
# value)
@ -363,23 +382,23 @@
# network drivers include flannel. (list value)
#kubernetes_allowed_network_drivers = all
# Default network driver for kubernetes baymodels.
# Default network driver for kubernetes baymodels. (string value)
#kubernetes_default_network_driver = flannel
# Allowed network drivers for docker swarm baymodels. Use 'all' keyword
# to allow all drivers supported for swarm baymodels. Supported
# network drivers include docker. (list value)
# Allowed network drivers for docker swarm baymodels. Use 'all'
# keyword to allow all drivers supported for swarm baymodels.
# Supported network drivers include docker and flannel. (list value)
#swarm_allowed_network_drivers = all
# Default network driver for docker swarm baymodels.
# Default network driver for docker swarm baymodels. (string value)
#swarm_default_network_driver = docker
# Allowed network drivers for mesos baymodels. Use 'all' keyword
# to allow all drivers supported for mesos baymodels. Supported
# network drivers include docker. (list value)
# Allowed network drivers for mesos baymodels. Use 'all' keyword to
# allow all drivers supported for mesos baymodels. Supported network
# drivers include docker. (list value)
#mesos_allowed_network_drivers = all
# Default network driver for mesos baymodels.
# Default network driver for mesos baymodels. (string value)
#mesos_default_network_driver = docker
@ -418,7 +437,7 @@
#
# Indicate whether this resource may be shared with the domain
# received in the requests "origin" header. (string value)
# received in the requests "origin" header. (list value)
#allowed_origin = <None>
# Indicate that the actual request can include user credentials
@ -448,7 +467,7 @@
#
# Indicate whether this resource may be shared with the domain
# received in the requests "origin" header. (string value)
# received in the requests "origin" header. (list value)
#allowed_origin = <None>
# Indicate that the actual request can include user credentials
@ -596,7 +615,7 @@
# Default timeout in seconds for docker client operations. (integer
# value)
#default_timeout = 10
#default_timeout = 60
# If set, ignore any SSL validation issues (boolean value)
#api_insecure = false
@ -614,6 +633,20 @@
#key_file = <None>
[docker_registry]
#
# From magnum
#
# User id of the trustee (string value)
#trustee_user_id = <None>
# The roles which are delegated to the trustee by the trustor. (list
# value)
#trust_roles = registry_user
[glance_client]
#
@ -829,6 +862,14 @@
# Service tenant name. (string value)
#admin_tenant_name = admin
# Authentication type to load (unknown value)
# Deprecated group/name - [DEFAULT]/auth_plugin
#auth_type = <None>
# Config Section from which to load plugin specific options (unknown
# value)
#auth_section = <None>
[magnum_client]

@ -41,7 +41,8 @@ class BayPatchType(types.JsonPatchType):
def internal_attrs():
internal_attrs = ['/api_address', '/node_addresses',
'/master_addresses', '/stack_id',
'/ca_cert_ref', '/magnum_cert_ref']
'/ca_cert_ref', '/magnum_cert_ref',
'/registry_trust_id']
return types.JsonPatchType.internal_attrs() + internal_attrs

@ -540,3 +540,11 @@ class FlavorNotFound(ResourceNotFound):
class NetworkNotFound(ResourceNotFound):
message = _("Unable to find network %(network)s.")
class TrustCreateFailed(MagnumException):
message = _("Failed to create trust for trustee %(trustee_user_id)s.")
class TrustDeleteFailed(MagnumException):
message = _("Failed to delete trust %(trust_id)s.")

@ -83,7 +83,8 @@ class KeystoneClientV3(object):
return 'token' in auth_token_info
def _get_ks_client(self):
kwargs = {'auth_url': self.auth_url}
kwargs = {'auth_url': self.auth_url,
'endpoint': self.auth_url}
if self.context.trust_id:
kwargs.update(self._get_admin_credentials())
kwargs['trust_id'] = self.context.trust_id
@ -112,11 +113,17 @@ class KeystoneClientV3(object):
def create_trust(self, trustee_user, role_names, impersonation=True):
trustor_user_id = self.client.auth_ref.user_id
trustor_project_id = self.client.auth_ref.project_id
trust = self.client.trusts.create(trustor_user=trustor_user_id,
project=trustor_project_id,
trustee_user=trustee_user,
impersonation=impersonation,
role_names=role_names)
try:
trust = self.client.trusts.create(
trustor_user=trustor_user_id,
project=trustor_project_id,
trustee_user=trustee_user,
impersonation=impersonation,
role_names=role_names)
except Exception as e:
LOG.exception(str(e))
raise exception.TrustCreateFailed(
trustee_user_id=trustee_user)
return trust
def create_trust_to_admin(self, role_names, impersonation=True):
@ -124,7 +131,12 @@ class KeystoneClientV3(object):
return self.create_trust(trustee_user, role_names, impersonation)
def delete_trust(self, trust_id):
if trust_id is None:
return
try:
self.client.trusts.delete(trust_id)
except kc_exception.NotFound:
pass
except Exception as e:
LOG.exception(str(e))
raise exception.TrustDeleteFailed(trust_id=trust_id)

@ -51,8 +51,19 @@ bay_heat_opts = [
'interval is in minutes. The default is no timeout.'))
]
cfg.CONF.register_opts(bay_heat_opts, group='bay_heat')
docker_registry_opts = [
cfg.StrOpt('trustee_user_id',
default=None,
help='User id of the trustee'),
cfg.ListOpt('trust_roles',
default=['registry_user'],
help='The roles which are delegated to the trustee '
'by the trustor.')
]
CONF = cfg.CONF
CONF.register_opts(bay_heat_opts, group='bay_heat')
CONF.register_opts(docker_registry_opts, 'docker_registry')
LOG = logging.getLogger(__name__)
@ -123,6 +134,14 @@ class Handler(object):
osc = clients.OpenStackClients(context)
baymodel = objects.BayModel.get_by_uuid(context,
bay.baymodel_id)
if baymodel.registry_enabled:
trust = osc.keystone().create_trust(
CONF.docker_registry.trustee_user_id,
CONF.docker_registry.trust_roles)
bay.registry_trust_id = trust.id
try:
# Generate certificate and set the cert reference to bay
bay.uuid = uuid.uuid4()
@ -199,6 +218,7 @@ class Handler(object):
except Exception:
raise
osc.keystone().delete_trust(bay.registry_trust_id)
self._poll_and_check(osc, bay)
return None

@ -0,0 +1,31 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""add registry_trust_id to bay
Revision ID: adc3b7679ae
Revises: 40f325033343
Create Date: 2015-12-07 15:49:07.622122
"""
# revision identifiers, used by Alembic.
revision = 'adc3b7679ae'
down_revision = '40f325033343'
from alembic import op
import sqlalchemy as sa
def upgrade():
op.add_column('bay', sa.Column('registry_trust_id',
sa.String(length=255), nullable=True))

@ -120,6 +120,8 @@ class Bay(Base):
bay_create_timeout = Column(Integer())
discovery_url = Column(String(255))
master_addresses = Column(JSONEncodedList)
# TODO(wanghua): encrypt registry_trust_id in db
registry_trust_id = Column(String(255))
# (yuanying) if we use barbican,
# cert_ref size is determined by below format
# * http(s)://${DOMAIN_NAME}/v1/containers/${UUID}

@ -27,7 +27,8 @@ class Bay(base.MagnumPersistentObject, base.MagnumObject,
base.MagnumObjectDictCompat):
# Version 1.0: Initial version
# Version 1.1: Added 'bay_create_timeout' field
VERSION = '1.1'
# Version 1.2: Add 'registry_trust_id' field
VERSION = '1.2'
dbapi = dbapi.get_instance()
@ -50,6 +51,7 @@ class Bay(base.MagnumPersistentObject, base.MagnumObject,
'master_addresses': fields.ListOfStringsField(nullable=True),
'ca_cert_ref': fields.StringField(nullable=True),
'magnum_cert_ref': fields.StringField(nullable=True),
'registry_trust_id': fields.StringField(nullable=True)
}
@staticmethod

@ -46,6 +46,8 @@ def list_opts():
('conductor', magnum.conductor.config.SERVICE_OPTS),
('database', magnum.db.sql_opts),
('docker', magnum.common.docker_utils.docker_opts),
('docker_registry',
magnum.conductor.handlers.bay_conductor.docker_registry_opts),
('magnum_client', magnum.common.clients.magnum_client_opts),
('heat_client', magnum.common.clients.heat_client_opts),
('glance_client', magnum.common.clients.glance_client_opts),

@ -49,7 +49,8 @@ class KeystoneClientTest(base.BaseTestCase):
ks_client.client
self.assertIsNotNone(ks_client._client)
mock_ks.assert_called_once_with(token='abcd1234',
auth_url='http://server.test:5000/v3')
auth_url='http://server.test:5000/v3',
endpoint='http://server.test:5000/v3')
def test_client_with_no_credentials(self, mock_ks):
self.ctx.auth_token = None
@ -65,6 +66,7 @@ class KeystoneClientTest(base.BaseTestCase):
self.assertIsNotNone(ks_client._client)
mock_ks.assert_called_once_with(auth_ref={'version': 'v2.0'},
auth_url='http://server.test:5000/v3',
endpoint='http://server.test:5000/v3',
token='abcd1234')
def test_client_with_v3_auth_token_info(self, mock_ks):
@ -75,6 +77,7 @@ class KeystoneClientTest(base.BaseTestCase):
self.assertIsNotNone(ks_client._client)
mock_ks.assert_called_once_with(auth_ref={'version': 'v3'},
auth_url='http://server.test:5000/v3',
endpoint='http://server.test:5000/v3',
token='abcd1234')
def test_client_with_invalid_auth_token_info(self, mock_ks):

@ -95,6 +95,8 @@ def get_test_bay(**kw):
'node_count': kw.get('node_count', 3),
'master_count': kw.get('master_count', 3),
'master_addresses': kw.get('master_addresses', ['172.17.2.18']),
'registry_trust_id': kw.get('registry_trust_id',
'1f2281ac-e532-4e53-bbe6-3c9be24b0504'),
'created_at': kw.get('created_at'),
'updated_at': kw.get('updated_at'),
}

@ -423,7 +423,7 @@ class _TestObject(object):
# For more information on object version testing, read
# http://docs.openstack.org/developer/magnum/objects.html
object_data = {
'Bay': '1.1-aa9937c7453c0fdb9165bd2a83640ed9',
'Bay': '1.2-0749bac339a2cc24dc03f45a4359013d',
'BayLock': '1.0-7d1eb08cf2070523bd210369c7a2e076',
'BayModel': '1.8-a4bb0976be245f06edbd1db087a18071',
'Certificate': '1.0-2aff667971b85c1edf8d15684fd7d5e2',

Loading…
Cancel
Save