From 61ca460427309535ae35fb6ef2e4f8b4f5d57dc3 Mon Sep 17 00:00:00 2001 From: Dusan Petrovic Date: Mon, 14 Oct 2024 16:41:31 +0200 Subject: [PATCH] Create ConfigMap before running the app --- .../oracle/assets/ConfigMapProvider.java | 146 ++++++++++++++++++ .../oracle/assets/RunInClusterAction.java | 24 ++- java/java.lsp.server/vscode/package.json | 2 +- 3 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/assets/ConfigMapProvider.java diff --git a/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/assets/ConfigMapProvider.java b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/assets/ConfigMapProvider.java new file mode 100644 index 000000000000..4a9de51e9cef --- /dev/null +++ b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/assets/ConfigMapProvider.java @@ -0,0 +1,146 @@ +/* + * 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.netbeans.modules.cloud.oracle.assets; + +import io.fabric8.kubernetes.api.model.ConfigMap; +import io.fabric8.kubernetes.api.model.ConfigMapBuilder; +import io.fabric8.kubernetes.api.model.ConfigMapList; +import io.fabric8.kubernetes.api.model.ConfigMapVolumeSource; +import io.fabric8.kubernetes.api.model.ConfigMapVolumeSourceBuilder; +import io.fabric8.kubernetes.client.KubernetesClient; +import java.util.Map; +import java.util.TreeMap; +import org.netbeans.modules.cloud.oracle.compute.ClusterItem; + +/** + * + * @author Dusan Petrovic + */ +public class ConfigMapProvider { + + private static final String APP = "app"; //NOI18N + public static final String VOLUME_MOUNT_PATH = "/etc/conf"; //NOI18N + public static final String ENVIRONMENT = "oraclecloud"; //NOI18N + public static final String CONFIG_VOLUME_NAME = "configuration"; + public static final String BOOTSTRAP_PROPERTIES_FILE = "bootstrap-" + ENVIRONMENT + ".properties"; //NOI18N + public static final String APPLICATION_PROPERTIES_FILE = "application-" + ENVIRONMENT + ".properties"; //NOI18N + + private final String projectName; + private final String namespace; + private final PropertiesGenerator propertiesGenerator; + + public ConfigMapProvider(String projectName, String namespace) { + this.projectName = projectName; + this.namespace = namespace; + this.propertiesGenerator = new PropertiesGenerator(false); + } + + public String getMicronautConfigFiles() { + return new StringBuilder(VOLUME_MOUNT_PATH) + .append("/") + .append(APPLICATION_PROPERTIES_FILE) + .append(",") + .append(VOLUME_MOUNT_PATH) + .append("/") + .append(BOOTSTRAP_PROPERTIES_FILE) + .toString(); + } + + public void createConfigMap() { + ClusterItem cluster = CloudAssets.getDefault().getItem(ClusterItem.class); + KubernetesUtils.runWithClient(cluster, client -> { + boolean configMapExist = checkIfConfigMapExist(client); + if (configMapExist) { + updateConfigMap(client); + return; + } + createConfigMap(client); + }); + } + + public ConfigMapVolumeSource getVolumeSource() { + return new ConfigMapVolumeSourceBuilder() + .withName(projectName) + .addNewItem() + .withKey(APPLICATION_PROPERTIES_FILE) + .withPath(APPLICATION_PROPERTIES_FILE) + .endItem() + .addNewItem() + .withKey(BOOTSTRAP_PROPERTIES_FILE) + .withPath(BOOTSTRAP_PROPERTIES_FILE) + .endItem() + .build(); + } + + private boolean checkIfConfigMapExist(KubernetesClient client) { + ConfigMapList cmList = client.configMaps().inNamespace(namespace).list(); + for (ConfigMap cm : cmList.getItems()) { + if (projectName.equals(cm.getMetadata().getName())) { + return true; + } + } + return false; + } + + private void updateConfigMap(KubernetesClient client) { + Map applicationProperties = propertiesGenerator.getApplication(); + Map bootstrapProperties = propertiesGenerator.getBootstrap(); + + client.configMaps() + .inNamespace(namespace) + .withName(projectName) + .edit(cm -> new ConfigMapBuilder(cm) + .removeFromData(APPLICATION_PROPERTIES_FILE) + .removeFromData(BOOTSTRAP_PROPERTIES_FILE) + .addToData(APPLICATION_PROPERTIES_FILE, toFileLikeKeys(applicationProperties)) + .addToData(BOOTSTRAP_PROPERTIES_FILE, toFileLikeKeys(bootstrapProperties)) + .build()); + } + + private ConfigMap createConfigMap(KubernetesClient client) { + Map applicationProperties = propertiesGenerator.getApplication(); + Map bootstrapProperties = propertiesGenerator.getBootstrap(); + + ConfigMap configMap = new ConfigMapBuilder() + .withNewMetadata() + .withName(projectName) + .addToLabels(APP, projectName) + .endMetadata() + .addToData(APPLICATION_PROPERTIES_FILE, toFileLikeKeys(applicationProperties)) + .addToData(BOOTSTRAP_PROPERTIES_FILE, toFileLikeKeys(bootstrapProperties)) + .build(); + + return client.configMaps() + .inNamespace(namespace) + .resource(configMap) + .create(); + } + + private String toFileLikeKeys(Map properties) { + StringBuilder res = new StringBuilder(""); + TreeMap sortedProperties = new TreeMap<>(properties); + for (Map.Entry entry : sortedProperties.entrySet()) { + res.append(entry.getKey()) + .append("=") //NOI18N + .append(entry.getValue()) + .append("\n");//NOI18N + } + return res.toString(); + } +} diff --git a/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/assets/RunInClusterAction.java b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/assets/RunInClusterAction.java index 70157bade064..ab5e60cc37f1 100644 --- a/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/assets/RunInClusterAction.java +++ b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/assets/RunInClusterAction.java @@ -29,6 +29,9 @@ import org.netbeans.api.project.Project; import org.netbeans.api.project.ProjectInformation; import org.netbeans.api.project.ProjectUtils; +import static org.netbeans.modules.cloud.oracle.assets.ConfigMapProvider.CONFIG_VOLUME_NAME; +import static org.netbeans.modules.cloud.oracle.assets.ConfigMapProvider.ENVIRONMENT; +import static org.netbeans.modules.cloud.oracle.assets.ConfigMapProvider.VOLUME_MOUNT_PATH; import org.netbeans.modules.cloud.oracle.compute.ClusterItem; import org.netbeans.modules.cloud.oracle.developer.ContainerTagItem; import org.netbeans.modules.cloud.oracle.steps.ProjectStep; @@ -97,6 +100,9 @@ private void runInCluster() { existingDeployment = deployment; } } + ConfigMapProvider configMapProvider = new ConfigMapProvider(projectName, cluster.getNamespace()); + configMapProvider.createConfigMap(); + if (existingDeployment != null) { client.apps() .deployments() @@ -151,7 +157,24 @@ private void runInCluster() { .addNewPort() .withContainerPort(8080) .endPort() + .addNewEnv() + .withName("MICRONAUT_CONFIG_FILES") + .withValue(configMapProvider.getMicronautConfigFiles()) + .endEnv() + .addNewEnv() + .withName("MICRONAUT_ENVIRONMENTS") + .withValue(ENVIRONMENT) + .endEnv() + .addNewVolumeMount() + .withName(CONFIG_VOLUME_NAME) + .withMountPath(VOLUME_MOUNT_PATH) + .withReadOnly(Boolean.TRUE) + .endVolumeMount() .endContainer() + .addNewVolume() + .withName(CONFIG_VOLUME_NAME) + .withConfigMap(configMapProvider.getVolumeSource()) + .endVolume() .endSpec() .endTemplate() .endSpec() @@ -168,5 +191,4 @@ private void runInCluster() { h.finish(); } } - } diff --git a/java/java.lsp.server/vscode/package.json b/java/java.lsp.server/vscode/package.json index 59ecf6f08a3c..44312a4ef39f 100644 --- a/java/java.lsp.server/vscode/package.json +++ b/java/java.lsp.server/vscode/package.json @@ -673,7 +673,7 @@ }, { "command": "nbls.cloud.assets.configmap.upload", - "title": "Add Cloud Assets to ConfigMap", + "title": "Add Cloud Assets to ConfigMap whithin OCI DevOps project", "icon": "$(add)" }, {