You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2020/07/08 13:18:19 UTC

[brooklyn-server] 09/20: make namespaces optional for deployments

This is an automated email from the ASF dual-hosted git repository.

heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git

commit 0e61978d6b6524970d605cf9de97f7c27e26ba9e
Author: Alex Heneveld <al...@cloudsoftcorp.com>
AuthorDate: Tue Jul 7 17:45:31 2020 +0100

    make namespaces optional for deployments
    
    and tidy tests not to have warnings
---
 .../location/kubernetes/KubernetesLocation.java    | 60 +++++++++++++++++++---
 .../kubernetes/KubernetesLocationYamlLiveTest.java | 30 +++++++----
 2 files changed, 74 insertions(+), 16 deletions(-)

diff --git a/locations/container/src/main/java/org/apache/brooklyn/container/location/kubernetes/KubernetesLocation.java b/locations/container/src/main/java/org/apache/brooklyn/container/location/kubernetes/KubernetesLocation.java
index d6023a0..a0466b1 100644
--- a/locations/container/src/main/java/org/apache/brooklyn/container/location/kubernetes/KubernetesLocation.java
+++ b/locations/container/src/main/java/org/apache/brooklyn/container/location/kubernetes/KubernetesLocation.java
@@ -21,13 +21,14 @@ package org.apache.brooklyn.container.location.kubernetes;
 import java.io.InputStream;
 import java.net.InetAddress;
 import java.nio.charset.Charset;
-import java.util.*;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.concurrent.TimeUnit;
 
-import javax.annotation.Nullable;
-
-import io.fabric8.kubernetes.api.model.*;
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.api.location.MachineLocation;
@@ -62,6 +63,7 @@ import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.core.config.ResolvingConfigBag;
 import org.apache.brooklyn.util.core.internal.ssh.SshTool;
 import org.apache.brooklyn.util.core.text.TemplateProcessor;
+import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.exceptions.ReferenceWithError;
 import org.apache.brooklyn.util.net.Networking;
 import org.apache.brooklyn.util.repeat.Repeater;
@@ -75,7 +77,6 @@ import org.slf4j.LoggerFactory;
 import com.google.common.base.Functions;
 import com.google.common.base.Joiner;
 import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
 import com.google.common.base.Predicates;
 import com.google.common.base.Stopwatch;
 import com.google.common.base.Throwables;
@@ -89,9 +90,40 @@ import com.google.common.collect.Sets;
 import com.google.common.io.BaseEncoding;
 import com.google.common.net.HostAndPort;
 
+import io.fabric8.kubernetes.api.model.Container;
+import io.fabric8.kubernetes.api.model.ContainerBuilder;
+import io.fabric8.kubernetes.api.model.ContainerPort;
+import io.fabric8.kubernetes.api.model.ContainerPortBuilder;
+import io.fabric8.kubernetes.api.model.EndpointAddress;
+import io.fabric8.kubernetes.api.model.EndpointSubset;
+import io.fabric8.kubernetes.api.model.Endpoints;
+import io.fabric8.kubernetes.api.model.EnvVar;
+import io.fabric8.kubernetes.api.model.EnvVarBuilder;
+import io.fabric8.kubernetes.api.model.HasMetadata;
+import io.fabric8.kubernetes.api.model.LabelSelector;
+import io.fabric8.kubernetes.api.model.LabelSelectorBuilder;
+import io.fabric8.kubernetes.api.model.Namespace;
+import io.fabric8.kubernetes.api.model.NamespaceBuilder;
+import io.fabric8.kubernetes.api.model.PersistentVolume;
+import io.fabric8.kubernetes.api.model.PersistentVolumeBuilder;
+import io.fabric8.kubernetes.api.model.Pod;
+import io.fabric8.kubernetes.api.model.PodList;
+import io.fabric8.kubernetes.api.model.PodTemplateSpec;
+import io.fabric8.kubernetes.api.model.PodTemplateSpecBuilder;
+import io.fabric8.kubernetes.api.model.QuantityBuilder;
+import io.fabric8.kubernetes.api.model.ReplicationController;
+import io.fabric8.kubernetes.api.model.ResourceRequirements;
+import io.fabric8.kubernetes.api.model.ResourceRequirementsBuilder;
+import io.fabric8.kubernetes.api.model.Secret;
+import io.fabric8.kubernetes.api.model.SecretBuilder;
+import io.fabric8.kubernetes.api.model.Service;
+import io.fabric8.kubernetes.api.model.ServiceBuilder;
+import io.fabric8.kubernetes.api.model.ServicePort;
+import io.fabric8.kubernetes.api.model.ServicePortBuilder;
 import io.fabric8.kubernetes.api.model.apps.Deployment;
 import io.fabric8.kubernetes.api.model.apps.DeploymentBuilder;
 import io.fabric8.kubernetes.api.model.apps.DeploymentStatus;
+import io.fabric8.kubernetes.client.DefaultKubernetesClient;
 import io.fabric8.kubernetes.client.KubernetesClient;
 import io.fabric8.kubernetes.client.KubernetesClientException;
 
@@ -311,7 +343,22 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
         InputStream processedResource = Streams.newInputStreamWithContents(processedContents);
 
 
-        try (KubernetesClient client = getClient()) {
+        try (KubernetesClient clientUnnamespaced = getClient()) {
+            Namespace namespaceFromConfig = null;
+            Boolean shouldCreate = setup.get(CREATE_NAMESPACE);
+            try {
+                namespaceFromConfig = createOrGetNamespace(lookup(NAMESPACE, entity, setup), shouldCreate);
+            } catch (Exception e) {
+                // unable to create
+                if (Boolean.TRUE.equals(shouldCreate)) {
+                    throw Exceptions.propagate(e);
+                }
+                LOG.debug("Unable to create/get namespace; ignoring, but may fail subsequently: " + e, e);
+            }
+            final KubernetesClient client = 
+                namespaceFromConfig!=null ?
+                    ((DefaultKubernetesClient)clientUnnamespaced).inNamespace(namespaceFromConfig.getMetadata().getName())
+                : clientUnnamespaced;
             final List<HasMetadata> result = client.load(processedResource).createOrReplace();
 
             ExitCondition exitCondition = new ExitCondition() {
@@ -331,6 +378,7 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
             };
             waitForExitCondition(exitCondition);
 
+            // TODO only returns info on the first item :|
             HasMetadata metadata = result.get(0);
             String resourceType = metadata.getKind();
             String resourceName = metadata.getMetadata().getName();
diff --git a/locations/container/src/test/java/org/apache/brooklyn/container/location/kubernetes/KubernetesLocationYamlLiveTest.java b/locations/container/src/test/java/org/apache/brooklyn/container/location/kubernetes/KubernetesLocationYamlLiveTest.java
index a3030b1..b9019e9 100644
--- a/locations/container/src/test/java/org/apache/brooklyn/container/location/kubernetes/KubernetesLocationYamlLiveTest.java
+++ b/locations/container/src/test/java/org/apache/brooklyn/container/location/kubernetes/KubernetesLocationYamlLiveTest.java
@@ -46,6 +46,7 @@ import org.apache.brooklyn.container.entity.docker.DockerContainer;
 import org.apache.brooklyn.container.entity.kubernetes.KubernetesPod;
 import org.apache.brooklyn.container.entity.kubernetes.KubernetesResource;
 import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.entity.Dumper;
 import org.apache.brooklyn.core.entity.Entities;
 import org.apache.brooklyn.core.entity.EntityPredicates;
 import org.apache.brooklyn.core.location.Machines;
@@ -59,6 +60,7 @@ import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.util.core.config.ConfigBag;
 import org.apache.brooklyn.util.net.Networking;
 import org.apache.brooklyn.util.text.Identifiers;
+import org.apache.brooklyn.util.text.Strings;
 import org.apache.commons.lang3.StringUtils;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
@@ -89,12 +91,20 @@ public class KubernetesLocationYamlLiveTest extends AbstractYamlTest {
     public void setUp() throws Exception {
         super.setUp();
 
+        String config = "    {}";
+
+        if (Strings.isNonBlank(KUBERNETES_ENDPOINT)) {
+            // if the above is set, we use it.  otherwise use ~/.kube/config
+            config = Joiner.on("\n").join(
+                    "    " + KubernetesLocationConfig.MASTER_URL.getName() + ": \"" + KUBERNETES_ENDPOINT + "\"",
+                    "    " + (StringUtils.isBlank(IDENTITY) ? "" : "identity: " + IDENTITY),
+                    "    " + (StringUtils.isBlank(CREDENTIAL) ? "" : "credential: " + CREDENTIAL));
+        }
+        
         locationYaml = Joiner.on("\n").join(
                 "location:",
                 "  kubernetes:",
-                "    " + KubernetesLocationConfig.MASTER_URL.getName() + ": \"" + KUBERNETES_ENDPOINT + "\"",
-                "    " + (StringUtils.isBlank(IDENTITY) ? "" : "identity: " + IDENTITY),
-                "    " + (StringUtils.isBlank(CREDENTIAL) ? "" : "credential: " + CREDENTIAL));
+                config);
     }
 
     @Test(groups = {"Live"})
@@ -182,7 +192,7 @@ public class KubernetesLocationYamlLiveTest extends AbstractYamlTest {
                 "      checkRunning.command: true");
 
         Entity app = createStartWaitAndLogApplication(yaml);
-        Entities.dumpInfo(app);
+        Dumper.dumpInfo(app);
 
         Entity server1 = Iterables.find(Entities.descendantsAndSelf(app), EntityPredicates.displayNameEqualTo("server1"));
         Entity server2 = Iterables.find(Entities.descendantsAndSelf(app), EntityPredicates.displayNameEqualTo("server2"));
@@ -265,7 +275,7 @@ public class KubernetesLocationYamlLiveTest extends AbstractYamlTest {
         Entity app = createStartWaitAndLogApplication(yaml);
         T entity = Iterables.getOnlyElement(Entities.descendantsAndSelf(app, type));
 
-        Entities.dumpInfo(app);
+        Dumper.dumpInfo(app);
         String publicMapped = assertAttributeEventuallyNonNull(entity, Sensors.newStringSensor("docker.port.8080.mapped.public"));
         HostAndPort publicPort = HostAndPort.fromString(publicMapped);
 
@@ -383,7 +393,7 @@ public class KubernetesLocationYamlLiveTest extends AbstractYamlTest {
      */
     protected void runWordpress(String yaml, String randomId) throws Exception {
         Entity app = createStartWaitAndLogApplication(yaml);
-        Entities.dumpInfo(app);
+        Dumper.dumpInfo(app);
 
         Iterable<DockerContainer> containers = Entities.descendantsAndSelf(app, DockerContainer.class);
         DockerContainer mysql = Iterables.find(containers, EntityPredicates.displayNameEqualTo("mysql"));
@@ -441,7 +451,7 @@ public class KubernetesLocationYamlLiveTest extends AbstractYamlTest {
     protected <T extends Entity> void checkPod(Entity app, Class<T> type) {
         T container = Iterables.getOnlyElement(Entities.descendantsAndSelf(app, type));
 
-        Entities.dumpInfo(app);
+        Dumper.dumpInfo(app);
 
         String publicMapped = assertAttributeEventuallyNonNull(container, Sensors.newStringSensor("docker.port.8080.mapped.public"));
         HostAndPort publicPort = HostAndPort.fromString(publicMapped);
@@ -468,7 +478,7 @@ public class KubernetesLocationYamlLiveTest extends AbstractYamlTest {
     protected <T extends Entity> void checkNginxResource(Entity app, Class<T> type) {
         T entity = Iterables.getOnlyElement(Entities.descendantsAndSelf(app, type));
 
-        Entities.dumpInfo(app);
+        Dumper.dumpInfo(app);
 
         assertEntityHealthy(entity);
         assertAttributeEqualsEventually(entity, KubernetesResource.RESOURCE_NAME, "nginx-replication-controller");
@@ -502,7 +512,7 @@ public class KubernetesLocationYamlLiveTest extends AbstractYamlTest {
         assertEntityHealthy(nginxReplicationController);
         assertEntityHealthy(nginxService);
 
-        Entities.dumpInfo(app);
+        Dumper.dumpInfo(app);
 
         Integer httpPort = assertAttributeEventuallyNonNull(nginxService, Sensors.newIntegerSensor("kubernetes.http.port"));
         assertEquals(httpPort, Integer.valueOf(80));
@@ -519,7 +529,7 @@ public class KubernetesLocationYamlLiveTest extends AbstractYamlTest {
     }
 
     public KubernetesClient getClient(Entity entity) {
-        MachineProvisioningLocation location = entity.sensors().get(SoftwareProcess.PROVISIONING_LOCATION);
+        MachineProvisioningLocation<?> location = entity.sensors().get(SoftwareProcess.PROVISIONING_LOCATION);
         if (location instanceof KubernetesLocation) {
             KubernetesLocation kubernetes = (KubernetesLocation) location;
             ConfigBag config = kubernetes.config().getBag();