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 <[email protected]> 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();
