Skip to content

Commit

Permalink
Create ConfigMap before running the app
Browse files Browse the repository at this point in the history
  • Loading branch information
petrovic-d committed Oct 15, 2024
1 parent 01a871f commit a939501
Show file tree
Hide file tree
Showing 7 changed files with 569 additions and 320 deletions.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/*
* 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 ClusterItem cluster;
private final PropertiesGenerator propertiesGenerator;

public ConfigMapProvider(String projectName, ClusterItem cluster) {
this.projectName = projectName;
this.cluster = cluster;
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() {
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(cluster.getNamespace()).list();
for (ConfigMap cm : cmList.getItems()) {
if (projectName.equals(cm.getMetadata().getName())) {
return true;
}
}
return false;
}

private void updateConfigMap(KubernetesClient client) {
Map<String, String> applicationProperties = propertiesGenerator.getApplication();
Map<String, String> bootstrapProperties = propertiesGenerator.getBootstrap();

client.configMaps()
.inNamespace(cluster.getNamespace())
.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<String, String> applicationProperties = propertiesGenerator.getApplication();
Map<String, String> 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(cluster.getNamespace())
.resource(configMap)
.create();
}

private String toFileLikeKeys(Map<String, String> properties) {
StringBuilder res = new StringBuilder("");
TreeMap<String, String> sortedProperties = new TreeMap<>(properties);
for (Map.Entry<String, String> entry : sortedProperties.entrySet()) {
res.append(entry.getKey())
.append("=") //NOI18N
.append(entry.getValue())
.append("\n");//NOI18N
}
return res.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import org.netbeans.modules.cloud.oracle.actions.ConfigMapUploader;
import org.netbeans.modules.cloud.oracle.actions.DevOpsProjectConfigMapUploader;
import org.netbeans.spi.lsp.CommandProvider;
import org.openide.util.lookup.ServiceProvider;

Expand All @@ -36,10 +37,12 @@
public class CreateConfigCommand implements CommandProvider {

private static final String COMMAND_CREATE_CONFIG = "nbls.cloud.assets.config.create.local"; //NOI18N
private static final String COMMAND_UPLOAD_TO_CONFIGMAP_WITHIN_DEVOPS = "nbls.cloud.assets.configmap.devops.upload"; //NOI18N
private static final String COMMAND_UPLOAD_TO_CONFIGMAP = "nbls.cloud.assets.configmap.upload"; //NOI18N

private static final Set COMMANDS = new HashSet<>(Arrays.asList(
COMMAND_CREATE_CONFIG,
COMMAND_UPLOAD_TO_CONFIGMAP_WITHIN_DEVOPS,
COMMAND_UPLOAD_TO_CONFIGMAP
));

Expand All @@ -56,6 +59,8 @@ public CompletableFuture<Object> runCommand(String command, List<Object> argumen
ApplicationPropertiesGenerator appPropGen = new ApplicationPropertiesGenerator(propGen);
String toWrite = appPropGen.getApplicationPropertiesString();
future.complete(toWrite);
} else if (COMMAND_UPLOAD_TO_CONFIGMAP_WITHIN_DEVOPS.equals(command)) {
DevOpsProjectConfigMapUploader.uploadConfigMap(future);
} else if (COMMAND_UPLOAD_TO_CONFIGMAP.equals(command)) {
ConfigMapUploader.uploadConfigMap(future);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -91,12 +94,15 @@ private void runInCluster() {
h.start();
KubernetesUtils.runWithClient(cluster, client -> {
Deployment existingDeployment = null;
DeploymentList dList = client.apps().deployments().list();
DeploymentList dList = client.apps().deployments().inNamespace(cluster.getNamespace()).list();
for (Deployment deployment : dList.getItems()) {
if (projectName.equals(deployment.getMetadata().getName())) {
existingDeployment = deployment;
}
}
ConfigMapProvider configMapProvider = new ConfigMapProvider(projectName, cluster);
configMapProvider.createConfigMap();

if (existingDeployment != null) {
client.apps()
.deployments()
Expand Down Expand Up @@ -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()
Expand All @@ -168,5 +191,4 @@ private void runInCluster() {
h.finish();
}
}

}
7 changes: 6 additions & 1 deletion java/java.lsp.server/vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -671,9 +671,14 @@
"title": "Add New Cloud Resource",
"icon": "$(add)"
},
{
"command": "nbls.cloud.assets.configmap.devops.upload",
"title": "Add Cloud Assets to ConfigMap whithin an OCI DevOps project",
"icon": "$(add)"
},
{
"command": "nbls.cloud.assets.configmap.upload",
"title": "Add Cloud Assets to ConfigMap",
"title": "Add Cloud Assets to ConfigMap whithin OKE cluster",
"icon": "$(add)"
},
{
Expand Down
14 changes: 9 additions & 5 deletions java/java.lsp.server/vscode/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -400,12 +400,16 @@ export function activate(context: ExtensionContext): VSNetBeansAPI {
);
context.subscriptions.push(vscode.commands.registerCommand('cloud.assets.config.create', async function (viewItem) {
const CONFIG_LOCAL = 'Open a preview of the config in the editor';
const CONFIG_TO_CM = 'Upload the config to a ConfigMap artifact in an OCI DevOps Project';
const selected: any = await window.showQuickPick([CONFIG_LOCAL, CONFIG_TO_CM], { placeHolder: 'Select a target for the config' });
if (selected == CONFIG_TO_CM) {
await commands.executeCommand('nbls.cloud.assets.configmap.upload');
const CONFIG_TO_DEVOPS_CM = 'Upload the config to a ConfigMap artifact whithin an OCI DevOps Project';
const CONFIG_TO_OKE_CM = 'Upload the config to a ConfigMap artifact whithin OKE cluster';
const selected: any = await window.showQuickPick([CONFIG_LOCAL, CONFIG_TO_OKE_CM, CONFIG_TO_DEVOPS_CM], { placeHolder: 'Select a target for the config' });
if (selected == CONFIG_TO_DEVOPS_CM) {
await commands.executeCommand('nbls.cloud.assets.configmap.devops.upload');
return;
}
} else if (selected == CONFIG_TO_OKE_CM) {
await commands.executeCommand('nbls.cloud.assets.configmap.upload');
return;
}
const content = await vscode.commands.executeCommand('nbls.cloud.assets.config.create.local') as string;
const document = vscode.Uri.parse(`${scheme}:application.properties?${encodeURIComponent(content)}`);
vscode.workspace.openTextDocument(document).then(doc => {
Expand Down

0 comments on commit a939501

Please sign in to comment.