diff --git a/chart/crds/identity.openstack.org_endpoints.yaml b/chart/crds/identity.openstack.org_endpoints.yaml new file mode 100644 index 00000000..38a18494 --- /dev/null +++ b/chart/crds/identity.openstack.org_endpoints.yaml @@ -0,0 +1,24 @@ +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: endpoints.identity.openstack.org +spec: + group: identity.openstack.org + names: + kind: Endpoint + listKind: EndpointList + plural: endpoints + singular: endpoint + scope: Cluster + version: v1alpha1 + versions: + - name: v1alpha1 + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/chart/templates/clusterrole.yaml b/chart/templates/clusterrole.yaml index 89da1440..d6f6f904 100644 --- a/chart/templates/clusterrole.yaml +++ b/chart/templates/clusterrole.yaml @@ -114,6 +114,7 @@ rules: resources: - services - keystones + - endpoints verbs: - create - delete @@ -127,6 +128,7 @@ rules: resources: - services/status - keystones/status + - endpoints/status verbs: - get - patch diff --git a/chart/templates/deployment.yaml b/chart/templates/deployment.yaml index 2c2e9ad9..17a5e473 100644 --- a/chart/templates/deployment.yaml +++ b/chart/templates/deployment.yaml @@ -37,6 +37,8 @@ spec: - -m - openstack_operator.memcached - -m + - openstack_operator.openstack.identity.endpoints + - -m - openstack_operator.openstack.identity.services - -m - openstack_operator.rabbitmq diff --git a/config/samples/identity_v1alpha1_endpoint.yaml b/config/samples/identity_v1alpha1_endpoint.yaml new file mode 100644 index 00000000..9d522740 --- /dev/null +++ b/config/samples/identity_v1alpha1_endpoint.yaml @@ -0,0 +1,9 @@ +--- +apiVersion: identity.openstack.org/v1alpha1 +kind: Endpoint +metadata: + name: heat-public +spec: + service: orchestration + interface: public + url: https://orchestration.sjc1.vexxhost.net diff --git a/devstack/override-defaults b/devstack/override-defaults index 78b9f491..c93d4870 100644 --- a/devstack/override-defaults +++ b/devstack/override-defaults @@ -135,3 +135,19 @@ function bootstrap_keystone { --bootstrap-public-url "$KEYSTONE_SERVICE_URI" } export -f bootstrap_keystone +# Create an endpoint with a specific interface +# Usage: _get_or_create_endpoint_with_interface +function _get_or_create_endpoint_with_interface { + cat < 1: + raise RuntimeError("Multiple services with type: %s" % service_type) + if len(services) == 0: + raise RuntimeError("Unable to find service: %s" % service_type) + return services[0] + + +def _get_endpoint(conn, service_type, interface): + """Get an endpoint from Keystone + + This method will retrieve the endpoint from Keystone, raise an error if it + found more than one or return None if it couldn't find it + """ + + service = _get_service_by_type(conn, service_type) + + filters = { + "service_id": service.id, + "interface": interface, + "region": conn.config.get_region_name(), + } + endpoints = conn.search_endpoints(filters=filters) + + if len(endpoints) > 1: + raise RuntimeError("Found multiple endpoints with interface & region") + if len(endpoints) == 0: + return service, None + return service, endpoints[0] + + +@kopf.on.resume('identity.openstack.org', 'v1alpha1', 'endpoints') +@kopf.on.create('identity.openstack.org', 'v1alpha1', 'endpoints') +def create_or_resume(spec, **_): + """Create or resume controller + + This function runs when a new resource is created or when the controller + is first started. It creates or updates the appropriate endpoint. + """ + + conn = utils.get_openstack_connection() + service, endpoint = _get_endpoint(conn, spec["service"], spec["interface"]) + if endpoint: + conn.update_endpoint(endpoint.id, url=spec["url"]) + return + + conn.create_endpoint(service_name_or_id=service.id, url=spec["url"], + interface=spec["interface"], + region=conn.config.get_region_name()) + + +@kopf.on.delete('identity.openstack.org', 'v1alpha1', 'endpoints') +def delete(spec, **_): + """Delete an endpoint + + This function runs when the endpoint CR is deleted and removes the record + from Keystone. + """ + + conn = utils.get_openstack_connection() + endpoint = _get_endpoint(conn, spec["service"], spec["interface"]) + + if not endpoint: + return + + conn.delete_endpoint(endpoint) diff --git a/openstack_operator/openstack/identity/services.py b/openstack_operator/openstack/identity/services.py index a1f4a741..a4f8c99a 100644 --- a/openstack_operator/openstack/identity/services.py +++ b/openstack_operator/openstack/identity/services.py @@ -51,7 +51,6 @@ def create_or_resume(name, spec, **_): conn = utils.get_openstack_connection() service = _get_service(conn, name, spec["type"]) - if service: service = conn.update_service(service.id, name=name, type=spec["type"], diff --git a/playbooks/functional/post.yaml b/playbooks/functional/post.yaml index c534f2b0..e376b7aa 100755 --- a/playbooks/functional/post.yaml +++ b/playbooks/functional/post.yaml @@ -16,5 +16,6 @@ - hosts: all roles: - - collect-container-logs - - collect-kubernetes-logs + - collect-container-logs + - collect-kubernetes-logs + diff --git a/playbooks/functional/run.yaml b/playbooks/functional/run.yaml index 96820e42..6beca174 100755 --- a/playbooks/functional/run.yaml +++ b/playbooks/functional/run.yaml @@ -32,6 +32,7 @@ OS_USER_DOMAIN_ID: default OS_USERNAME: admin OS_PASSWORD: secretadmin + OS_REGION_NAME: RegionOne EOF roles: - role: helm-template