diff --git a/Makefile b/Makefile index 168d45f3076..fdf4c9a232d 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,14 @@ OPENSHIFT_PROJECT ?= $(shell oc project -q) OPENSHIFT_USER ?= $(shell oc whoami) OPENSHIFT_TOKEN ?= $(shell oc whoami -t) OPENSHIFT_MASTER ?= $(shell oc whoami --show-server=true) -MULTITENANT ?= false SYSTEMTEST_ARGS = +MODE ?= singletenant + +ifeq ($(MODE),singletenant) + MULTITENANT=false +else + MULTITENANT=true +endif DOCKER_TARGETS = docker_build docker_tag docker_push BUILD_TARGETS = init build test package clean $(DOCKER_TARGETS) coverage @@ -34,7 +40,7 @@ $(DOCKER_DIRS): $(MAKE) FULL_BUILD=$(FULL_BUILD) -C $@ $(MAKECMDGOALS) deploy: - ./templates/install/deploy-openshift.sh -n $(OPENSHIFT_PROJECT) -u $(OPENSHIFT_USER) -m $(OPENSHIFT_MASTER) -p MULTITENANT=$(MULTITENANT) -a "standard none" + ./templates/install/deploy-openshift.sh -n $(OPENSHIFT_PROJECT) -u $(OPENSHIFT_USER) -m $(OPENSHIFT_MASTER) -o $(MODE) -a "standard none" systemtests: OPENSHIFT_PROJECT=$(OPENSHIFT_PROJECT) OPENSHIFT_MULTITENANT=$(MULTITENANT) OPENSHIFT_TOKEN=$(OPENSHIFT_TOKEN) OPENSHIFT_USER=$(OPENSHIFT_USER) OPENSHIFT_URL=$(OPENSHIFT_MASTER) OPENSHIFT_USE_TLS=true ./systemtests/scripts/run_tests.sh $(SYSTEMTEST_ARGS) diff --git a/address-controller/src/main/java/io/enmasse/controller/Controller.java b/address-controller/src/main/java/io/enmasse/controller/Controller.java index 9b945a8c12a..ff50cffcf54 100644 --- a/address-controller/src/main/java/io/enmasse/controller/Controller.java +++ b/address-controller/src/main/java/io/enmasse/controller/Controller.java @@ -56,10 +56,9 @@ public Controller(OpenShiftClient client, AddressSpaceApi addressSpaceApi, Kubernetes kubernetes, AuthenticationServiceResolverFactory authResolverFactory, - boolean isMultitenant, UserDatabase userDatabase, List addressSpaceControllers) { - this.helper = new ControllerHelper(kubernetes, isMultitenant, authResolverFactory, userDatabase); + this.helper = new ControllerHelper(kubernetes, authResolverFactory, userDatabase); this.client = client; this.addressSpaceApi = addressSpaceApi; this.addressSpaceControllers = addressSpaceControllers; @@ -125,7 +124,7 @@ public void resourcesUpdated(Set resources) throws Exception { } private void retainAddressSpaces(Set desiredAddressSpaces) { - helper.retainAddressSpaces(desiredAddressSpaces.stream().map(AddressSpace::getName).collect(Collectors.toSet())); + helper.retainAddressSpaces(desiredAddressSpaces); } private void createAddressSpaces(Set instances) { diff --git a/address-controller/src/main/java/io/enmasse/controller/ControllerHelper.java b/address-controller/src/main/java/io/enmasse/controller/ControllerHelper.java index a26c8775415..42c2b632149 100644 --- a/address-controller/src/main/java/io/enmasse/controller/ControllerHelper.java +++ b/address-controller/src/main/java/io/enmasse/controller/ControllerHelper.java @@ -43,14 +43,12 @@ public class ControllerHelper { private static final Logger log = LoggerFactory.getLogger(ControllerHelper.class.getName()); private final Kubernetes kubernetes; - private final boolean isMultitenant; private final String namespace; private final AuthenticationServiceResolverFactory authResolverFactory; private final UserDatabase userDatabase; - public ControllerHelper(Kubernetes kubernetes, boolean isMultitenant, AuthenticationServiceResolverFactory authResolverFactory, UserDatabase userDatabase) { + public ControllerHelper(Kubernetes kubernetes, AuthenticationServiceResolverFactory authResolverFactory, UserDatabase userDatabase) { this.kubernetes = kubernetes; - this.isMultitenant = isMultitenant; this.namespace = kubernetes.getNamespace(); this.authResolverFactory = authResolverFactory; this.userDatabase = userDatabase; @@ -62,7 +60,7 @@ public void create(AddressSpace addressSpace) { return; } log.info("Creating address space {}", addressSpace); - if (isMultitenant) { + if (!addressSpace.getNamespace().equals(namespace)) { kubernetes.createNamespace(addressSpace.getName(), addressSpace.getNamespace()); kubernetes.addDefaultViewPolicy(addressSpace.getNamespace()); } @@ -222,20 +220,23 @@ public boolean isReady(AddressSpace addressSpace) { return readyDeployments.containsAll(requiredDeployments); } - public void retainAddressSpaces(Set desiredAddressSpaces) { - if (isMultitenant) { - Map labels = new LinkedHashMap<>(); - labels.put(LabelKeys.APP, "enmasse"); - labels.put(LabelKeys.TYPE, "address-space"); - for (Namespace namespace : kubernetes.listNamespaces(labels)) { - String id = namespace.getMetadata().getAnnotations().get(AnnotationKeys.ADDRESS_SPACE); - if (!desiredAddressSpaces.contains(id)) { - try { - log.info("Deleting address space {}", id); - kubernetes.deleteNamespace(namespace.getMetadata().getName()); - } catch(KubernetesClientException e){ - log.info("Exception when deleting namespace (may already be in progress): " + e.getMessage()); - } + public void retainAddressSpaces(Set desiredAddressSpaces) { + if (desiredAddressSpaces.size() == 1 && desiredAddressSpaces.iterator().next().getNamespace().equals(namespace)) { + return; + } + Set addressSpaceIds = desiredAddressSpaces.stream().map(AddressSpace::getName).collect(Collectors.toSet()); + + Map labels = new LinkedHashMap<>(); + labels.put(LabelKeys.APP, "enmasse"); + labels.put(LabelKeys.TYPE, "address-space"); + for (Namespace namespace : kubernetes.listNamespaces(labels)) { + String id = namespace.getMetadata().getAnnotations().get(AnnotationKeys.ADDRESS_SPACE); + if (!addressSpaceIds.contains(id)) { + try { + log.info("Deleting address space {}", id); + kubernetes.deleteNamespace(namespace.getMetadata().getName()); + } catch(KubernetesClientException e){ + log.info("Exception when deleting namespace (may already be in progress): " + e.getMessage()); } } } diff --git a/address-controller/src/main/java/io/enmasse/controller/ControllerOptions.java b/address-controller/src/main/java/io/enmasse/controller/ControllerOptions.java index 7a617158e3e..df584692bea 100644 --- a/address-controller/src/main/java/io/enmasse/controller/ControllerOptions.java +++ b/address-controller/src/main/java/io/enmasse/controller/ControllerOptions.java @@ -29,7 +29,6 @@ public final class ControllerOptions { private static final String SERVICEACCOUNT_PATH = "/var/run/secrets/kubernetes.io/serviceaccount"; private final String masterUrl; - private final boolean isMultitenant; private final String namespace; private final String token; private final File caDir; @@ -46,13 +45,12 @@ public final class ControllerOptions { private final String userDbSecretName; private final boolean enableApiAuth; - private ControllerOptions(String masterUrl, boolean isMultitenant, String namespace, String token, + private ControllerOptions(String masterUrl, String namespace, String token, File caDir, File templateDir, String messagingHost, String mqttHost, String consoleHost, String certSecret, String certDir, PasswordAuthentication osbAuth, AuthServiceInfo noneAuthService, AuthServiceInfo standardAuthService, String userDbSecretName, boolean enableApiAuth) { this.masterUrl = masterUrl; - this.isMultitenant = isMultitenant; this.namespace = namespace; this.token = token; this.caDir = caDir; @@ -81,10 +79,6 @@ public String token() { return token; } - public boolean isMultitenant() { - return isMultitenant; - } - public File caDir() { return caDir; } @@ -138,7 +132,6 @@ public static ControllerOptions fromEnv(Map env) throws IOExcept String masterHost = getEnvOrThrow(env, "KUBERNETES_SERVICE_HOST"); String masterPort = getEnvOrThrow(env, "KUBERNETES_SERVICE_PORT"); - boolean isMultitenant= Boolean.parseBoolean(env.get("MULTITENANT")); String namespace = getEnv(env, "NAMESPACE") .orElseGet(() -> readFile(new File(SERVICEACCOUNT_PATH, "namespace"))); @@ -173,7 +166,6 @@ public static ControllerOptions fromEnv(Map env) throws IOExcept boolean enableApiAuth = Boolean.parseBoolean(getEnv(env, "ADDRESS_CONTROLLER_ENABLE_API_AUTH").orElse("false")); return new ControllerOptions(String.format("https://%s:%s", masterHost, masterPort), - isMultitenant, namespace, token, caDir, diff --git a/address-controller/src/main/java/io/enmasse/controller/Main.java b/address-controller/src/main/java/io/enmasse/controller/Main.java index 9e4f473caff..eb8fa43eb4a 100644 --- a/address-controller/src/main/java/io/enmasse/controller/Main.java +++ b/address-controller/src/main/java/io/enmasse/controller/Main.java @@ -18,16 +18,10 @@ import java.util.*; -import io.enmasse.address.model.AddressSpace; -import io.enmasse.address.model.AuthenticationService; import io.enmasse.address.model.AuthenticationServiceResolver; import io.enmasse.address.model.AuthenticationServiceType; import io.enmasse.address.model.CertProvider; import io.enmasse.address.model.Endpoint; -import io.enmasse.address.model.SecretCertProvider; -import io.enmasse.address.model.types.AddressSpaceType; -import io.enmasse.address.model.types.standard.StandardAddressSpaceType; -import io.enmasse.address.model.v1.CodecV1; import io.enmasse.controller.auth.*; import io.enmasse.controller.brokered.BrokeredController; import io.enmasse.controller.common.*; @@ -63,29 +57,6 @@ private Main(ControllerOptions options) throws Exception { public void start(Future startPromise) { AddressSpaceApi addressSpaceApi = new ConfigMapAddressSpaceApi(controllerClient); - if (!options.isMultitenant() && !kubernetes.hasService("messaging")) { - AddressSpaceType type = new StandardAddressSpaceType(); - AddressSpace.Builder builder = new AddressSpace.Builder() - .setName("default") - .setNamespace(kubernetes.getNamespace()) - .setType(type) - .setAuthenticationService(new AuthenticationService.Builder() - .setType(CodecV1.resolveAuthServiceType(System.getenv())) - .build()) - .setPlan(type.getDefaultPlan()); - - CertProvider certProvider = options.certSecret().map(SecretCertProvider::new).orElse(null); - - options.messagingHost().ifPresent(host -> - appendEndpoint(certProvider, "messaging", "messaging", host)); - options.mqttHost().ifPresent(host -> - appendEndpoint(certProvider, "mqtt", "mqtt", host)); - options.consoleHost().ifPresent(host -> - appendEndpoint(certProvider, "console", "console", host)); - addressSpaceApi.createAddressSpace(builder.build()); - } - - UserDatabase userDb = null; if (options.isEnableApiAuth()) { userDb = SecretUserDatabase.create(controllerClient, options.namespace(), options.userDbSecretName()); @@ -98,7 +69,7 @@ public void start(Future startPromise) { deployVerticles(startPromise, new Deployment(new AuthController(certManager, addressSpaceApi)), - new Deployment(new Controller(controllerClient, addressSpaceApi, kubernetes, resolverFactory, options.isMultitenant(), userDb, Arrays.asList(standardController, brokeredController))), + new Deployment(new Controller(controllerClient, addressSpaceApi, kubernetes, resolverFactory, userDb, Arrays.asList(standardController, brokeredController))), // new Deployment(new AMQPServer(kubernetes.getNamespace(), addressSpaceApi, options.port())), new Deployment(new HTTPServer(addressSpaceApi, options.certDir(), options.osbAuth().orElse(null), userDb), new DeploymentOptions().setWorker(true))); } diff --git a/address-controller/src/test/java/io/enmasse/controller/ControllerTest.java b/address-controller/src/test/java/io/enmasse/controller/ControllerTest.java index e464c2d1a2c..ed3d3ddcff4 100644 --- a/address-controller/src/test/java/io/enmasse/controller/ControllerTest.java +++ b/address-controller/src/test/java/io/enmasse/controller/ControllerTest.java @@ -19,7 +19,6 @@ import io.enmasse.address.model.types.brokered.BrokeredAddressSpaceType; import io.enmasse.address.model.types.standard.StandardAddressSpaceType; import io.enmasse.controller.auth.UserDatabase; -import io.enmasse.controller.brokered.BrokeredController; import io.enmasse.controller.common.AddressSpaceController; import io.enmasse.controller.common.Kubernetes; import io.enmasse.controller.common.NoneAuthenticationServiceResolver; @@ -70,7 +69,7 @@ public void teardown() { @Test public void testController(TestContext context) throws Exception { - Controller controller = new Controller(client, testApi, kubernetes, (a) -> new NoneAuthenticationServiceResolver("localhost", 1234), true, new DummyUserDb(), Arrays.asList(spaceController)); + Controller controller = new Controller(client, testApi, kubernetes, (a) -> new NoneAuthenticationServiceResolver("localhost", 1234), new DummyUserDb(), Arrays.asList(spaceController)); vertx.deployVerticle(controller, context.asyncAssertSuccess()); diff --git a/systemtests/scripts/run_test_component.sh b/systemtests/scripts/run_test_component.sh index 760e72711ea..59d98db4775 100755 --- a/systemtests/scripts/run_test_component.sh +++ b/systemtests/scripts/run_test_component.sh @@ -31,7 +31,7 @@ function setup_test() { DEPLOY_ARGS=( "-y" "-n" "$OPENSHIFT_PROJECT" "-u" "$OPENSHIFT_USER" "-m" "$OPENSHIFT_URL" "-a" "none standard" ) if [ "$OPENSHIFT_MULTITENANT" == true ]; then - DEPLOY_ARGS+=( "-p" "MULTITENANT=true" ) + DEPLOY_ARGS+=( "-o" "multi" ) fi $ENMASSE_DIR/deploy-openshift.sh "${DEPLOY_ARGS[@]}" diff --git a/templates/include/address-controller.jsonnet b/templates/include/address-controller.jsonnet index 11b8e24544e..d0d9bfc5f76 100644 --- a/templates/include/address-controller.jsonnet +++ b/templates/include/address-controller.jsonnet @@ -45,7 +45,7 @@ local common = import "common.jsonnet"; external_service:: self.common_service("address-controller-external", "LoadBalancer", {}), - deployment(image_repo, multitenant, template_config, ca_secret, cert_secret, enable_auth):: + deployment(image_repo, template_config, ca_secret, cert_secret, enable_auth):: { "apiVersion": "extensions/v1beta1", "kind": "Deployment", @@ -110,10 +110,6 @@ local common = import "common.jsonnet"; "image": image_repo, "name": "address-controller", "env": [{ - "name": "MULTITENANT", - "value": multitenant, - - }, { "name": "CA_DIR", "value": "/ca-cert" }, { diff --git a/templates/include/enmasse-kubernetes.jsonnet b/templates/include/enmasse-kubernetes.jsonnet index f8954e59d68..b4894b52fb0 100644 --- a/templates/include/enmasse-kubernetes.jsonnet +++ b/templates/include/enmasse-kubernetes.jsonnet @@ -12,7 +12,7 @@ local images = import "images.jsonnet"; "apiVersion": "v1", "kind": "List", "items": [ templateConfig.generate(with_kafka), - addressController.deployment(images.address_controller, "false", "enmasse-template-config", "enmasse-ca", "address-controller-cert", "false"), + addressController.deployment(images.address_controller, "enmasse-template-config", "enmasse-ca", "address-controller-cert", "false"), common.empty_secret("address-controller-userdb"), restapiRoute.ingress(""), addressController.internal_service ] diff --git a/templates/include/enmasse-template.jsonnet b/templates/include/enmasse-template.jsonnet index b8669ce62b2..0c9f73de252 100644 --- a/templates/include/enmasse-template.jsonnet +++ b/templates/include/enmasse-template.jsonnet @@ -22,7 +22,7 @@ local images = import "images.jsonnet"; storage.template(true, true), standardInfra.generate(with_kafka), brokeredInfra.template, - addressController.deployment("${ADDRESS_CONTROLLER_REPO}", "${MULTITENANT}", "", "${ENMASSE_CA_SECRET}", "${ADDRESS_CONTROLLER_CERT_SECRET}", "${ADDRESS_CONTROLLER_ENABLE_API_AUTH}"), + addressController.deployment("${ADDRESS_CONTROLLER_REPO}", "", "${ENMASSE_CA_SECRET}", "${ADDRESS_CONTROLLER_CERT_SECRET}", "${ADDRESS_CONTROLLER_ENABLE_API_AUTH}"), common.empty_secret("address-controller-userdb"), addressController.internal_service, restapiRoute.route("${RESTAPI_HOSTNAME}") ], @@ -31,11 +31,6 @@ local images = import "images.jsonnet"; "name": "RESTAPI_HOSTNAME", "description": "The hostname to use for the exposed route for the REST API" }, - { - "name": "MULTITENANT", - "description": "If set to true, the address controller will deploy infrastructure to separate namespaces", - "value": "false" - }, { "name": "ADDRESS_CONTROLLER_REPO", "description": "The docker image to use for the address controller", diff --git a/templates/install/common.sh b/templates/install/common.sh index 12ae7ee8d55..591e7d38a3d 100755 --- a/templates/install/common.sh +++ b/templates/install/common.sh @@ -30,6 +30,30 @@ function random_string() { LC_CTYPE=C head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 } +function create_address_space() { + local CMD=$1 + local name=$2 + local namespace=$3 + + payload="{ \\\"kind\\\":\\\"AddressSpace\\\", \\\"apiVersion\\\": \\\"enmasse.io/v1\\\", \\\"metadata\\\": { \\\"name\\\": \\\"$name\\\", \\\"namespace\\\": \\\"$namespace\\\" }, \\\"spec\\\": { \\\"type\\\": \\\"standard\\\" } }" + + runcmd "cat <