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