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:12 UTC
[brooklyn-server] 02/20: Deploy basic Helm based cluster
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 a88d8ec6ce003afba46b482f6c6bd9d065187041
Author: Duncan Grant <du...@cloudsoft.io>
AuthorDate: Tue Jun 16 11:34:51 2020 +0100
Deploy basic Helm based cluster
---
.../brooklyn/container/entity/helm/HelmDriver.java | 25 ++++
.../brooklyn/container/entity/helm/HelmEntity.java | 49 +++++++
.../container/entity/helm/HelmEntityImpl.java | 71 ++++++++++
.../container/entity/helm/HelmSshDriver.java | 156 +++++++++++++++++++++
.../container/entity/helm/HelmEntityLiveTest.java | 62 ++++++++
5 files changed, 363 insertions(+)
diff --git a/locations/container/src/main/java/org/apache/brooklyn/container/entity/helm/HelmDriver.java b/locations/container/src/main/java/org/apache/brooklyn/container/entity/helm/HelmDriver.java
new file mode 100644
index 0000000..52dbbc8
--- /dev/null
+++ b/locations/container/src/main/java/org/apache/brooklyn/container/entity/helm/HelmDriver.java
@@ -0,0 +1,25 @@
+/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.container.entity.helm;
+
+import org.apache.brooklyn.entity.software.base.SoftwareProcessDriver;
+
+import java.util.concurrent.Callable;
+
+public interface HelmDriver extends SoftwareProcessDriver {
+ Callable getCallable(String command);
+}
diff --git a/locations/container/src/main/java/org/apache/brooklyn/container/entity/helm/HelmEntity.java b/locations/container/src/main/java/org/apache/brooklyn/container/entity/helm/HelmEntity.java
new file mode 100644
index 0000000..e34499f
--- /dev/null
+++ b/locations/container/src/main/java/org/apache/brooklyn/container/entity/helm/HelmEntity.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.container.entity.helm;
+
+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.ConfigKeys;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.entity.software.base.SoftwareProcess;
+
+@ImplementedBy(HelmEntityImpl.class)
+public interface HelmEntity extends SoftwareProcess {
+
+ public static final ConfigKey<String> REPO_NAME = ConfigKeys.newStringConfigKey(
+ "repo.name",
+ "Name to add repo under");
+
+ public static final ConfigKey<String> REPO_URL = ConfigKeys.newStringConfigKey(
+ "repo.url",
+ "Repo url");
+
+ public static final ConfigKey<String> HELM_TEMPLATE = ConfigKeys.newStringConfigKey(
+ "helm.template",
+ "Template name or url");
+
+ public static final ConfigKey<String> HELM_TEMPLATE_INSTALL_NAME = ConfigKeys.newStringConfigKey(
+ "helm.template.install.name",
+ "Kuberentes deployment name");
+
+ AttributeSensor<String> STATUS = Sensors.newStringSensor("helm.status",
+ "The results of a status call");
+}
diff --git a/locations/container/src/main/java/org/apache/brooklyn/container/entity/helm/HelmEntityImpl.java b/locations/container/src/main/java/org/apache/brooklyn/container/entity/helm/HelmEntityImpl.java
new file mode 100644
index 0000000..72ed9f5
--- /dev/null
+++ b/locations/container/src/main/java/org/apache/brooklyn/container/entity/helm/HelmEntityImpl.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.container.entity.helm;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.entity.brooklynnode.BrooklynClusterImpl;
+import org.apache.brooklyn.entity.brooklynnode.BrooklynNode;
+import org.apache.brooklyn.entity.software.base.SoftwareProcessDriver;
+import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
+import org.apache.brooklyn.feed.function.FunctionFeed;
+import org.apache.brooklyn.feed.function.FunctionPollConfig;
+import org.apache.brooklyn.util.time.Duration;
+
+import javax.annotation.Nullable;
+import java.util.concurrent.Callable;
+
+public class HelmEntityImpl extends SoftwareProcessImpl implements HelmEntity {
+ @Override
+ public Class getDriverInterface() {
+ return HelmDriver.class;
+ }
+
+ @Override
+ public void init() {
+ super.init();
+ }
+
+ @Override
+ protected void connectSensors() {
+ super.connectSensors();
+ connectServiceUpIsRunning();
+
+ HelmDriver driver = getDriver();
+ Callable status = driver.getCallable("status");
+ FunctionPollConfig pollConfig = new FunctionPollConfig<Object, String>(STATUS)
+ .callable(status);
+
+ addFeed(FunctionFeed.builder()
+ .entity(this)
+ .poll(pollConfig)
+ .period(Duration.FIVE_SECONDS)
+ .build());
+ }
+
+ @Override
+ protected void disconnectSensors() {
+ super.disconnectSensors();
+ disconnectServiceUpIsRunning();
+ }
+
+ @Override
+ public HelmDriver getDriver() {
+ return (HelmDriver) super.getDriver();
+ }
+}
diff --git a/locations/container/src/main/java/org/apache/brooklyn/container/entity/helm/HelmSshDriver.java b/locations/container/src/main/java/org/apache/brooklyn/container/entity/helm/HelmSshDriver.java
new file mode 100644
index 0000000..c8c6728
--- /dev/null
+++ b/locations/container/src/main/java/org/apache/brooklyn/container/entity/helm/HelmSshDriver.java
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.container.entity.helm;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.entity.java.JavaSoftwareProcessSshDriver;
+import org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessDriver;
+import org.apache.brooklyn.entity.software.base.SoftwareProcess;
+import org.apache.brooklyn.entity.software.base.SoftwareProcessDriver;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
+import org.apache.brooklyn.util.core.internal.ssh.process.ProcessTool;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+public class HelmSshDriver extends AbstractSoftwareProcessDriver implements HelmDriver{
+
+ public HelmSshDriver(EntityLocal entity, Location location) {
+ super(entity, location);
+ }
+
+ @Override
+ public boolean isRunning() {
+ String helm_name_install_name = getEntity().getConfig(HelmEntity.HELM_TEMPLATE_INSTALL_NAME);
+ ImmutableList<String> command = ImmutableList.<String>of(String.format("helm status %s", helm_name_install_name));
+ OutputStream out = new ByteArrayOutputStream();
+ OutputStream err = new ByteArrayOutputStream();
+ return 0 == ProcessTool.execProcesses(command, null, null, out, err,";",false, this);
+ }
+
+ @Override
+ public void stop() {
+ String helm_name_install_name = getEntity().getConfig(HelmEntity.HELM_TEMPLATE_INSTALL_NAME);
+ ImmutableList<String> command = ImmutableList.<String>of(String.format("helm delete %s", helm_name_install_name));
+ OutputStream out = new ByteArrayOutputStream();
+ OutputStream err = new ByteArrayOutputStream();
+ ProcessTool.execProcesses(command, null, null, out, err,";",false, this);
+
+ //TODO Do something with output
+ }
+
+ @Override
+ public void runPreInstallCommand() {
+
+ }
+
+ @Override
+ public void setup() {
+
+ }
+
+ @Override
+ public void install() {
+ String repo_name = getEntity().getConfig(HelmEntity.REPO_NAME);
+ String repo_url = getEntity().getConfig(HelmEntity.REPO_URL);
+
+ String helm_template = getEntity().getConfig(HelmEntity.HELM_TEMPLATE);
+ String helm_name_install_name = getEntity().getConfig(HelmEntity.HELM_TEMPLATE_INSTALL_NAME);
+ //TODO Fix string formating
+ ImmutableList<String> installHelmTemplateCommand =
+ ImmutableList.<String>of(String.format("helm repo add %s %s", repo_name, repo_url),
+ String.format("helm install %s %s", helm_name_install_name, helm_template));
+ OutputStream out = new ByteArrayOutputStream();
+ OutputStream err = new ByteArrayOutputStream();
+ ProcessTool.execProcesses(installHelmTemplateCommand, null, null, out, err,";", false, this);
+
+ //TODO Do something with output
+ }
+
+ @Override
+ public void runPostInstallCommand() {
+
+ }
+
+ @Override
+ public void runPreCustomizeCommand() {
+
+ }
+
+ @Override
+ public void customize() {
+
+ }
+
+ @Override
+ public void runPostCustomizeCommand() {
+
+ }
+
+ @Override
+ public void runPreLaunchCommand() {
+
+ }
+
+ @Override
+ public void launch() {
+
+ }
+
+ @Override
+ public void runPostLaunchCommand() {
+
+ }
+
+ @Override
+ protected void createDirectory(String directoryName, String summaryForLogging) {
+
+ }
+
+ @Override
+ public int copyResource(Map<Object, Object> sshFlags, String sourceUrl, String target, boolean createParentDir) {
+ return 0;
+ }
+
+ @Override
+ public int copyResource(Map<Object, Object> sshFlags, InputStream source, String target, boolean createParentDir) {
+ return 0;
+ }
+
+ @Override
+ public Callable<String> getCallable(String command) {
+ return new Callable() {
+ @Override
+ public Object call() throws Exception {
+ String helm_name_install_name = getEntity().getConfig(HelmEntity.HELM_TEMPLATE_INSTALL_NAME);
+ ImmutableList<String> installHelmTemplateCommand =
+ ImmutableList.<String>of(String.format("helm %s %s", command, helm_name_install_name));
+ OutputStream out = new ByteArrayOutputStream();
+ OutputStream err = new ByteArrayOutputStream();
+ return ProcessTool.execProcesses(installHelmTemplateCommand, null, null, out, err,";", false, this);
+ }
+ };
+ }
+}
diff --git a/locations/container/src/test/java/org/apache/brooklyn/container/entity/helm/HelmEntityLiveTest.java b/locations/container/src/test/java/org/apache/brooklyn/container/entity/helm/HelmEntityLiveTest.java
new file mode 100644
index 0000000..ffd021b
--- /dev/null
+++ b/locations/container/src/test/java/org/apache/brooklyn/container/entity/helm/HelmEntityLiveTest.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.container.entity.helm;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.container.location.kubernetes.KubernetesLocation;
+import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
+import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.testng.annotations.Test;
+
+import java.util.Map;
+
+import static org.apache.brooklyn.core.entity.EntityAsserts.assertAttributeEqualsEventually;
+import static org.testng.Assert.*;
+
+public class HelmEntityLiveTest extends BrooklynAppLiveTestSupport {
+
+ @Test
+ public void testSimpleDeploy() throws Exception {
+ HelmEntity andManageChild = app.createAndManageChild(EntitySpec.create(HelmEntity.class)
+ .configure(HelmEntity.REPO_NAME, "bitnami")
+ .configure(HelmEntity.REPO_URL, "https://charts.bitnami.com/bitnami")
+ .configure(HelmEntity.HELM_TEMPLATE_INSTALL_NAME, "wordpress-test")
+ .configure(HelmEntity.HELM_TEMPLATE, "bitnami/wordpress"));
+
+ app.start(ImmutableList.<Location>of(app.newLocalhostProvisioningLocation()));
+
+ assertAttributeEqualsEventually(andManageChild, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
+ app.stop();
+ }
+
+ protected KubernetesLocation newKubernetesLocation(Map<String, ?> flags) throws Exception {
+ Map<String, ?> allFlags = MutableMap.<String, Object>builder()
+ .put("kubeconfig", "/Users/duncangrant/.kube/config")
+ .put("image", "cloudsoft/centos:7")
+ .put("loginUser", "root")
+ .put("loginUser.password", "p4ssw0rd")
+ .putAll(flags)
+ .build();
+ return (KubernetesLocation) mgmt.getLocationRegistry().getLocationManaged("kubernetes", allFlags);
+ }
+}
\ No newline at end of file