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:58 UTC
[16/50] [abbrv] brooklyn-server git commit: Add
KubernetesMachineLocation interface and implementations
Add KubernetesMachineLocation interface and implementations
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/fcb0db07
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/fcb0db07
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/fcb0db07
Branch: refs/heads/master
Commit: fcb0db07b5afa3de7718975977349b5144e1a389
Parents: 90123e4
Author: Andrew Donald Kennedy <an...@cloudsoftcorp.com>
Authored: Wed Feb 1 19:32:36 2017 +0000
Committer: Andrew Donald Kennedy <an...@cloudsoftcorp.com>
Committed: Fri May 19 14:01:20 2017 +0100
----------------------------------------------------------------------
.../kubernetes/entity/KubernetesPod.java | 2 +
.../KubernetesEmptyMachineLocation.java | 68 ++++++++++++++++++
.../kubernetes/location/KubernetesLocation.java | 75 ++++++++++++++------
.../location/KubernetesMachineLocation.java | 27 +++++++
.../location/KubernetesSshMachineLocation.java | 27 +++++++
.../KubernetesLocationYamlLiveTest.java | 39 +++++++++-
6 files changed, 215 insertions(+), 23 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/fcb0db07/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 4c334ec..35da4b8 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
@@ -77,4 +77,6 @@ public interface KubernetesPod extends DockerContainer {
AttributeSensor<String> KUBERNETES_POD = Sensors.builder(String.class, "kubernetes.pod")
.description("Pod running the deployment")
.build();
+
+ String EMPTY = "Empty";
}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/fcb0db07/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesEmptyMachineLocation.java
----------------------------------------------------------------------
diff --git a/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesEmptyMachineLocation.java b/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesEmptyMachineLocation.java
new file mode 100644
index 0000000..ffda23f
--- /dev/null
+++ b/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesEmptyMachineLocation.java
@@ -0,0 +1,68 @@
+package io.cloudsoft.amp.containerservice.kubernetes.location;
+
+import java.net.InetAddress;
+import java.util.Set;
+
+import org.apache.brooklyn.api.location.MachineDetails;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.OsDetails;
+import org.apache.brooklyn.core.location.AbstractLocation;
+import org.apache.brooklyn.util.net.Networking;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * A {@link MachineLocation} represemnting a Kubernetes resource that does not support SSH access.
+ *
+ * @see {@link KubernetesSshMachineLocation}
+ */
+public class KubernetesEmptyMachineLocation extends AbstractLocation implements KubernetesMachineLocation {
+
+ @Override
+ public String getHostname() {
+ return getResourceName();
+ }
+
+ @Override
+ public Set<String> getPublicAddresses() {
+ return ImmutableSet.of("0.0.0.0");
+ }
+
+ @Override
+ public Set<String> getPrivateAddresses() {
+ return ImmutableSet.of("0.0.0.0");
+ }
+
+ @Override
+ public InetAddress getAddress() {
+ return Networking.getInetAddressWithFixedName("0.0.0.0");
+ }
+
+ @Override
+ public OsDetails getOsDetails() {
+ return null;
+ // throw new UnsupportedOperationException("No OS details for empty KubernetesMachineLocation");
+ }
+
+ @Override
+ public MachineDetails getMachineDetails() {
+ return null;
+ // throw new UnsupportedOperationException("No machine details for empty KubernetesMachineLocation");
+ }
+
+ @Override
+ public String getResourceName() {
+ return config().get(KUBERNETES_RESOURCE_NAME);
+ }
+
+ @Override
+ public String getResourceType() {
+ return config().get(KUBERNETES_RESOURCE_TYPE);
+ }
+
+ @Override
+ public String getNamespace() {
+ return config().get(KUBERNETES_NAMESPACE);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/fcb0db07/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 28f193c..f5123b9 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
@@ -128,6 +128,7 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
public static final String CLOUDSOFT_APPLICATION_ID = "cloudsoft.io/application-id";
public static final String KUBERNETES_DOCKERCFG = "kubernetes.io/dockercfg";
+ public static final String PHASE_AVAILABLE = "Available";
public static final String PHASE_TERMINATING = "Terminating";
public static final String PHASE_ACTIVE = "Active";
@@ -185,15 +186,41 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
if (isKubernetesResource(entity)) {
return createKubernetesResourceLocation(entity, setup);
} else {
+ // Heuristic for determining whether KubernetesPod is simply a parent entity
+ if (isKubernetesPod(entity) &&
+ entity.config().get(DockerContainer.IMAGE_NAME) == null &&
+ entity.config().get(DockerContainer.INBOUND_TCP_PORTS) == null &&
+ entity.getChildren().size() > 0) {
+ return createEmptyKubernetesMachineLocation(entity);
+ }
return createKubernetesContainerLocation(entity, setup);
}
}
+ /** @deprecated This mechanism will be removed in future releases */
+ @Deprecated
+ public KubernetesEmptyMachineLocation createEmptyKubernetesMachineLocation(Entity entity) {
+ LOG.warn("IMPORTANT: Deprecated behaviour: Use of KubernetesPod as a parent entity is deprecated and support will be removed in future versions");
+
+ LocationSpec<KubernetesEmptyMachineLocation> locationSpec = LocationSpec.create(KubernetesEmptyMachineLocation.class)
+ .configure(KubernetesLocationConfig.CALLER_CONTEXT, entity)
+ .configure(KubernetesMachineLocation.KUBERNETES_RESOURCE_TYPE, KubernetesPod.EMPTY)
+ .configure(KubernetesMachineLocation.KUBERNETES_RESOURCE_NAME, entity.getId());
+
+ KubernetesEmptyMachineLocation machine = getManagementContext().getLocationManager().createLocation(locationSpec);
+
+ return machine;
+ }
+
@Override
public void release(MachineLocation machine) {
Entity entity = validateCallerContext(machine);
if (isKubernetesResource(entity)) {
- deleteKubernetesResourceLocation(entity);
+ if (machine instanceof KubernetesEmptyMachineLocation && KubernetesPod.EMPTY.equals(machine.config().get(KubernetesMachineLocation.KUBERNETES_RESOURCE_TYPE))) {
+ // Nothing to do, the location does not represent a Kubernetes resource
+ } else {
+ deleteKubernetesResourceLocation(entity);
+ }
} else {
deleteKubernetesContainerLocation(entity, machine);
}
@@ -346,25 +373,27 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
entity.sensors().set(KubernetesResource.RESOURCE_NAME, resourceName);
entity.sensors().set(KubernetesResource.RESOURCE_TYPE, resourceType);
- LocationSpec<SshMachineLocation> locationSpec = LocationSpec.create(SshMachineLocation.class)
- .configure(CALLER_CONTEXT, setup.get(CALLER_CONTEXT));
+ LocationSpec<? extends KubernetesMachineLocation> locationSpec = LocationSpec.create(KubernetesSshMachineLocation.class);
if (!findResourceAddress(locationSpec, entity, metadata, resourceType, resourceName, namespace)) {
LOG.info("Resource {} with type {} has no associated address", resourceName, resourceType);
- locationSpec.configure("address", "0.0.0.0");
+ locationSpec = LocationSpec.create(KubernetesEmptyMachineLocation.class);
}
+ locationSpec.configure(CALLER_CONTEXT, setup.get(CALLER_CONTEXT))
+ .configure(KubernetesMachineLocation.KUBERNETES_NAMESPACE, namespace)
+ .configure(KubernetesMachineLocation.KUBERNETES_RESOURCE_NAME, resourceName)
+ .configure(KubernetesMachineLocation.KUBERNETES_RESOURCE_TYPE, resourceType);
- SshMachineLocation machine = getManagementContext().getLocationManager().createLocation(locationSpec);
+ KubernetesMachineLocation machine = getManagementContext().getLocationManager().createLocation(locationSpec);
- if (resourceType.equals(KubernetesResource.SERVICE)) {
+ if (resourceType.equals(KubernetesResource.SERVICE) && machine instanceof KubernetesSshMachineLocation) {
Service service = getService(namespace, resourceName);
- registerPortMappings(machine, entity, service);
-
+ registerPortMappings((KubernetesSshMachineLocation) machine, entity, service);
}
return machine;
}
- protected boolean findResourceAddress(LocationSpec<SshMachineLocation> locationSpec, Entity entity, HasMetadata metadata, String resourceType, String resourceName, String namespace) {
+ protected boolean findResourceAddress(LocationSpec<? extends KubernetesMachineLocation> locationSpec, Entity entity, HasMetadata metadata, String resourceType, String resourceName, String namespace) {
if (resourceType.equals(KubernetesResource.DEPLOYMENT) || resourceType.equals(KubernetesResource.REPLICATION_CONTROLLER) || resourceType.equals(KubernetesResource.POD)) {
Map<String, String> labels = MutableMap.of();
if (resourceType.equals(KubernetesResource.DEPLOYMENT)) {
@@ -443,8 +472,12 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
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);
+ LocationSpec<KubernetesSshMachineLocation> locationSpec = prepareSshableLocationSpec(entity, setup, namespace, deploymentName, service, pod)
+ .configure(KubernetesMachineLocation.KUBERNETES_NAMESPACE, namespace.getMetadata().getName())
+ .configure(KubernetesMachineLocation.KUBERNETES_RESOURCE_NAME, deploymentName)
+ .configure(KubernetesMachineLocation.KUBERNETES_RESOURCE_TYPE, KubernetesResource.DEPLOYMENT);
+
+ KubernetesSshMachineLocation machine = getManagementContext().getLocationManager().createLocation(locationSpec);
registerPortMappings(machine, entity, service);
if (!isDockerContainer(entity)) {
waitForSshable(machine, Duration.FIVE_MINUTES);
@@ -482,11 +515,11 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
}
}
- protected void registerPortMappings(SshMachineLocation machine, Entity entity, Service service) {
+ protected void registerPortMappings(KubernetesSshMachineLocation machine, Entity entity, Service service) {
PortForwardManager portForwardManager = (PortForwardManager) getManagementContext().getLocationRegistry()
.getLocationManaged(PortForwardManagerLocationResolver.PFM_GLOBAL_SPEC);
List<ServicePort> ports = service.getSpec().getPorts();
- String publicHostText = machine.getSshHostAndPort().getHostText();
+ String publicHostText = ((SshMachineLocation) machine).getSshHostAndPort().getHostText();
LOG.debug("Recording port-mappings for container {} of {}: {}", new Object[] { machine, this, ports });
for (ServicePort port : ports) {
@@ -741,10 +774,10 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
return client.services().inNamespace(namespace).withName(serviceName).get();
}
- protected LocationSpec<SshMachineLocation> prepareLocationSpec(Entity entity, ConfigBag setup, Namespace namespace, String deploymentName, Service service, Pod pod) {
+ protected LocationSpec<KubernetesSshMachineLocation> prepareSshableLocationSpec(Entity entity, ConfigBag setup, Namespace namespace, String deploymentName, Service service, Pod pod) {
InetAddress node = Networking.getInetAddressWithFixedName(pod.getSpec().getNodeName());
String podAddress = pod.getStatus().getPodIP();
- LocationSpec<SshMachineLocation> locationSpec = LocationSpec.create(SshMachineLocation.class)
+ LocationSpec<KubernetesSshMachineLocation> locationSpec = LocationSpec.create(KubernetesSshMachineLocation.class)
.configure("address", node)
.configure(SshMachineLocation.PRIVATE_ADDRESSES, ImmutableSet.of(podAddress))
.configure(CALLER_CONTEXT, setup.get(CALLER_CONTEXT));
@@ -775,13 +808,13 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
for (final String persistentVolume : volumes) {
PersistentVolume volume = new PersistentVolumeBuilder()
.withNewMetadata()
- .withName(persistentVolume)
- .withLabels(ImmutableMap.of("type", "local")) // TODO make it configurable
+ .withName(persistentVolume)
+ .withLabels(ImmutableMap.of("type", "local")) // TODO make it configurable
.endMetadata()
.withNewSpec()
- .addToCapacity("storage", new QuantityBuilder().withAmount("20").build()) // TODO make it configurable
- .addToAccessModes("ReadWriteOnce") // TODO make it configurable
- .withNewHostPath().withPath("/tmp/pv-1").endHostPath() // TODO make it configurable
+ .addToCapacity("storage", new QuantityBuilder().withAmount("20").build()) // TODO make it configurable
+ .addToAccessModes("ReadWriteOnce") // TODO make it configurable
+ .withNewHostPath().withPath("/tmp/pv-1").endHostPath() // TODO make it configurable
.endSpec()
.build();
client.persistentVolumes().create(volume);
@@ -790,7 +823,7 @@ public class KubernetesLocation extends AbstractLocation implements MachineProvi
public Boolean call() {
PersistentVolume pv = client.persistentVolumes().withName(persistentVolume).get();
return pv != null && pv.getStatus() != null
- && pv.getStatus().getPhase().equals("Available");
+ && pv.getStatus().getPhase().equals(PHASE_AVAILABLE);
}
@Override
public String getFailureMessage() {
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/fcb0db07/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesMachineLocation.java
----------------------------------------------------------------------
diff --git a/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesMachineLocation.java b/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesMachineLocation.java
new file mode 100644
index 0000000..9c620bb
--- /dev/null
+++ b/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesMachineLocation.java
@@ -0,0 +1,27 @@
+package io.cloudsoft.amp.containerservice.kubernetes.location;
+
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+
+public interface KubernetesMachineLocation extends MachineLocation {
+
+ ConfigKey<String> KUBERNETES_NAMESPACE = ConfigKeys.builder(String.class, "kubernetes.namespace")
+ .description("Namespace for the KubernetesMachineLocation")
+ .build();
+
+ ConfigKey<String> KUBERNETES_RESOURCE_NAME = ConfigKeys.builder(String.class, "kubernetes.name")
+ .description("Name of the resource represented by the KubernetesMachineLocation")
+ .build();
+
+ ConfigKey<String> KUBERNETES_RESOURCE_TYPE = ConfigKeys.builder(String.class, "kubernetes.type")
+ .description("Type of the resource represented by the KubernetesMachineLocation")
+ .build();
+
+ public String getResourceName();
+
+ public String getResourceType();
+
+ public String getNamespace();
+
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/fcb0db07/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesSshMachineLocation.java
----------------------------------------------------------------------
diff --git a/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesSshMachineLocation.java b/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesSshMachineLocation.java
new file mode 100644
index 0000000..97fabbb
--- /dev/null
+++ b/kubernetes-location/src/main/java/io/cloudsoft/amp/containerservice/kubernetes/location/KubernetesSshMachineLocation.java
@@ -0,0 +1,27 @@
+package io.cloudsoft.amp.containerservice.kubernetes.location;
+
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
+
+/**
+ * A {@link MachineLocation} represemnting a Kubernetes resource that allows SSH access.
+ *
+ * @see {@link KubernetesSshMachineLocation}
+ */
+public class KubernetesSshMachineLocation extends SshMachineLocation implements KubernetesMachineLocation {
+
+ @Override
+ public String getResourceName() {
+ return config().get(KUBERNETES_RESOURCE_NAME);
+ }
+
+ @Override
+ public String getResourceType() {
+ return config().get(KUBERNETES_RESOURCE_TYPE);
+ }
+
+ @Override
+ public String getNamespace() {
+ return config().get(KUBERNETES_NAMESPACE);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/fcb0db07/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 9654d6d..f783630 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
@@ -259,9 +259,8 @@ public class KubernetesLocationYamlLiveTest extends AbstractYamlTest {
return entity;
}
-
@Test(groups={"Live"})
- public void testWordpressInContainers() throws Exception {
+ public void testWordpressInContainersWithStartableParent() throws Exception {
// TODO docker.container.inboundPorts doesn't accept list of ints - need to use quotes
String randomId = Identifiers.makeRandomLowercaseId(4);
String yaml = Joiner.on("\n").join(
@@ -297,6 +296,42 @@ public class KubernetesLocationYamlLiveTest extends AbstractYamlTest {
}
@Test(groups={"Live"})
+ public void testWordpressInContainersWithPodParent() throws Exception {
+ // TODO docker.container.inboundPorts doesn't accept list of ints - need to use quotes
+ String randomId = Identifiers.makeRandomLowercaseId(4);
+ String yaml = Joiner.on("\n").join(
+ locationYaml,
+ "services:",
+ " - type: " + KubernetesPod.class.getName(),
+ " brooklyn.children:",
+ " - type: " + DockerContainer.class.getName(),
+ " id: wordpress-mysql",
+ " name: mysql",
+ " brooklyn.config:",
+ " docker.container.imageName: mysql:5.6",
+ " docker.container.inboundPorts:",
+ " - \"3306\"",
+ " docker.container.environment:",
+ " MYSQL_ROOT_PASSWORD: \"password\"",
+ " provisioning.properties:",
+ " deployment: wordpress-mysql-" + randomId,
+ " - type: " + DockerContainer.class.getName(),
+ " id: wordpress",
+ " name: wordpress",
+ " brooklyn.config:",
+ " docker.container.imageName: wordpress:4.4-apache",
+ " docker.container.inboundPorts:",
+ " - \"80\"",
+ " docker.container.environment:",
+ " WORDPRESS_DB_HOST: \"wordpress-mysql" + randomId + "\"",
+ " WORDPRESS_DB_PASSWORD: \"password\"",
+ " provisioning.properties:",
+ " deployment: wordpress-" + randomId);
+
+ runWordpress(yaml, randomId);
+ }
+
+ @Test(groups={"Live"})
public void testWordpressInPods() throws Exception {
// TODO docker.container.inboundPorts doesn't accept list of ints - need to use quotes
String randomId = Identifiers.makeRandomLowercaseId(4);