You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by dr...@apache.org on 2017/06/29 15:35:57 UTC
[15/50] [abbrv] brooklyn-server git commit: Refactoring of kubernetes
location to use KubernetesPod entity
Refactoring of kubernetes location to use KubernetesPod entity
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/422d78da
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/422d78da
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/422d78da
Branch: refs/heads/master
Commit: 422d78da0e63c10c4816f0570277e9a9b2e00419
Parents: eb94f08
Author: Andrew Donald Kennedy <an...@cloudsoftcorp.com>
Authored: Sat Jan 28 03:14:37 2017 +0000
Committer: Andrew Donald Kennedy <an...@cloudsoftcorp.com>
Committed: Fri May 19 14:01:20 2017 +0100
----------------------------------------------------------------------
.../kubernetes/entity/KubernetesPod.java | 84 ++++++++-
.../kubernetes/entity/KubernetesResource.java | 12 ++
.../kubernetes/location/KubernetesLocation.java | 185 +++++++++++--------
.../location/KubernetesLocationConfig.java | 73 +-------
.../KubernetesLocationYamlLiveTest.java | 148 ++++++++-------
5 files changed, 301 insertions(+), 201 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/422d78da/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/entity/KubernetesPod.java
----------------------------------------------------------------------
diff --git a/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/entity/KubernetesPod.java b/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/entity/KubernetesPod.java
index ae9bdb3..475f941 100644
--- a/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/entity/KubernetesPod.java
+++ b/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/entity/KubernetesPod.java
@@ -1,10 +1,92 @@
package io.cloudsoft.amp.containerservice.kubernetes.entity;
+import java.util.List;
+import java.util.Map;
+
import org.apache.brooklyn.api.entity.ImplementedBy;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.BasicConfigInheritance;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.config.MapConfigKey;
+import org.apache.brooklyn.core.sensor.Sensors;
+
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.reflect.TypeToken;
import io.cloudsoft.amp.containerservice.dockercontainer.DockerContainer;
import io.cloudsoft.amp.containerservice.kubernetes.location.KubernetesLocationConfig;
@ImplementedBy(KubernetesPodImpl.class)
-public interface KubernetesPod extends DockerContainer, KubernetesLocationConfig {
+public interface KubernetesPod extends DockerContainer {
+
+ ConfigKey<String> NAMESPACE = KubernetesLocationConfig.NAMESPACE;
+
+ ConfigKey<String> POD = ConfigKeys.builder(String.class)
+ .name("pod")
+ .description("The name of the pod")
+ .constraint(Predicates.<String>notNull())
+ .build();
+
+ @SuppressWarnings("serial")
+ ConfigKey<List<String>> PERSISTENT_VOLUMES = ConfigKeys.builder(new TypeToken<List<String>>() {})
+ .name("persistentVolumes")
+ .description("Persistent volumes used by the pod")
+ .constraint(Predicates.<List<String>>notNull())
+ .build();
+
+ ConfigKey<String> DEPLOYMENT = ConfigKeys.builder(String.class)
+ .name("deployment")
+ .description("The name of the service the deployed pod will use")
+ .constraint(Predicates.<String>notNull())
+ .build();
+
+ ConfigKey<Integer> REPLICAS = ConfigKeys.builder(Integer.class)
+ .name("replicas")
+ .description("Number of replicas in the pod")
+ .constraint(Predicates.notNull())
+ .defaultValue(1)
+ .build();
+
+ @SuppressWarnings("serial")
+ ConfigKey<Map<String, String>> SECRETS = ConfigKeys.builder(new TypeToken<Map<String, String>>() {})
+ .name("secrets")
+ .description("Secrets to be added to the pod")
+ .build();
+
+ @SuppressWarnings("serial")
+ ConfigKey<Map<String, String>> LIMITS = ConfigKeys.builder(new TypeToken<Map<String, String>>() {})
+ .name("limits")
+ .description("Container resource limits for the pod")
+ .build();
+
+ ConfigKey<Boolean> PRIVILEGED = ConfigKeys.builder(Boolean.class)
+ .name("privileged")
+ .description("Whether the container is privileged")
+ .defaultValue(false)
+ .build();
+
+ MapConfigKey<Object> METADATA = new MapConfigKey.Builder<Object>(Object.class, "metadata")
+ .description("Metadata to set on the pod")
+ .defaultValue(ImmutableMap.<String, Object>of())
+ .typeInheritance(BasicConfigInheritance.DEEP_MERGE)
+ .runtimeInheritance(BasicConfigInheritance.NOT_REINHERITED_ELSE_DEEP_MERGE)
+ .build();
+
+ AttributeSensor<String> KUBERNETES_DEPLOYMENT = Sensors.builder(String.class, "kubernetes.deployment")
+ .description("Deployment resources run in")
+ .build();
+
+ AttributeSensor<String> KUBERNETES_NAMESPACE = Sensors.builder(String.class, "kubernetes.namespace")
+ .description("Namespace that resources run in")
+ .build();
+
+ AttributeSensor<String> KUBERNETES_SERVICE = Sensors.builder(String.class, "kubernetes.service")
+ .description("Service that exposes the deployment")
+ .build();
+
+ AttributeSensor<String> KUBERNETES_POD = Sensors.builder(String.class, "kubernetes.pod")
+ .description("Pod running the deployment")
+ .build();
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/422d78da/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/entity/KubernetesResource.java
----------------------------------------------------------------------
diff --git a/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/entity/KubernetesResource.java b/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/entity/KubernetesResource.java
index 3274cb2..320c924 100644
--- a/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/entity/KubernetesResource.java
+++ b/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/entity/KubernetesResource.java
@@ -25,4 +25,16 @@ public interface KubernetesResource extends SoftwareProcess {
.description("Kubernetes resource name")
.build();
+ AttributeSensor<String> KUBERNETES_NAMESPACE = KubernetesPod.KUBERNETES_NAMESPACE;
+
+ String POD = "Pod";
+ String DEPLOYMENT = "Deployment";
+ String REPLICA_SET = "ReplicaSet";
+ String CONFIG_MAP = "ConfigMap";
+ String PERSISTENT_VOLUME = "PersistentVolume";
+ String SECRET = "Secret";
+ String SERVICE = "Service";
+ String REPLICATION_CONTROLLER = "ReplicationController";
+ String NAMESPACE = "Namespace";
+
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/422d78da/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesLocation.java
----------------------------------------------------------------------
diff --git a/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesLocation.java b/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesLocation.java
index 1cf9545..cd44f37 100644
--- a/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesLocation.java
+++ b/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesLocation.java
@@ -3,6 +3,7 @@ package io.cloudsoft.amp.containerservice.kubernetes.location;
import java.io.InputStream;
import java.net.InetAddress;
import java.nio.charset.Charset;
+import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -17,6 +18,7 @@ import org.apache.brooklyn.api.location.NoMachinesAvailableException;
import org.apache.brooklyn.api.location.PortRange;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.api.sensor.EnricherSpec;
+import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.location.AbstractLocation;
@@ -49,6 +51,7 @@ 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;
import com.google.common.collect.ImmutableList;
@@ -63,6 +66,7 @@ import com.google.common.net.HostAndPort;
import io.cloudsoft.amp.containerservice.ThreadedRepeater;
import io.cloudsoft.amp.containerservice.dockercontainer.DockerContainer;
import io.cloudsoft.amp.containerservice.dockerlocation.DockerJcloudsLocation;
+import io.cloudsoft.amp.containerservice.kubernetes.entity.KubernetesPod;
import io.cloudsoft.amp.containerservice.kubernetes.entity.KubernetesResource;
import io.fabric8.kubernetes.api.model.Container;
import io.fabric8.kubernetes.api.model.ContainerBuilder;
@@ -98,7 +102,7 @@ import io.fabric8.kubernetes.api.model.extensions.DeploymentStatus;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientException;
-public class KubernetesLocation extends AbstractLocation implements MachineProvisioningLocation<MachineLocation>, CloudLocationConfig, KubernetesLocationConfig {
+public class KubernetesLocation extends AbstractLocation implements MachineProvisioningLocation<MachineLocation>, KubernetesLocationConfig {
/*
* TODO
@@ -173,6 +177,14 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
if (isKubernetesResource(entity)) {
return createKubernetesResourceLocation(entity, setup);
} else {
+ // Heuristic for determining whether KubernetesPod is simply a container
+ if (isKubernetesPod(entity) &&
+ entity.config().get(DockerContainer.IMAGE_NAME) == null &&
+ entity.config().get(DockerContainer.INBOUND_TCP_PORTS) == null &&
+ entity.config().get(KubernetesPod.POD) == null &&
+ entity.getChildren().size() > 0) {
+ return null;
+ }
return createKubernetesContainerLocation(entity, setup);
}
}
@@ -188,10 +200,10 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
}
protected void deleteKubernetesContainerLocation(Entity entity, MachineLocation machine) {
- final String namespace = entity.sensors().get(KUBERNETES_NAMESPACE);
- final String deployment = entity.sensors().get(KUBERNETES_DEPLOYMENT);
- final String pod = entity.sensors().get(KUBERNETES_POD);
- final String service = entity.sensors().get(KUBERNETES_SERVICE);
+ final String namespace = entity.sensors().get(KubernetesPod.KUBERNETES_NAMESPACE);
+ final String deployment = entity.sensors().get(KubernetesPod.KUBERNETES_DEPLOYMENT);
+ final String pod = entity.sensors().get(KubernetesPod.KUBERNETES_POD);
+ final String service = entity.sensors().get(KubernetesPod.KUBERNETES_SERVICE);
undeploy(namespace, deployment, pod);
@@ -215,7 +227,7 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
}
protected void deleteKubernetesResourceLocation(Entity entity) {
- final String namespace = entity.sensors().get(KUBERNETES_NAMESPACE);
+ final String namespace = entity.sensors().get(KubernetesPod.KUBERNETES_NAMESPACE);
final String resourceType = entity.sensors().get(KubernetesResource.RESOURCE_TYPE);
final String resourceName = entity.sensors().get(KubernetesResource.RESOURCE_NAME);
@@ -227,21 +239,21 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
protected boolean handleResourceDelete(String resourceType, String resourceName, String namespace) {
try {
switch (resourceType) {
- case "Deployment":
+ case KubernetesResource.DEPLOYMENT:
return client.extensions().deployments().inNamespace(namespace).withName(resourceName).delete();
- case "ReplicaSet":
+ case KubernetesResource.REPLICA_SET:
return client.extensions().replicaSets().inNamespace(namespace).withName(resourceName).delete();
- case "ConfigMap":
+ case KubernetesResource.CONFIG_MAP:
return client.configMaps().inNamespace(namespace).withName(resourceName).delete();
- case "PersistentVolume":
+ case KubernetesResource.PERSISTENT_VOLUME:
return client.persistentVolumes().withName(resourceName).delete();
- case "Secret":
+ case KubernetesResource.SECRET:
return client.secrets().inNamespace(namespace).withName(resourceName).delete();
- case "Service":
+ case KubernetesResource.SERVICE:
return client.services().inNamespace(namespace).withName(resourceName).delete();
- case "ReplicationController":
+ case KubernetesResource.REPLICATION_CONTROLLER:
return client.replicationControllers().inNamespace(namespace).withName(resourceName).delete();
- case "Namespace":
+ case KubernetesResource.NAMESPACE:
return client.namespaces().withName(resourceName).delete();
}
} catch (KubernetesClientException kce) {
@@ -330,7 +342,7 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
String namespace = metadata.getMetadata().getNamespace();
LOG.debug("Resource {} (type {}) deployed to {}", resourceName, resourceType, namespace);
- entity.sensors().set(KUBERNETES_NAMESPACE, namespace);
+ entity.sensors().set(KubernetesPod.KUBERNETES_NAMESPACE, namespace);
entity.sensors().set(KubernetesResource.RESOURCE_NAME, resourceName);
entity.sensors().set(KubernetesResource.RESOURCE_TYPE, resourceType);
@@ -343,7 +355,7 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
SshMachineLocation machine = getManagementContext().getLocationManager().createLocation(locationSpec);
- if (resourceType.equals("Service")) {
+ if (resourceType.equals(KubernetesResource.SERVICE)) {
Service service = getService(namespace, resourceName);
registerPortMappings(machine, entity, service);
@@ -353,17 +365,17 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
}
protected boolean findResourceAddress(LocationSpec<SshMachineLocation> locationSpec, Entity entity, HasMetadata metadata, String resourceType, String resourceName, String namespace) {
- if (resourceType.equals("Deployment") || resourceType.equals("ReplicationController") || resourceType.equals("Pod")) {
+ if (resourceType.equals(KubernetesResource.DEPLOYMENT) || resourceType.equals(KubernetesResource.REPLICATION_CONTROLLER) || resourceType.equals(KubernetesResource.POD)) {
Map<String, String> labels = MutableMap.of();
- if (resourceType.equals("Deployment")) {
+ if (resourceType.equals(KubernetesResource.DEPLOYMENT)) {
Deployment deployment = (Deployment) metadata;
labels = deployment.getSpec().getTemplate().getMetadata().getLabels();
- } else if (resourceType.equals("ReplicationController")) {
+ } else if (resourceType.equals(KubernetesResource.REPLICATION_CONTROLLER)) {
ReplicationController replicationController = (ReplicationController) metadata;
labels = replicationController.getSpec().getTemplate().getMetadata().getLabels();
}
- Pod pod = resourceType.equals("Pod") ? getPod(namespace, resourceName) : getPod(namespace, labels);
- entity.sensors().set(KubernetesLocationConfig.KUBERNETES_POD, pod.getMetadata().getName());
+ Pod pod = resourceType.equals(KubernetesResource.POD) ? getPod(namespace, resourceName) : getPod(namespace, labels);
+ entity.sensors().set(KubernetesPod.KUBERNETES_POD, pod.getMetadata().getName());
InetAddress node = Networking.getInetAddressWithFixedName(pod.getSpec().getNodeName());
String podAddress = pod.getStatus().getPodIP();
@@ -372,7 +384,7 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
locationSpec.configure(SshMachineLocation.PRIVATE_ADDRESSES, ImmutableSet.of(podAddress));
return true;
- } else if (resourceType.equals("Service")) {
+ } else if (resourceType.equals(KubernetesResource.SERVICE)) {
getService(namespace, resourceName);
Endpoints endpoints = client.endpoints().inNamespace(namespace).withName(resourceName).get();
@@ -385,7 +397,7 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
try {
Pod pod = getPod(namespace, podName);
- entity.sensors().set(KubernetesLocationConfig.KUBERNETES_POD, podName);
+ entity.sensors().set(KubernetesPod.KUBERNETES_POD, podName);
InetAddress node = Networking.getInetAddressWithFixedName(pod.getSpec().getNodeName());
locationSpec.configure("address", node);
@@ -400,22 +412,22 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
}
protected MachineLocation createKubernetesContainerLocation(Entity entity, ConfigBag setup) {
- String deploymentName = findDeploymentName(entity, setup);
- Integer replicas = setup.get(REPLICAS);
- List<String> volumes = setup.get(KubernetesLocationConfig.PERSISTENT_VOLUMES);
- Map<String, String> secrets = setup.get(KubernetesLocationConfig.SECRETS);
- Map<String, String> limits = setup.get(KubernetesLocationConfig.LIMITS);
- Boolean privileged = setup.get(KubernetesLocationConfig.PRIVILEGED);
+ String deploymentName = lookup(KubernetesPod.DEPLOYMENT, entity, setup, entity.getId());
+ Integer replicas = lookup(KubernetesPod.REPLICAS, entity, setup);
+ List<String> volumes = lookup(KubernetesPod.PERSISTENT_VOLUMES, entity, setup);
+ Map<String, String> secrets = lookup(KubernetesPod.SECRETS, entity, setup);
+ Map<String, String> limits = lookup(KubernetesPod.LIMITS, entity, setup);
+ Boolean privileged = lookup(KubernetesPod.PRIVILEGED, entity, setup);
String imageName = findImageName(entity, setup);
Iterable<Integer> inboundPorts = findInboundPorts(entity, setup);
Map<String, String> env = findEnvironmentVariables(entity, setup, imageName);
- Map<String, String> metadata = findMetadata(entity, deploymentName);
+ Map<String, String> metadata = findMetadata(entity, setup, deploymentName);
if (volumes != null) {
createPersistentVolumes(volumes);
}
- Namespace namespace = createOrGetNamespace(setup.get(NAMESPACE), setup.get(CREATE_NAMESPACE));
+ Namespace namespace = createOrGetNamespace(lookup(NAMESPACE, entity, setup), setup.get(CREATE_NAMESPACE));
if (secrets != null) {
createSecrets(namespace.getMetadata().getName(), secrets);
@@ -426,10 +438,10 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
Service service = exposeService(namespace.getMetadata().getName(), metadata, deploymentName, inboundPorts);
Pod pod = getPod(namespace.getMetadata().getName(), metadata);
- entity.sensors().set(KubernetesLocationConfig.KUBERNETES_NAMESPACE, namespace.getMetadata().getName());
- entity.sensors().set(KubernetesLocationConfig.KUBERNETES_DEPLOYMENT, deploymentName);
- entity.sensors().set(KubernetesLocationConfig.KUBERNETES_POD, pod.getMetadata().getName());
- entity.sensors().set(KubernetesLocationConfig.KUBERNETES_SERVICE, service.getMetadata().getName());
+ entity.sensors().set(KubernetesPod.KUBERNETES_NAMESPACE, namespace.getMetadata().getName());
+ entity.sensors().set(KubernetesPod.KUBERNETES_DEPLOYMENT, deploymentName);
+ entity.sensors().set(KubernetesPod.KUBERNETES_POD, pod.getMetadata().getName());
+ entity.sensors().set(KubernetesPod.KUBERNETES_SERVICE, service.getMetadata().getName());
LocationSpec<SshMachineLocation> locationSpec = prepareLocationSpec(entity, setup, namespace, deploymentName, service, pod);
SshMachineLocation machine = getManagementContext().getLocationManager().createLocation(locationSpec);
@@ -497,10 +509,6 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
entity.enrichers().add(EnricherSpec.create(OnPublicNetworkEnricher.class).configure(OnPublicNetworkEnricher.MAP_MATCHING, "kubernetes.[a-zA-Z0-9][a-zA-Z0-9-_]*.port"));
}
- protected String findDeploymentName(Entity entity, ConfigBag setup) {
- return Optional.fromNullable(setup.get(KubernetesLocationConfig.DEPLOYMENT)).or(entity.getId());
- }
-
protected synchronized Namespace createOrGetNamespace(final String name, Boolean create) {
Namespace namespace = client.namespaces().withName(name).get();
ExitCondition namespaceReady = new ExitCondition() {
@@ -573,14 +581,13 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
String json = String.format("{\"https://index.docker.io/v1/\":{\"auth\":\"%s\"}}", auth);
String base64encoded = BaseEncoding.base64().encode(json.getBytes(Charset.defaultCharset()));
- secret = client.secrets().inNamespace(namespace)
- .create(new SecretBuilder()
+ secret = new SecretBuilder()
.withNewMetadata()
.withName(secretName)
.endMetadata()
.withType("kubernetes.io/dockercfg")
.withData(ImmutableMap.of(".dockercfg", base64encoded))
- .build());
+ .build();
try {
client.secrets().inNamespace(namespace).create(secret);
} catch (KubernetesClientException e) {
@@ -642,6 +649,12 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
.withNewSpec()
.addToContainers(container)
.endSpec();
+ if (isKubernetesPod(entity)) {
+ String podName = entity.config().get(KubernetesPod.POD);
+ if (Strings.isNonBlank(podName)) {
+ podTemplateSpecBuilder.editOrNewMetadata().withName(podName).endMetadata();
+ }
+ }
if (secrets != null) {
for (String secretName : secrets.keySet()) {
podTemplateSpecBuilder.withNewSpec()
@@ -797,53 +810,55 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
protected Entity validateCallerContext(ConfigBag setup) {
// Lookup entity flags
Object callerContext = setup.get(LocationConfigKeys.CALLER_CONTEXT);
- if (callerContext == null || !(callerContext instanceof Entity)) {
+ if (callerContext instanceof Entity) {
+ return (Entity) callerContext;
+ } else {
throw new IllegalStateException("Invalid caller context: " + callerContext);
}
- return (Entity) callerContext;
}
protected Entity validateCallerContext(MachineLocation machine) {
// Lookup entity flags
Object callerContext = machine.config().get(LocationConfigKeys.CALLER_CONTEXT);
- if (callerContext == null || !(callerContext instanceof Entity)) {
+ if (callerContext instanceof Entity) {
+ return (Entity) callerContext;
+ } else {
throw new IllegalStateException("Invalid caller context: " + callerContext);
}
- return (Entity) callerContext;
}
-
- protected Map<String, String> findMetadata(Entity entity, String value) {
- Map<String, String> metadata = Maps.newHashMap();
- if (!isDockerContainer(entity)) {
- metadata.put(SSHABLE_CONTAINER, value);
+ protected Map<String, String> findMetadata(Entity entity, ConfigBag setup, String value) {
+ Map<String, String> podMetadata = Maps.newLinkedHashMap();
+ if (isDockerContainer(entity)) {
+ podMetadata.put(IMMUTABLE_CONTAINER_KEY, value);
} else {
- metadata.put(IMMUTABLE_CONTAINER_KEY, value);
+ podMetadata.put(SSHABLE_CONTAINER, value);
}
- return metadata;
+
+ Map<String, Object> metadata = MutableMap.<String, Object>builder()
+ .putAll(MutableMap.copyOf(setup.get(KubernetesPod.METADATA)))
+ .putAll(MutableMap.copyOf(entity.config().get(KubernetesPod.METADATA)))
+ .putAll(podMetadata)
+ .build();
+ return Maps.transformValues(metadata, Functions.toStringFunction());
}
/**
- * Appends the config's "env" with the {@code CLOUDSOFT_ROOT_PASSWORD} env if appropriate.
+ * Sets the {@code CLOUDSOFT_ROOT_PASSWORD} variable in the container environment if appropriate.
* This is (approximately) the same behaviour as the {@link DockerJcloudsLocation} used for
* Swarm.
*
- * Side-effects the {@code config}, to set the loginPassword if one is auto-generated.
- *
- * TODO Longer term, we'll add a config key to the `DockerContainer` entity for env variables.
- * We'll inject those when launching the container (and will do the same in
- * `DockerJcloudsLocation` for Swarm). What would the precedence be? Would we prefer the
- * entity's config over the location's (or vice versa)? I think the entity's would take
- * precedence, as a location often applies to a whole app so we might well want to override
- * or augment it for specific entities.
+ * Side-effects the location {@code config} to set the {@link KubernetesLocationConfig#LOGIN_USER_PASSWORD loginUser.password}
+ * if one is auto-generated. Note that this injected value overrides any other settings configured for the
+ * container environment.
*/
- protected Map<String, String> findEnvironmentVariables(Entity entity, ConfigBag config, String imageName) {
- String loginUser = config.get(LOGIN_USER);
- String loginPassword = config.get(LOGIN_USER_PASSWORD);
+ protected Map<String, String> findEnvironmentVariables(Entity entity, ConfigBag setup, String imageName) {
+ String loginUser = setup.get(LOGIN_USER);
+ String loginPassword = setup.get(LOGIN_USER_PASSWORD);
Map<String, String> injections = Maps.newLinkedHashMap();
// Check if login credentials should be injected
- Boolean injectLoginCredentials = config.get(INJECT_LOGIN_CREDENTIAL);
+ Boolean injectLoginCredentials = setup.get(INJECT_LOGIN_CREDENTIAL);
if (injectLoginCredentials == null) {
for (String regex : IMAGE_DESCRIPTION_REGEXES_REQUIRING_INJECTED_LOGIN_CREDS) {
if (imageName != null && imageName.matches(regex)) {
@@ -856,11 +871,11 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
if (Boolean.TRUE.equals(injectLoginCredentials)) {
if ((Strings.isBlank(loginUser) || "root".equals(loginUser))) {
loginUser = "root";
- config.configure(LOGIN_USER, loginUser);
+ setup.configure(LOGIN_USER, loginUser);
if (Strings.isBlank(loginPassword)) {
loginPassword = Identifiers.makeRandomPassword(12);
- config.configure(LOGIN_USER_PASSWORD, loginPassword);
+ setup.configure(LOGIN_USER_PASSWORD, loginPassword);
}
injections.put("CLOUDSOFT_ROOT_PASSWORD", loginPassword);
@@ -868,9 +883,9 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
}
Map<String,Object> rawEnv = MutableMap.<String, Object>builder()
- .putAll(injections)
- .putAll(MutableMap.copyOf(config.get(ENV)))
+ .putAll(MutableMap.copyOf(setup.get(ENV)))
.putAll(MutableMap.copyOf(entity.config().get(DockerContainer.CONTAINER_ENVIRONMENT)))
+ .putAll(injections)
.build();
return Maps.transformValues(rawEnv, Functions.toStringFunction());
}
@@ -918,16 +933,40 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
}
protected boolean isDockerContainer(Entity entity) {
- return entity.getEntityType().getName().equalsIgnoreCase(DockerContainer.class.getName());
+ return implementsInterface(entity, DockerContainer.class);
+ }
+
+ protected boolean isKubernetesPod(Entity entity) {
+ return implementsInterface(entity, KubernetesPod.class);
}
protected boolean isKubernetesResource(Entity entity) {
- return entity.getEntityType().getName().equalsIgnoreCase(KubernetesResource.class.getName());
+ return implementsInterface(entity, KubernetesResource.class);
+ }
+
+ protected boolean implementsInterface(Entity entity, Class<?> type) {
+ return Iterables.tryFind(Arrays.asList(entity.getClass().getInterfaces()), Predicates.instanceOf(type)).isPresent();
}
@Override
public MachineProvisioningLocation<MachineLocation> newSubLocation(Map<?, ?> newFlags) {
- return null;
+ throw new UnsupportedOperationException();
+ }
+
+ /** @see {@link #lookup(ConfigKey, Entity, ConfigBag, Object)} */
+ protected <T> T lookup(ConfigKey<T> config, Entity entity, ConfigBag setup) {
+ return lookup(config, entity, setup, null);
+ }
+
+ /**
+ * Looks up {@link ConfigKey configuration} with the entity value taking precedence over the
+ * location, and returning a default value (normally {@literal null}) if neither is present.
+ */
+ protected <T> T lookup(ConfigKey<T> config, Entity entity, ConfigBag setup, T defaultValue) {
+ Optional<T> entityValue = Optional.fromNullable(entity.config().get(config));
+ Optional<T> locationValue = Optional.fromNullable(setup.get(config));
+
+ return entityValue.or(locationValue).or(defaultValue);
}
protected void waitForExitCondition(ExitCondition exitCondition) {
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/422d78da/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesLocationConfig.java
----------------------------------------------------------------------
diff --git a/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesLocationConfig.java b/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesLocationConfig.java
index c2e9d89..fdb658b 100644
--- a/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesLocationConfig.java
+++ b/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesLocationConfig.java
@@ -1,23 +1,21 @@
package io.cloudsoft.amp.containerservice.kubernetes.location;
-import java.util.List;
import java.util.Map;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.location.LocationConfigKeys;
import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.util.core.flags.SetFromFlag;
import org.apache.brooklyn.util.time.Duration;
+import org.apache.brooklyn.core.location.cloud.CloudLocationConfig;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableMap;
import com.google.common.reflect.TypeToken;
-public interface KubernetesLocationConfig {
+public interface KubernetesLocationConfig extends CloudLocationConfig {
- @SetFromFlag("endpoint")
ConfigKey<String> MASTER_URL = LocationConfigKeys.CLOUD_ENDPOINT;
ConfigKey<String> CA_CERT_DATA = ConfigKeys.builder(String.class)
@@ -110,16 +108,11 @@ public interface KubernetesLocationConfig {
.build();
@SuppressWarnings("serial")
- ConfigKey<List<String>> PERSISTENT_VOLUMES = ConfigKeys.builder(new TypeToken<List<String>>() {})
- .name("persistentVolumes")
- .description("Set up persistent volumes.")
- .constraint(Predicates.<List<String>>notNull())
- .build();
-
- ConfigKey<String> DEPLOYMENT = ConfigKeys.builder(String.class)
- .name("deployment")
- .description("Deployment where resources will live.")
- .constraint(Predicates.<String>notNull())
+ ConfigKey<Map<String, ?>> ENV = ConfigKeys.builder(new TypeToken<Map<String, ?>>() {})
+ .name("env")
+ .description("Environment variables to inject when starting the container")
+ .defaultValue(ImmutableMap.<String, Object>of())
+ .constraint(Predicates.<Map<String, ?>>notNull())
.build();
ConfigKey<String> IMAGE = ConfigKeys.builder(String.class)
@@ -138,41 +131,7 @@ public interface KubernetesLocationConfig {
.description("Regular expression for the OS version to load")
.build();
- @SuppressWarnings("serial")
- ConfigKey<Map<String, ?>> ENV = ConfigKeys.newConfigKey(
- new TypeToken<Map<String, ?>>() {},
- "env",
- "Environment variables to inject when starting the container",
- ImmutableMap.<String, Object>of());
-
- ConfigKey<Integer> REPLICAS = ConfigKeys.builder(Integer.class)
- .name("replicas")
- .description("Number of replicas of the pod")
- .constraint(Predicates.notNull())
- .defaultValue(1)
- .build();
-
- @SuppressWarnings("serial")
- ConfigKey<Map<String, String>> SECRETS = ConfigKeys.builder(
- new TypeToken<Map<String, String>>() {})
- .name("secrets")
- .description("Kubernetes secrets to be added to the pod")
- .build();
-
- @SuppressWarnings("serial")
- ConfigKey<Map<String, String>> LIMITS = ConfigKeys.builder(
- new TypeToken<Map<String, String>>() {})
- .name("limits")
- .description("Kubernetes resource limits")
- .build();
-
- ConfigKey<Boolean> PRIVILEGED = ConfigKeys.builder(Boolean.class)
- .name("privileged")
- .description("Whether Kubernetes should allow privileged containers")
- .defaultValue(false)
- .build();
-
- ConfigKey<KubernetesClientRegistry> KUBERNETES_CLIENT_REGISTRY = ConfigKeys.builder(KubernetesClientRegistry.class)
+ ConfigKey<KubernetesClientRegistry> KUBERNETES_CLIENT_REGISTRY = ConfigKeys.builder(KubernetesClientRegistry.class)
.name("kubernetesClientRegistry")
.description("Registry/Factory for creating Kubernetes client; default is almost always fine, "
+ "except where tests want to customize behaviour")
@@ -197,21 +156,5 @@ public interface KubernetesLocationConfig {
.description("Whether to inject login credentials (if null, will infer from image choice); ignored if explicit 'loginUser.password' supplied")
.build();
- AttributeSensor<String> KUBERNETES_DEPLOYMENT = Sensors.builder(String.class, "kubernetes.deployment")
- .description("Deployment resources run in")
- .build();
-
- AttributeSensor<String> KUBERNETES_NAMESPACE = Sensors.builder(String.class, "kubernetes.namespace")
- .description("Namespace that resources run in")
- .build();
-
- AttributeSensor<String> KUBERNETES_SERVICE = Sensors.builder(String.class, "kubernetes.service")
- .description("Service that exposes the deployment")
- .build();
-
- AttributeSensor<String> KUBERNETES_POD = Sensors.builder(String.class, "kubernetes.pod")
- .description("Pod running the deployment")
- .build();
-
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/422d78da/kubernetes-location/src/test/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesLocationYamlLiveTest.java
----------------------------------------------------------------------
diff --git a/kubernetes-location/src/test/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesLocationYamlLiveTest.java b/kubernetes-location/src/test/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesLocationYamlLiveTest.java
index 962be36..d623efa 100644
--- a/kubernetes-location/src/test/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesLocationYamlLiveTest.java
+++ b/kubernetes-location/src/test/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesLocationYamlLiveTest.java
@@ -30,7 +30,6 @@ import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.entity.software.base.EmptySoftwareProcess;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess;
-import org.apache.brooklyn.entity.stock.BasicStartable;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.apache.brooklyn.util.net.Networking;
import org.apache.brooklyn.util.text.Identifiers;
@@ -43,6 +42,7 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.net.HostAndPort;
+import io.cloudsoft.amp.containerservice.dockercontainer.DockerContainer;
import io.cloudsoft.amp.containerservice.kubernetes.entity.KubernetesPod;
import io.cloudsoft.amp.containerservice.kubernetes.entity.KubernetesResource;
@@ -82,10 +82,11 @@ public class KubernetesLocationYamlLiveTest extends AbstractYamlTest {
String yaml = Joiner.on("\n").join(
locationYaml,
"services:",
- "- type: " + EmptySoftwareProcess.class.getName(),
- " brooklyn.config:",
- " provisioning.properties:",
- " " + KubernetesLocationConfig.LOGIN_USER_PASSWORD.getName() + ": " + customPassword);
+ " - type: " + EmptySoftwareProcess.class.getName(),
+ " brooklyn.config:",
+ " provisioning.properties:",
+ " " + KubernetesLocationConfig.LOGIN_USER_PASSWORD.getName() + ": " + customPassword);
+
Entity app = createStartWaitAndLogApplication(yaml);
EmptySoftwareProcess entity = Iterables.getOnlyElement(Entities.descendantsAndSelf(app, EmptySoftwareProcess.class));
@@ -101,19 +102,17 @@ public class KubernetesLocationYamlLiveTest extends AbstractYamlTest {
String yaml = Joiner.on("\n").join(
locationYaml,
"services:",
- "- type: " + VanillaSoftwareProcess.class.getName(),
- " brooklyn.parameters:",
- " - name: netcat.port",
- " type: port",
- " default: 8081",
- " brooklyn.config:",
- " install.command: |",
- " yum install -y nc",
- " launch.command: |",
- " echo $MESSAGE | nc -l $NETCAT_PORT &",
- " echo $! > $PID_FILE",
- " checkRunning.command: |",
- " true",
+ " - type: " + VanillaSoftwareProcess.class.getName(),
+ " brooklyn.parameters:",
+ " - name: netcat.port",
+ " type: port",
+ " default: 8081",
+ " brooklyn.config:",
+ " install.command: |",
+ " yum install -y nc",
+ " launch.command: |",
+ " echo $MESSAGE | nc -l $NETCAT_PORT &",
+ " echo $! > $PID_FILE",
" shell.env:",
" MESSAGE: mymessage",
" NETCAT_PORT: $brooklyn:attributeWhenReady(\"netcat.port\")",
@@ -122,6 +121,7 @@ public class KubernetesLocationYamlLiveTest extends AbstractYamlTest {
" brooklyn.config:",
" " + OnPublicNetworkEnricher.SENSORS.getName() + ":",
" - netcat.port");
+
Entity app = createStartWaitAndLogApplication(yaml);
VanillaSoftwareProcess entity = Iterables.getOnlyElement(Entities.descendantsAndSelf(app, VanillaSoftwareProcess.class));
@@ -139,29 +139,26 @@ public class KubernetesLocationYamlLiveTest extends AbstractYamlTest {
String yaml = Joiner.on("\n").join(
locationYaml,
"services:",
- "- type: " + VanillaSoftwareProcess.class.getName(),
- " name: server1",
- " brooklyn.parameters:",
- " - name: netcat.port",
- " type: port",
- " default: " + netcatPort,
- " brooklyn.config:",
- " install.command: |",
- " yum install -y nc",
- " launch.command: |",
- " echo " + message + " | nc -l " + netcatPort + " > netcat.out &",
- " echo $! > $PID_FILE",
- " checkRunning.command: |",
- " true",
- "- type: " + VanillaSoftwareProcess.class.getName(),
- " name: server2",
- " brooklyn.config:",
- " install.command: |",
- " yum install -y nc",
- " launch.command: |",
- " true",
- " checkRunning.command: |",
- " true");
+ " - type: " + VanillaSoftwareProcess.class.getName(),
+ " name: server1",
+ " brooklyn.parameters:",
+ " - name: netcat.port",
+ " type: port",
+ " default: " + netcatPort,
+ " brooklyn.config:",
+ " install.command: |",
+ " yum install -y nc",
+ " launch.command: |",
+ " echo " + message + " | nc -l " + netcatPort + " > netcat.out &",
+ " echo $! > $PID_FILE",
+ " - type: " + VanillaSoftwareProcess.class.getName(),
+ " name: server2",
+ " brooklyn.config:",
+ " install.command: |",
+ " yum install -y nc",
+ " launch.command: true",
+ " checkRunning.command: true");
+
Entity app = createStartWaitAndLogApplication(yaml);
Entities.dumpInfo(app);
@@ -191,16 +188,37 @@ public class KubernetesLocationYamlLiveTest extends AbstractYamlTest {
}
@Test(groups={"Live"})
+ public void testTomcatPod() throws Exception {
+ String yaml = Joiner.on("\n").join(
+ locationYaml,
+ "services:",
+ " - type: " + KubernetesPod.class.getName(),
+ " brooklyn.config:",
+ " docker.container.imageName: tomcat",
+ " docker.container.inboundPorts: [ \"8080\" ]");
+
+ runTomcat(yaml);
+ }
+
+ @Test(groups={"Live"})
public void testTomcatContainer() throws Exception {
String yaml = Joiner.on("\n").join(
locationYaml,
"services:",
- "- type: " + KubernetesPod.class.getName(),
- " brooklyn.config:",
- " docker.container.imageName: tomcat",
- " docker.container.inboundPorts: [ \"8080\" ]");
+ " - type: " + DockerContainer.class.getName(),
+ " brooklyn.config:",
+ " docker.container.imageName: tomcat",
+ " docker.container.inboundPorts: [ \"8080\" ]");
+
+ runTomcat(yaml);
+ }
+
+ /**
+ * Assumes that the {@link DockerContainer} entity uses port 8080.
+ */
+ protected void runTomcat(String yaml) throws Exception {
Entity app = createStartWaitAndLogApplication(yaml);
- KubernetesPod entity = Iterables.getOnlyElement(Entities.descendantsAndSelf(app, KubernetesPod.class));
+ DockerContainer entity = Iterables.getOnlyElement(Entities.descendantsAndSelf(app, DockerContainer.class));
Entities.dumpInfo(app);
String publicMapped = assertAttributeEventuallyNonNull(entity, Sensors.newStringSensor("docker.port.8080.mapped.public"));
@@ -220,7 +238,7 @@ public class KubernetesLocationYamlLiveTest extends AbstractYamlTest {
"services:",
" - type: " + KubernetesPod.class.getName(),
" brooklyn.children:",
- " - type: " + KubernetesPod.class.getName(),
+ " - type: " + DockerContainer.class.getName(),
" id: wordpress-mysql",
" name: mysql",
" brooklyn.config:",
@@ -231,7 +249,7 @@ public class KubernetesLocationYamlLiveTest extends AbstractYamlTest {
" MYSQL_ROOT_PASSWORD: \"password\"",
" provisioning.properties:",
" deployment: wordpress-mysql-" + randomId,
- " - type: " + KubernetesPod.class.getName(),
+ " - type: " + DockerContainer.class.getName(),
" id: wordpress",
" name: wordpress",
" brooklyn.config:",
@@ -239,16 +257,16 @@ public class KubernetesLocationYamlLiveTest extends AbstractYamlTest {
" docker.container.inboundPorts:",
" - \"80\"",
" docker.container.environment:",
- " WORDPRESS_DB_HOST: \"wordpress-mysql\"",
+ " WORDPRESS_DB_HOST: \"wordpress-mysql" + randomId + "\"",
" WORDPRESS_DB_PASSWORD: \"password\"",
" provisioning.properties:",
" deployment: wordpress-" + randomId);
- runWordpress(yaml);
+ runWordpress(yaml, randomId);
}
@Test(groups={"Live"})
- public void testWordpressInSeperatePods() throws Exception {
+ public void testWordpressInPods() throws Exception {
// TODO docker.container.inboundPorts doesn't accept list of ints - need to use quotes
String randomId = Identifiers.makeRandomId(4);
String yaml = Joiner.on("\n").join(
@@ -263,6 +281,8 @@ public class KubernetesLocationYamlLiveTest extends AbstractYamlTest {
" - \"3306\"",
" docker.container.environment:",
" MYSQL_ROOT_PASSWORD: \"password\"",
+ " deployment: wordpress-mysql-" + randomId,
+ " pod: wordpress-mysql-pod-" + randomId,
" - type: " + KubernetesPod.class.getName(),
" id: wordpress",
" name: wordpress",
@@ -271,31 +291,35 @@ public class KubernetesLocationYamlLiveTest extends AbstractYamlTest {
" docker.container.inboundPorts:",
" - \"80\"",
" docker.container.environment:",
- " WORDPRESS_DB_HOST: \"wordpress-mysql\"",
+ " WORDPRESS_DB_HOST: \"wordpress-mysql" + randomId + "\"",
" WORDPRESS_DB_PASSWORD: \"password\"",
- " provisioning.properties:",
- " deployment: wordpress-" + randomId);
+ " deployment: wordpress-" + randomId);
- runWordpress(yaml);
+ runWordpress(yaml, randomId);
}
/**
- * Assumes that the {@link KubernetesPod} entities have display names of "mysql" and "wordpress",
+ * Assumes that the {@link DockerContainer} entities have display names of "mysql" and "wordpress",
* and that they use ports 3306 and 80 respectively.
*/
- protected void runWordpress(String yaml) throws Exception {
+ protected void runWordpress(String yaml, String randomId) throws Exception {
Entity app = createStartWaitAndLogApplication(yaml);
Entities.dumpInfo(app);
- Iterable<KubernetesPod> containers = Entities.descendantsAndSelf(app, KubernetesPod.class);
- KubernetesPod mysql = Iterables.find(containers, EntityPredicates.displayNameEqualTo("mysql"));
- KubernetesPod wordpress = Iterables.find(containers, EntityPredicates.displayNameEqualTo("wordpress"));
+ Iterable<DockerContainer> containers = Entities.descendantsAndSelf(app, DockerContainer.class);
+ DockerContainer mysql = Iterables.find(containers, EntityPredicates.displayNameEqualTo("mysql"));
+ DockerContainer wordpress = Iterables.find(containers, EntityPredicates.displayNameEqualTo("wordpress"));
String mysqlPublicPort = assertAttributeEventuallyNonNull(mysql, Sensors.newStringSensor("docker.port.3306.mapped.public"));
assertReachableEventually(HostAndPort.fromString(mysqlPublicPort));
+ assertAttributeEqualsEventually(mysql, KubernetesPod.KUBERNETES_POD, "wordpress-mysql-pod-" + randomId);
+ assertAttributeEqualsEventually(mysql, KubernetesPod.KUBERNETES_NAMESPACE, "amp");
+ assertAttributeEqualsEventually(mysql, KubernetesPod.KUBERNETES_SERVICE, "wordpress-mysql-" + randomId);
String wordpressPublicPort = assertAttributeEventuallyNonNull(wordpress, Sensors.newStringSensor("docker.port.80.mapped.public"));
assertReachableEventually(HostAndPort.fromString(wordpressPublicPort));
+ assertAttributeEqualsEventually(wordpress, KubernetesPod.KUBERNETES_NAMESPACE, "amp");
+ assertAttributeEqualsEventually(wordpress, KubernetesPod.KUBERNETES_SERVICE, "wordpress-" + randomId);
// TODO more assertions (e.g. wordpress can successfully reach the database)
}
@@ -309,7 +333,7 @@ public class KubernetesLocationYamlLiveTest extends AbstractYamlTest {
" brooklyn.config:",
" docker.container.imageName: tomcat",
" docker.container.inboundPorts:",
- " - \"8080\"",
+ " - \"8080\"",
" shell.env:",
" CLUSTER_ID: \"id\"",
" CLUSTER_TOKEN: \"token\"");
@@ -343,7 +367,7 @@ public class KubernetesLocationYamlLiveTest extends AbstractYamlTest {
assertEntityHealthy(entity);
assertAttributeEqualsEventually(entity, KubernetesResource.RESOURCE_NAME, "nginx-replication-controller");
assertAttributeEqualsEventually(entity, KubernetesResource.RESOURCE_TYPE, "ReplicationController");
- assertAttributeEqualsEventually(entity, KubernetesLocationConfig.KUBERNETES_NAMESPACE, "default");
+ assertAttributeEqualsEventually(entity, KubernetesResource.KUBERNETES_NAMESPACE, "default");
assertAttributeEventually(entity, SoftwareProcess.ADDRESS, and(notNull(), not(equalTo("0.0.0.0"))));
assertAttributeEventually(entity, SoftwareProcess.SUBNET_ADDRESS, and(notNull(), not(equalTo("0.0.0.0"))));
}