Adding action/command for adding DB connection proerties to the OCI Vault
diff --git a/enterprise/cloud.oracle/external/binaries-list b/enterprise/cloud.oracle/external/binaries-list
index 622fd13..ecd1327 100644
--- a/enterprise/cloud.oracle/external/binaries-list
+++ b/enterprise/cloud.oracle/external/binaries-list
@@ -15,16 +15,18 @@
# specific language governing permissions and limitations
# under the License.
-F89364D98A616CBA66CA535759EA092C54B4BF75 com.oracle.oci.sdk:oci-java-sdk-common:3.9.0
-7BB77013E6B91FCC7CD72D3338EB9F4019E20EA9 com.oracle.oci.sdk:oci-java-sdk-database:3.9.0
-8AB9B9CA57124F30B6D25CBAC944A7CEE0373068 com.oracle.oci.sdk:oci-java-sdk-identity:3.9.0
-F2071C1D75795350EB4D6807C4327AA333C5930C com.oracle.oci.sdk:oci-java-sdk-circuitbreaker:3.9.0
-10D73A80C8F66F959C84189272A7FC1C0CB1C435 com.oracle.oci.sdk:oci-java-sdk-workrequests:3.9.0
-031597E1BEEED3E48203BE6ECEBBA442E6FE177E com.oracle.oci.sdk:oci-java-sdk-devops:3.9.0
-5E52AF447D216717453E91782FCB965DF5669D5C com.oracle.oci.sdk:oci-java-sdk-adm:3.9.0
-C81CF0C79C300BF0526DF80D7890F688C1E32803 com.oracle.oci.sdk:oci-java-sdk-common-httpclient:3.9.0
-19C42576CC31E6028F29639F442EBA0CD895ADB3 com.oracle.oci.sdk:oci-java-sdk-common-httpclient-jersey:3.9.0
-9499C6360FFDBEBC6F0F1285A20DD91485FEDD46 com.oracle.oci.sdk:oci-java-sdk-addons-apache-configurator-jersey:3.9.0
+01713F2F4C8533893B8BD73C9461698F16F2B091 com.oracle.oci.sdk:oci-java-sdk-common:3.25.3
+5E25BDEF20C9897C16EA939DBF185177F158EC40 com.oracle.oci.sdk:oci-java-sdk-database:3.25.3
+D1015B3664782EABF06354C63748152E6D3BF268 com.oracle.oci.sdk:oci-java-sdk-vault:3.25.3
+0B6A6C71B4880A87B1FB034B3F1AB6E5361FC558 com.oracle.oci.sdk:oci-java-sdk-keymanagement:3.25.3
+E46F0CE2219BBCDA94B87D4CB4EF4166DAF6C925 com.oracle.oci.sdk:oci-java-sdk-identity:3.25.3
+832F50EFBFB3B320CA5CAEC75FE607FB8CEDF40E com.oracle.oci.sdk:oci-java-sdk-circuitbreaker:3.25.3
+78C9D083AD254C858E4A69F51958A9A46D260F97 com.oracle.oci.sdk:oci-java-sdk-workrequests:3.25.3
+9D89873EC1059B5B75058DB5FF1C25D66A9EC859 com.oracle.oci.sdk:oci-java-sdk-devops:3.25.3
+95F57672B60D7A611582262828DCED3F7544BA7C com.oracle.oci.sdk:oci-java-sdk-adm:3.25.3
+A8B7EBCA334E8145469A8FE0365C02A2727218EE com.oracle.oci.sdk:oci-java-sdk-common-httpclient:3.25.3
+AECECCD95E5ED92C73E455B7BA4AC714229041EE com.oracle.oci.sdk:oci-java-sdk-common-httpclient-jersey:3.25.3
+0CEE99CE7AA783353D19C56AC9F1AD72485DDBE8 com.oracle.oci.sdk:oci-java-sdk-addons-apache-configurator-jersey:3.25.3
E5F6CAE5CA7ECAAC1EC2827A9E2D65AE2869CADA org.apache.httpcomponents:httpclient:4.5.13
853B96D3AFBB7BF8CC303FE27EE96836A10C1834 org.apache.httpcomponents:httpcore:4.4.13
diff --git a/enterprise/cloud.oracle/external/oci-java-sdk-3.9.0-license.txt b/enterprise/cloud.oracle/external/oci-java-sdk-3.25.3-license.txt
similarity index 96%
rename from enterprise/cloud.oracle/external/oci-java-sdk-3.9.0-license.txt
rename to enterprise/cloud.oracle/external/oci-java-sdk-3.25.3-license.txt
index c7fcf3f..4506966 100644
--- a/enterprise/cloud.oracle/external/oci-java-sdk-3.9.0-license.txt
+++ b/enterprise/cloud.oracle/external/oci-java-sdk-3.25.3-license.txt
@@ -1,9 +1,9 @@
Name: OCI Java SDK
Description: Oracle Cloud Infrastructure SDK for Java
Origin: https://github.com/oracle/oci-java-sdk
-Version: 3.9.0
+Version: 3.25.3
License: UPL-Apache-2.0
-Files: oci-java-sdk-circuitbreaker-3.9.0.jar, oci-java-sdk-common-3.9.0.jar, oci-java-sdk-database-3.9.0.jar, oci-java-sdk-identity-3.9.0.jar, oci-java-sdk-workrequests-3.9.0.jar, oci-java-sdk-adm-3.9.0.jar, oci-java-sdk-devops-3.9.0.jar, oci-java-sdk-addons-apache-configurator-jersey-3.9.0.jar, oci-java-sdk-common-httpclient-3.9.0.jar, oci-java-sdk-common-httpclient-jersey-3.9.0.jar
+Files: oci-java-sdk-circuitbreaker-3.25.3.jar, oci-java-sdk-common-3.25.3.jar, oci-java-sdk-database-3.25.3.jar, oci-java-sdk-identity-3.25.3.jar, oci-java-sdk-workrequests-3.25.3.jar, oci-java-sdk-adm-3.25.3.jar, oci-java-sdk-devops-3.25.3.jar, oci-java-sdk-addons-apache-configurator-jersey-3.25.3.jar, oci-java-sdk-common-httpclient-3.25.3.jar, oci-java-sdk-common-httpclient-jersey-3.25.3.jar oci-java-sdk-keymanagement-3.25.3.jar oci-java-sdk-vault-3.25.3.jar
Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
diff --git a/enterprise/cloud.oracle/nbproject/project.properties b/enterprise/cloud.oracle/nbproject/project.properties
index f69596d..28ad8d5 100644
--- a/enterprise/cloud.oracle/nbproject/project.properties
+++ b/enterprise/cloud.oracle/nbproject/project.properties
@@ -15,17 +15,19 @@
# specific language governing permissions and limitations
# under the License.
-release.external/oci-java-sdk-circuitbreaker-3.9.0.jar=modules/ext/oci-java-sdk-circuitbreaker-3.9.0.jar
-release.external/oci-java-sdk-common-3.9.0.jar=modules/ext/oci-java-sdk-common-3.9.0.jar
-release.external/oci-java-sdk-devops-3.9.0.jar=modules/ext/oci-java-sdk-devops-3.9.0.jar
-release.external/oci-java-sdk-database-3.9.0.jar=modules/ext/oci-java-sdk-database-3.9.0.jar
-release.external/oci-java-sdk-identity-3.9.0.jar=modules/ext/oci-java-sdk-identity-3.9.0.jar
-release.external/oci-java-sdk-workrequests-3.9.0.jar=modules/ext/oci-java-sdk-workrequests-3.9.0.jar
-release.external/oci-java-sdk-devops-3.9.0.jar=modules/ext/oci-java-sdk-devops-3.9.0.jar
-release.external/oci-java-sdk-adm-3.9.0.jar=modules/ext/oci-java-sdk-adm-3.9.0.jar
-release.external/oci-java-sdk-common-httpclient-3.9.0.jar=modules/ext/oci-java-sdk-common-httpclient-3.9.0.jar
-release.external/oci-java-sdk-common-httpclient-jersey-3.9.0.jar=modules/ext/oci-java-sdk-common-httpclient-jersey-3.9.0.jar
-release.external/oci-java-sdk-addons-apache-configurator-jersey-3.9.0.jar=modules/ext/oci-java-sdk-addons-apache-configurator-jersey-3.9.0.jar
+release.external/oci-java-sdk-circuitbreaker-3.25.3.jar=modules/ext/oci-java-sdk-circuitbreaker-3.25.3.jar
+release.external/oci-java-sdk-common-3.25.3.jar=modules/ext/oci-java-sdk-common-3.25.3.jar
+release.external/oci-java-sdk-devops-3.25.3.jar=modules/ext/oci-java-sdk-devops-3.25.3.jar
+release.external/oci-java-sdk-database-3.25.3.jar=modules/ext/oci-java-sdk-database-3.25.3.jar
+release.external/oci-java-sdk-vault-3.25.3.jar=modules/ext/oci-java-sdk-vault-3.25.3.jar
+release.external/oci-java-sdk-keymanagement-3.25.3.jar=modules/ext/oci-java-sdk-keymanagement-3.25.3.jar
+release.external/oci-java-sdk-identity-3.25.3.jar=modules/ext/oci-java-sdk-identity-3.25.3.jar
+release.external/oci-java-sdk-workrequests-3.25.3.jar=modules/ext/oci-java-sdk-workrequests-3.25.3.jar
+release.external/oci-java-sdk-devops-3.25.3.jar=modules/ext/oci-java-sdk-devops-3.25.3.jar
+release.external/oci-java-sdk-adm-3.25.3.jar=modules/ext/oci-java-sdk-adm-3.25.3.jar
+release.external/oci-java-sdk-common-httpclient-3.25.3.jar=modules/ext/oci-java-sdk-common-httpclient-3.25.3.jar
+release.external/oci-java-sdk-common-httpclient-jersey-3.25.3.jar=modules/ext/oci-java-sdk-common-httpclient-jersey-3.25.3.jar
+release.external/oci-java-sdk-addons-apache-configurator-jersey-3.25.3.jar=modules/ext/oci-java-sdk-addons-apache-configurator-jersey-3.25.3.jar
release.external/httpclient-4.5.13.jar=modules/ext/httpclient-4.5.13.jar
release.external/httpcore-4.4.13.jar=modules/ext/httpcore-4.4.13.jar
release.external/javassist-3.25.0-GA.jar=modules/ext/javassist-3.25.0-GA.jar
diff --git a/enterprise/cloud.oracle/nbproject/project.xml b/enterprise/cloud.oracle/nbproject/project.xml
index 9cfde3c..2aee363 100644
--- a/enterprise/cloud.oracle/nbproject/project.xml
+++ b/enterprise/cloud.oracle/nbproject/project.xml
@@ -236,8 +236,8 @@
</test-dependencies>
<public-packages/>
<class-path-extension>
- <runtime-relative-path>ext/oci-java-sdk-identity-3.9.0.jar</runtime-relative-path>
- <binary-origin>external/oci-java-sdk-identity-3.9.0.jar</binary-origin>
+ <runtime-relative-path>ext/oci-java-sdk-identity-3.25.3.jar</runtime-relative-path>
+ <binary-origin>external/oci-java-sdk-identity-3.25.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/resilience4j-circuitbreaker-1.7.1.jar</runtime-relative-path>
@@ -248,28 +248,28 @@
<binary-origin>external/resilience4j-core-1.7.1.jar</binary-origin>
</class-path-extension>
<class-path-extension>
- <runtime-relative-path>ext/oci-java-sdk-common-3.9.0.jar</runtime-relative-path>
- <binary-origin>external/oci-java-sdk-common-3.9.0.jar</binary-origin>
+ <runtime-relative-path>ext/oci-java-sdk-common-3.25.3.jar</runtime-relative-path>
+ <binary-origin>external/oci-java-sdk-common-3.25.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
- <runtime-relative-path>ext/oci-java-sdk-devops-3.9.0.jar</runtime-relative-path>
- <binary-origin>external/oci-java-sdk-devops-3.9.0.jar</binary-origin>
+ <runtime-relative-path>ext/oci-java-sdk-devops-3.25.3.jar</runtime-relative-path>
+ <binary-origin>external/oci-java-sdk-devops-3.25.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
- <runtime-relative-path>ext/oci-java-sdk-adm-3.9.0.jar</runtime-relative-path>
- <binary-origin>external/oci-java-sdk-adm-3.9.0.jar</binary-origin>
+ <runtime-relative-path>ext/oci-java-sdk-adm-3.25.3.jar</runtime-relative-path>
+ <binary-origin>external/oci-java-sdk-adm-3.25.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
- <runtime-relative-path>ext/oci-java-sdk-common-httpclient-3.9.0.jar</runtime-relative-path>
- <binary-origin>external/oci-java-sdk-common-httpclient-3.9.0.jar</binary-origin>
+ <runtime-relative-path>ext/oci-java-sdk-common-httpclient-3.25.3.jar</runtime-relative-path>
+ <binary-origin>external/oci-java-sdk-common-httpclient-3.25.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
- <runtime-relative-path>ext/oci-java-sdk-common-httpclient-jersey-3.9.0.jar</runtime-relative-path>
- <binary-origin>external/oci-java-sdk-common-httpclient-jersey-3.9.0.jar</binary-origin>
+ <runtime-relative-path>ext/oci-java-sdk-common-httpclient-jersey-3.25.3.jar</runtime-relative-path>
+ <binary-origin>external/oci-java-sdk-common-httpclient-jersey-3.25.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
- <runtime-relative-path>ext/oci-java-sdk-addons-apache-configurator-jersey-3.9.0.jar</runtime-relative-path>
- <binary-origin>external/oci-java-sdk-addons-apache-configurator-jersey-3.9.0.jar</binary-origin>
+ <runtime-relative-path>ext/oci-java-sdk-addons-apache-configurator-jersey-3.25.3.jar</runtime-relative-path>
+ <binary-origin>external/oci-java-sdk-addons-apache-configurator-jersey-3.25.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/httpclient-4.5.13.jar</runtime-relative-path>
@@ -288,20 +288,28 @@
<binary-origin>external/vavr-0.10.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
- <runtime-relative-path>ext/oci-java-sdk-database-3.9.0.jar</runtime-relative-path>
- <binary-origin>external/oci-java-sdk-database-3.9.0.jar</binary-origin>
+ <runtime-relative-path>ext/oci-java-sdk-database-3.25.3.jar</runtime-relative-path>
+ <binary-origin>external/oci-java-sdk-database-3.25.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
- <runtime-relative-path>ext/oci-java-sdk-circuitbreaker-3.9.0.jar</runtime-relative-path>
- <binary-origin>external/oci-java-sdk-circuitbreaker-3.9.0.jar</binary-origin>
+ <runtime-relative-path>ext/oci-java-sdk-vault-3.25.3.jar</runtime-relative-path>
+ <binary-origin>external/oci-java-sdk-vault-3.25.3.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/oci-java-sdk-keymanagement-3.25.3.jar</runtime-relative-path>
+ <binary-origin>external/oci-java-sdk-keymanagement-3.25.3.jar</binary-origin>
+ </class-path-extension>
+ <class-path-extension>
+ <runtime-relative-path>ext/oci-java-sdk-circuitbreaker-3.25.3.jar</runtime-relative-path>
+ <binary-origin>external/oci-java-sdk-circuitbreaker-3.25.3.jar</binary-origin>
</class-path-extension>
<class-path-extension>
<runtime-relative-path>ext/vavr-match-0.10.2.jar</runtime-relative-path>
<binary-origin>external/vavr-match-0.10.2.jar</binary-origin>
</class-path-extension>
<class-path-extension>
- <runtime-relative-path>ext/oci-java-sdk-workrequests-3.9.0.jar</runtime-relative-path>
- <binary-origin>external/oci-java-sdk-workrequests-3.9.0.jar</binary-origin>
+ <runtime-relative-path>ext/oci-java-sdk-workrequests-3.25.3.jar</runtime-relative-path>
+ <binary-origin>external/oci-java-sdk-workrequests-3.25.3.jar</binary-origin>
</class-path-extension>
</data>
</configuration>
diff --git a/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/actions/AddDbConnectionToVault.java b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/actions/AddDbConnectionToVault.java
new file mode 100644
index 0000000..d98e75d
--- /dev/null
+++ b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/actions/AddDbConnectionToVault.java
@@ -0,0 +1,719 @@
+/*
+ * 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.actions;
+
+import com.oracle.bmc.identity.Identity;
+import com.oracle.bmc.identity.IdentityClient;
+import com.oracle.bmc.identity.model.Compartment;
+import com.oracle.bmc.identity.requests.ListCompartmentsRequest;
+import com.oracle.bmc.identity.responses.ListCompartmentsResponse;
+import com.oracle.bmc.identity.model.Tenancy;
+import org.netbeans.api.db.explorer.DatabaseConnection;
+import com.oracle.bmc.model.BmcException;
+import com.oracle.bmc.vault.VaultsClient;
+import com.oracle.bmc.vault.model.Base64SecretContentDetails;
+import com.oracle.bmc.vault.model.CreateSecretDetails;
+import com.oracle.bmc.vault.model.SecretContentDetails;
+import com.oracle.bmc.vault.model.SecretReuseRule;
+import com.oracle.bmc.vault.model.UpdateSecretDetails;
+import com.oracle.bmc.vault.requests.CreateSecretRequest;
+import com.oracle.bmc.vault.requests.ListSecretsRequest;
+import com.oracle.bmc.vault.requests.UpdateSecretRequest;
+import com.oracle.bmc.vault.responses.CreateSecretResponse;
+import com.oracle.bmc.vault.responses.ListSecretsResponse;
+import com.oracle.bmc.vault.responses.UpdateSecretResponse;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import org.netbeans.api.progress.ProgressHandle;
+import org.netbeans.modules.cloud.oracle.OCIManager;
+import static org.netbeans.modules.cloud.oracle.OCIManager.getDefault;
+import org.netbeans.modules.cloud.oracle.OCIProfile;
+import org.netbeans.modules.cloud.oracle.OCISessionInitiator;
+import org.netbeans.modules.cloud.oracle.compartment.CompartmentItem;
+import org.netbeans.modules.cloud.oracle.items.OCID;
+import org.netbeans.modules.cloud.oracle.items.OCIItem;
+import org.netbeans.modules.cloud.oracle.items.TenancyItem;
+import org.netbeans.modules.cloud.oracle.vault.KeyItem;
+import org.netbeans.modules.cloud.oracle.vault.KeyNode;
+import org.netbeans.modules.cloud.oracle.vault.SecretItem;
+import org.netbeans.modules.cloud.oracle.vault.SecretNode;
+import org.netbeans.modules.cloud.oracle.vault.VaultItem;
+import org.netbeans.modules.cloud.oracle.vault.VaultNode;
+import org.openide.DialogDescriptor;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.NotifyDescriptor.QuickPick.Item;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionReferences;
+import org.openide.awt.ActionRegistration;
+import org.openide.util.NbBundle;
+import org.openide.util.Pair;
+
+/**
+ *
+ * @author Jan Horvath
+ */
+@ActionID(
+ category = "Tools",
+ id = "org.netbeans.modules.cloud.oracle.actions.AddDbConnectionToVault"
+)
+@ActionRegistration(
+ displayName = "#AddADBToVault",
+ asynchronous = true
+)
+@ActionReferences(value = {
+ @ActionReference(path = "Cloud/Oracle/Databases/Actions", position = 250)
+})
+@NbBundle.Messages({
+ "AddADBToVault=Add Oracle Autonomous DB details to OCI Vault",
+ "SelectKey=Select Key",
+ "SelectVault=Select Vault",
+ "SecretsCreated=Secrets were created or updated",
+ "NoKeys=No keys in this Vault. Select another one.",
+ "DatasourceName=Datasource Name",
+ "AddVersion=Add new versions",
+ "Cancel=Cancel",
+ "SecretExists=Secrets with name {0} already exists",
+ "NoProfile=There is not any OCI profile in the config",
+ "NoCompartment=There are no compartments in the Tenancy"
+})
+public class AddDbConnectionToVault implements ActionListener {
+
+ private static final Logger LOG = Logger.getLogger(AddDbConnectionToVault.class.getName());
+
+ private final DatabaseConnection context;
+
+ public AddDbConnectionToVault(DatabaseConnection context) {
+ this.context = context;
+ }
+
+ static interface Step<T, U> {
+
+ Step<T, U> prepare(T item);
+
+ NotifyDescriptor createInput();
+
+ boolean onlyOneChoice();
+
+ Step getNext();
+
+ void setValue(String selected);
+
+ U getValue();
+ }
+
+ class TenancyStep implements Step<Object, TenancyItem> {
+
+ List<OCIProfile> profiles = new LinkedList<>();
+ private AtomicReference<TenancyItem> selected = new AtomicReference<>();
+
+ @Override
+ public NotifyDescriptor createInput() {
+ if (onlyOneChoice()) {
+ throw new IllegalStateException("No data to create input"); // NOI18N
+ }
+ String title = Bundle.SelectProfile();
+ List<NotifyDescriptor.QuickPick.Item> items = new ArrayList<>(profiles.size());
+ for (OCIProfile p : profiles) {
+ Tenancy t = p.getTenancyData();
+ if (t != null) {
+ items.add(new NotifyDescriptor.QuickPick.Item(p.getId(), Bundle.SelectProfile_Description(t.getName(), t.getHomeRegionKey())));
+ }
+ }
+ if (profiles.stream().filter(p -> p.getTenancy().isPresent()).count() == 0) {
+ title = Bundle.NoProfile();
+ }
+ return new NotifyDescriptor.QuickPick(title, title, items, false);
+ }
+
+ @Override
+ public Step getNext() {
+ return new CompartmentStep().prepare(getValue());
+ }
+
+ public Step<Object, TenancyItem> prepare(Object i) {
+ ProgressHandle h = ProgressHandle.createHandle(Bundle.MSG_CollectingProfiles());
+ h.start();
+ h.progress(Bundle.MSG_CollectingProfiles_Text());
+ try {
+ profiles = OCIManager.getDefault().getConnectedProfiles();
+ } finally {
+ h.finish();
+ }
+ return this;
+ }
+
+ public void setValue(String selected) {
+ for (OCIProfile profile : profiles) {
+ if (profile.getId().equals(selected)) {
+ profile.getTenancy().ifPresent(t -> this.selected.set(t));
+ break;
+ }
+ }
+ }
+
+ @Override
+ public TenancyItem getValue() {
+ if (onlyOneChoice()) {
+ return profiles.stream()
+ .map(p -> p.getTenancy())
+ .filter(Optional::isPresent)
+ .map(Optional::get)
+ .findFirst()
+ .get();
+ }
+ return selected.get();
+ }
+
+ @Override
+ public boolean onlyOneChoice() {
+ return profiles.stream().filter(p -> p.getTenancy().isPresent()).count() == 1;
+ }
+ }
+
+ static class CompartmentStep implements Step<TenancyItem, CompartmentItem> {
+
+ private Map<String, OCIItem> compartments = null;
+ private CompartmentItem selected;
+
+ public Step<TenancyItem, CompartmentItem> prepare(TenancyItem tenancy) {
+ ProgressHandle h = ProgressHandle.createHandle(Bundle.MSG_CollectingItems());
+ h.start();
+ h.progress(Bundle.MSG_CollectingItems_Text());
+ try {
+ compartments = getFlatCompartment(tenancy);
+ } finally {
+ h.finish();
+ }
+ return this;
+ }
+
+ @Override
+ public NotifyDescriptor createInput() {
+ if (onlyOneChoice()) {
+ throw new IllegalStateException("Input shouldn't be displayed for one choice"); // NOI18N
+ }
+ if (compartments.isEmpty()) {
+ createQuickPick(compartments, Bundle.NoCompartment());
+ }
+ return createQuickPick(compartments, Bundle.SelectCompartment());
+ }
+
+ @Override
+ public Step getNext() {
+ return new VaultStep().prepare(getValue());
+ }
+
+ @Override
+ public void setValue(String selected) {
+ this.selected = (CompartmentItem) compartments.get(selected);
+ }
+
+ @Override
+ public CompartmentItem getValue() {
+ if (onlyOneChoice()) {
+ return (CompartmentItem) compartments.values().iterator().next();
+ }
+ return selected;
+ }
+
+ @Override
+ public boolean onlyOneChoice() {
+ return compartments.size() == 1;
+ }
+ }
+
+ static class VaultStep implements Step<CompartmentItem, VaultItem> {
+
+ private Map<String, VaultItem> vaults = null;
+ private VaultItem selected;
+
+ public Step<CompartmentItem, VaultItem> prepare(CompartmentItem compartment) {
+ ProgressHandle h = ProgressHandle.createHandle(Bundle.MSG_CollectingItems());
+ h.start();
+ h.progress(Bundle.MSG_CollectingItems_Text());
+ try {
+ vaults = getVaults(compartment);
+ } finally {
+ h.finish();
+ }
+ return this;
+ }
+
+ @Override
+ public NotifyDescriptor createInput() {
+ return createQuickPick(vaults, Bundle.SelectVault());
+ }
+
+ @Override
+ public Step getNext() {
+ return new KeyStep().prepare(selected);
+ }
+
+ @Override
+ public void setValue(String selected) {
+ this.selected = vaults.get(selected);
+ }
+
+ @Override
+ public VaultItem getValue() {
+ if (onlyOneChoice()) {
+ vaults.values().iterator().next();
+ }
+ return selected;
+ }
+
+ @Override
+ public boolean onlyOneChoice() {
+ return vaults.size() == 1;
+ }
+ }
+
+ static class KeyStep implements Step<VaultItem, Pair<VaultItem, KeyItem>> {
+
+ private Map<String, KeyItem> keys = null;
+ private KeyItem selected;
+ private VaultItem vault;
+
+ public Step<VaultItem, Pair<VaultItem, KeyItem>> prepare(VaultItem vault) {
+ this.vault = vault;
+ ProgressHandle h = ProgressHandle.createHandle(Bundle.MSG_CollectingItems());
+ h.start();
+ h.progress(Bundle.MSG_CollectingItems_Text());
+ try {
+ keys = getKeys(vault);
+ } finally {
+ h.finish();
+ }
+ return this;
+ }
+
+ @Override
+ public boolean onlyOneChoice() {
+ return keys.size() == 1;
+ }
+
+ @Override
+ public NotifyDescriptor createInput() {
+ if (keys.size() > 1) {
+ return createQuickPick(keys, Bundle.SelectKey());
+ }
+ if (keys.size() == 0) {
+ return new NotifyDescriptor.QuickPick("", Bundle.NoKeys(), Collections.emptyList(), false);
+ }
+
+ throw new IllegalStateException("No data to create input"); // NOI18N
+ }
+
+ @Override
+ public Step getNext() {
+ return new DatasourceNameStep().prepare(getValue());
+ }
+
+ @Override
+ public void setValue(String selected) {
+ this.selected = keys.get(selected);
+ }
+
+ @Override
+ public Pair<VaultItem, KeyItem> getValue() {
+ if (keys.size() == 1) {
+ return Pair.of(vault, keys.values().iterator().next());
+ }
+ return Pair.of(vault, selected);
+ }
+
+ }
+
+ static class DatasourceNameStep implements Step<Pair<VaultItem, KeyItem>, Result> {
+
+ private Result result = new Result();
+
+ @Override
+ public Step<Pair<VaultItem, KeyItem>, Result> prepare(Pair<VaultItem, KeyItem> item) {
+ result.vault = item.first();
+ result.key = item.second();
+ return this;
+ }
+
+ @Override
+ public NotifyDescriptor createInput() {
+ return new NotifyDescriptor.InputLine("DEFAULT", Bundle.DatasourceName()); //NOI18N
+ }
+
+ @Override
+ public Step getNext() {
+ return new OverwriteStep().prepare(result);
+ }
+
+ @Override
+ public void setValue(String selected) {
+ result.datasourceName = selected;
+ }
+
+ @Override
+ public Result getValue() {
+ return result;
+ }
+
+ @Override
+ public boolean onlyOneChoice() {
+ return false;
+ }
+
+ }
+
+ static class OverwriteStep implements Step<Result, Result> {
+
+ private Result result;
+ private Set<String> dsNames;
+ private String choice;
+
+ @Override
+ public Step<Result, Result> prepare(Result result) {
+ this.result = result;
+ List<SecretItem> secrets = SecretNode.getSecrets().apply(result.vault);
+ this.dsNames = secrets.stream()
+ .map(s -> extractDatasourceName(s.getName()))
+ .filter(Objects::nonNull)
+ .collect(Collectors.toSet());
+ return this;
+ }
+
+ @Override
+ public NotifyDescriptor createInput() {
+ List<Item> yesNo = new ArrayList();
+ yesNo.add(new Item(Bundle.AddVersion(), ""));
+ yesNo.add(new Item(Bundle.Cancel(), ""));
+ return new NotifyDescriptor.QuickPick("", Bundle.SecretExists(result.datasourceName), yesNo, false);
+ }
+
+ @Override
+ public Step getNext() {
+ return null;
+ }
+
+ @Override
+ public void setValue(String choice) {
+ this.choice = choice;
+ }
+
+ @Override
+ public Result getValue() {
+ if (Bundle.AddVersion().equals(choice) || onlyOneChoice()) {
+ result.update = true;
+ return result;
+ }
+ return null;
+ }
+
+ @Override
+ public boolean onlyOneChoice() {
+ return !dsNames.contains(result.datasourceName);
+ }
+
+ }
+
+ static class Result {
+ VaultItem vault;
+ KeyItem key;
+ String datasourceName;
+ private boolean update;
+ }
+
+ static class Multistep {
+
+ private final LinkedList<Step> steps = new LinkedList<>();
+
+ Multistep(Step firstStep) {
+ steps.add(firstStep);
+ }
+
+ NotifyDescriptor.ComposedInput.Callback createInput() {
+ return new NotifyDescriptor.ComposedInput.Callback() {
+
+ private void showInput(Step step, NotifyDescriptor desc) {
+ String selected = null;
+ if (!step.onlyOneChoice()) {
+ if (desc instanceof NotifyDescriptor.QuickPick) {
+ for (NotifyDescriptor.QuickPick.Item item : ((NotifyDescriptor.QuickPick) desc).getItems()) {
+ if (item.isSelected()) {
+ selected = item.getLabel();
+ break;
+ }
+ }
+ } else if (desc instanceof NotifyDescriptor.InputLine) {
+ selected = ((NotifyDescriptor.InputLine) desc).getInputText();
+ }
+ step.setValue(selected);
+ }
+ }
+
+ NotifyDescriptor prepareInput(NotifyDescriptor.ComposedInput input, int number) {
+ if (number == 1) {
+ steps.get(0).prepare(null);
+ return steps.get(0).createInput();
+ }
+ if (steps.size() > number) {
+ steps.removeLast();
+ return steps.getLast().createInput();
+ }
+ showInput(steps.getLast(), input.getInputs()[number - 2]);
+ Step currentStep = steps.getLast().getNext();
+ if (currentStep == null) {
+ return null;
+ }
+
+ steps.add(currentStep);
+ if (currentStep.onlyOneChoice()) {
+ return prepareInput(input, number);
+ }
+ return currentStep.createInput();
+ }
+
+ @Override
+ public NotifyDescriptor createInput(NotifyDescriptor.ComposedInput input, int number) {
+ return prepareInput(input, number);
+ }
+ };
+ }
+
+ Object getResult() {
+ return steps.getLast().getValue();
+ }
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+
+ Multistep multistep = new Multistep(new TenancyStep());
+
+ NotifyDescriptor.ComposedInput ci = new NotifyDescriptor.ComposedInput(Bundle.AddADB(), 3, multistep.createInput());
+ if (DialogDescriptor.OK_OPTION == DialogDisplayer.getDefault().notify(ci)) {
+ if (multistep.getResult() != null) {
+ Result v = (Result) multistep.getResult();
+ addDbConnectionToVault(v.vault, v.key, context, v.datasourceName);
+ }
+ }
+
+ }
+
+ private static void addDbConnectionToVault(VaultItem vault, KeyItem key, DatabaseConnection connection, String datasourceName) {
+ VaultsClient client = VaultsClient.builder().build(getDefault().getActiveProfile().getConfigProvider());
+
+ ListSecretsRequest listSecretsRequest = ListSecretsRequest.builder()
+ .compartmentId(vault.getCompartmentId())
+ .vaultId(vault.getKey().getValue())
+ .limit(88)
+ .build();
+
+ ListSecretsResponse secrets = client.listSecrets(listSecretsRequest);
+
+ Map<String, String> existingSecrets = secrets.getItems().stream()
+ .collect(Collectors.toMap(s -> s.getSecretName(), s -> s.getId()));
+
+ Map<String, String> values = new HashMap<String, String>() {
+ {
+ put("Username", connection.getUser()); //NOI18N
+ put("Password", connection.getPassword()); //NOI18N
+ put("OCID", (String) connection.getConnectionProperties().get("OCID")); //NOI18N
+ put("wallet_Password", UUID.randomUUID().toString()); //NOI18N
+ }
+ };
+
+ try {
+ for (Entry<String, String> entry : values.entrySet()) {
+ String secretName = "DATASOURCES_" + datasourceName + "_" + entry.getKey().toUpperCase(); //NOI18N
+ String base64Content = Base64.getEncoder().encodeToString(entry.getValue().getBytes(StandardCharsets.UTF_8));
+
+ SecretContentDetails contentDetails = Base64SecretContentDetails.builder()
+ .content(base64Content)
+ .stage(SecretContentDetails.Stage.Current).build();
+ if (existingSecrets.containsKey(secretName)) {
+ UpdateSecretDetails updateSecretDetails = UpdateSecretDetails.builder()
+ .secretContent(contentDetails)
+ .build();
+ UpdateSecretRequest request = UpdateSecretRequest.builder()
+ .secretId(existingSecrets.get(secretName))
+ .updateSecretDetails(updateSecretDetails)
+ .build();
+ UpdateSecretResponse response = client.updateSecret(request);
+ } else {
+ CreateSecretDetails createDetails = CreateSecretDetails.builder()
+ .secretName(secretName)
+ .secretContent(contentDetails)
+ .secretRules(new ArrayList<>(Arrays.asList(SecretReuseRule.builder()
+ .isEnforcedOnDeletedSecretVersions(false).build())))
+ .compartmentId(vault.getCompartmentId())
+ .vaultId(vault.getKey().getValue())
+ .keyId(key.getKey().getValue())
+ .build();
+ CreateSecretRequest request = CreateSecretRequest
+ .builder()
+ .createSecretDetails(createDetails)
+ .build();
+ CreateSecretResponse response = client.createSecret(request);
+ }
+ }
+
+ } catch (BmcException e) {
+ NotifyDescriptor.Message msg = new NotifyDescriptor.Message(e.getMessage());
+ DialogDisplayer.getDefault().notify(msg);
+ throw new RuntimeException(e);
+ }
+ NotifyDescriptor.Message msg = new NotifyDescriptor.Message(Bundle.SecretsCreated());
+ DialogDisplayer.getDefault().notify(msg);
+ }
+
+ private static <T extends OCIItem> NotifyDescriptor.QuickPick createQuickPick(Map<String, T> ociItems, String title) {
+
+ List<NotifyDescriptor.QuickPick.Item> items = ociItems.entrySet().stream()
+ .map(entry -> new NotifyDescriptor.QuickPick.Item(entry.getKey(), entry.getValue().getDescription()))
+ .collect(Collectors.toList());
+ return new NotifyDescriptor.QuickPick(title, title, items, false);
+ }
+
+ private static Map<String, OCIItem> getFlatCompartment(TenancyItem tenancy) {
+ Map<OCID, FlatCompartmentItem> compartments = new HashMap<>();
+ OCISessionInitiator session = OCIManager.getDefault().getActiveSession();
+ Identity identityClient = session.newClient(IdentityClient.class);
+ String nextPageToken = null;
+
+ do {
+ ListCompartmentsResponse response
+ = identityClient.listCompartments(
+ ListCompartmentsRequest.builder()
+ .compartmentId(tenancy.getKey().getValue())
+ .compartmentIdInSubtree(true)
+ .lifecycleState(Compartment.LifecycleState.Active)
+ .accessLevel(ListCompartmentsRequest.AccessLevel.Accessible)
+ .limit(1000)
+ .page(nextPageToken)
+ .build());
+ for (Compartment comp : response.getItems()) {
+ FlatCompartmentItem ci = new FlatCompartmentItem(comp) {
+ FlatCompartmentItem getItem(OCID compId) {
+ return compartments.get(compId);
+ }
+ };
+ compartments.put(ci.getKey(), ci);
+ }
+ nextPageToken = response.getOpcNextPage();
+ } while (nextPageToken != null);
+ Map<String, OCIItem> pickItems = computeFlatNames(compartments);
+ pickItems.put(tenancy.getName() + " (root)", tenancy); // NOI18N
+ return pickItems;
+ }
+
+ private static Map<String, OCIItem> computeFlatNames(Map<OCID, FlatCompartmentItem> compartments) {
+ Map<String, OCIItem> pickItems = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+ for (FlatCompartmentItem comp : compartments.values()) {
+ pickItems.put(comp.getName(), comp);
+ }
+ return pickItems;
+ }
+
+ private static abstract class FlatCompartmentItem extends CompartmentItem {
+
+ private final OCID parentId;
+ private String flatName;
+
+ private FlatCompartmentItem(Compartment ociComp) {
+ super(OCID.of(ociComp.getId(), "Compartment"), ociComp.getName()); // NOI18N
+ setDescription(ociComp.getDescription());
+ parentId = OCID.of(ociComp.getCompartmentId(), "Compartment"); // NOI18N
+ }
+
+ public String getName() {
+ if (parentId.getValue() == null) {
+ return "";
+ }
+ if (flatName == null) {
+ String parentFlatName = "";
+ FlatCompartmentItem parentComp = getItem(parentId);
+ if (parentComp != null) {
+ parentFlatName = parentComp.getName();
+ }
+ flatName = super.getName();
+ if (!parentFlatName.isEmpty()) {
+ flatName = parentFlatName + "/" + flatName; // NOI18N
+ }
+ }
+ return flatName;
+ }
+
+ abstract FlatCompartmentItem getItem(OCID compId);
+ }
+
+ protected static Map<String, VaultItem> getVaults(OCIItem parent) {
+ Map<String, VaultItem> items = new HashMap<>();
+ try {
+ if (parent instanceof CompartmentItem) {
+ VaultNode.getVaults().apply((CompartmentItem) parent).forEach((db) -> items.put(db.getName(), db));
+ }
+ } catch (BmcException e) {
+ LOG.log(Level.SEVERE, "Unable to load vault list", e); //NOI18N
+ }
+ return items;
+ }
+
+ protected static Map<String, KeyItem> getKeys(OCIItem parent) {
+ Map<String, KeyItem> items = new HashMap<>();
+ try {
+ if (parent instanceof VaultItem) {
+ KeyNode.getKeys().apply((VaultItem) parent).forEach((db) -> items.put(db.getName(), db));
+ }
+ } catch (BmcException e) {
+ LOG.log(Level.SEVERE, "Unable to load vault list", e); //NOI18N
+ }
+ return items;
+ }
+
+ static Pattern p = Pattern.compile("[A-Z]*_([A-Z]*)_[A-Z]*"); //NOI18N
+
+ protected static String extractDatasourceName(String value) {
+ Matcher m = p.matcher(value);
+ if (m.matches()) {
+ return m.group(1);
+ }
+ return null;
+ }
+}
diff --git a/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/resources/key.svg b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/resources/key.svg
new file mode 100644
index 0000000..16e1b4e
--- /dev/null
+++ b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/resources/key.svg
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+
+ 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.
+
+-->
+
+<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+
+<svg
+ version="1.1"
+ id="Vector_Icons"
+ x="0px"
+ y="0px"
+ width="16px"
+ height="16px"
+ viewBox="0 0 16 16"
+ style="enable-background:new 0 0 16 16;"
+ xml:space="preserve"
+ sodipodi:docname="key.svg"
+ inkscape:version="1.3 (0e150ed, 2023-07-21)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"><defs
+ id="defs2"><linearGradient
+ id="swatch1"
+ inkscape:swatch="solid"><stop
+ style="stop-color:#eaeaea;stop-opacity:1;"
+ offset="0"
+ id="stop1" /></linearGradient></defs><sodipodi:namedview
+ id="namedview2"
+ pagecolor="#ffffff"
+ bordercolor="#000000"
+ borderopacity="0.25"
+ inkscape:showpageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ inkscape:deskcolor="#d1d1d1"
+ inkscape:zoom="20"
+ inkscape:cx="5.675"
+ inkscape:cy="6.5"
+ inkscape:window-width="1512"
+ inkscape:window-height="893"
+ inkscape:window-x="152"
+ inkscape:window-y="112"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="Vector_Icons" /> <style
+ type="text/css"
+ id="style1"> .st0{fill:#FFFFFF;} .st1{opacity:0.25;} .st2{fill:#FAFAFA;} .st3{opacity:0.33;} .st4{fill:none;stroke:#474747;stroke-miterlimit:10;} .st5{opacity:0.42;} .st6{fill:#CAE3FF;} .st7{opacity:0.2;} .st8{opacity:0.03;} .st9{opacity:0.1;} .st10{opacity:0.15;} .st11{opacity:0.45;} .st12{fill:#FFE1B0;} .st13{fill:#B3DBFF;} .st14{fill:#FBDC7C;} .st15{fill:#FFDB43;} .st16{fill:#E79B00;} .st17{fill:#3883CE;} .st18{fill:none;stroke:#003399;stroke-width:1.375;stroke-miterlimit:10;} .st19{fill:#E8513D;} .st20{fill:#1E1E1E;} .st21{fill:#FFC36D;} .st22{fill:#9FCBFF;} .st23{fill:#E9F7FF;} .st24{fill:#62707C;} .st25{fill:#7A8896;} .st26{fill:#57BFFF;} .st27{fill:#E69D35;} .st28{fill:#9CFF73;} .st29{fill:#4891CC;} .st30{fill:#474747;} .st31{fill:#CCA05E;} .st32{opacity:0.67;} .st33{opacity:0.3;} .st34{fill:#EAEAEA;} .st35{fill:#FFE945;} .st36{fill:#FFCF8C;} .st37{fill:#FF5252;} .st38{opacity:0.12;} .st39{fill:#45A5F4;} .st40{fill:url(#SVGID_1_);} .st41{fill:url(#SVGID_2_);} .st42{opacity:0.05;} .st43{fill:#3D81F5;} .st44{fill:#CECECE;} .st45{fill:#B5B5B5;} .st46{opacity:0.4;} .st47{fill:#595959;} .st48{fill:#80FF80;} .st49{fill:#C8FF80;} .st50{fill:#FFEE80;} .st51{fill:#FFA680;} .st52{fill:#FF8080;} .st53{fill:none;} .st54{fill:#007AFF;} .st55{fill:#EFFF78;} .st56{fill:#FFDA00;} .st57{fill:#3EADFF;} .st58{opacity:0.67;fill:#FFFFFF;} .st59{fill:#2E92FF;} .st60{fill:#3AEA00;} .st61{fill:#303030;} </style> <g
+ id="path14"><path
+ style="color:#000000;fill:#aaaaaa;fill-opacity:0.98;-inkscape-stroke:none;paint-order:stroke fill markers"
+ d="m 8.1230469,1.4667969 c -2.2137385,0 -3.96875,1.9199255 -3.96875,4.2070312 0,2.2871058 1.7550115,4.2070313 3.96875,4.2070313 2.2137381,0 3.9707031,-1.9199255 3.9707031,-4.2070313 0,-2.2871057 -1.756965,-4.2070312 -3.9707031,-4.2070312 z m 0,1.5 c 1.3433463,0 2.4707031,1.1749514 2.4707031,2.7070312 0,1.5320799 -1.1273568,2.7070313 -2.4707031,2.7070313 -1.3433463,0 -2.46875,-1.1749514 -2.46875,-2.7070313 0,-1.5320798 1.1254037,-2.7070312 2.46875,-2.7070312 z"
+ id="path3" /><path
+ style="color:#000000;fill:#ffffff;-inkscape-stroke:none;paint-order:stroke fill markers"
+ d="M 11.344011,5.6738701 A 3.2203391,3.4576271 0 0 1 8.1236715,9.1314971 3.2203391,3.4576271 0 0 1 4.9033325,5.6738701 3.2203391,3.4576271 0 0 1 8.1236715,2.216243 3.2203391,3.4576271 0 0 1 11.344011,5.6738701 Z"
+ id="path4" /></g><g
+ id="rect15"
+ transform="translate(0.05,0.15)"><path
+ style="color:#000000;fill:#aaaaaa;-inkscape-stroke:none;paint-order:stroke fill markers"
+ d="M 2.1015625,5.7460937 V 6.5175781 13.941406 H 14.191406 V 5.7460937 Z M 3.6464844,7.2890625 H 12.646484 V 12.396484 H 3.6464844 Z"
+ id="path1" /><path
+ style="color:#000000;fill:#fffffe;-inkscape-stroke:none;paint-order:stroke fill markers"
+ d="M 2.8737502,6.5174522 H 13.418947 V 13.169272 H 2.8737502 Z"
+ id="path2" /></g><path
+ fill-rule="evenodd"
+ clip-rule="evenodd"
+ d="m 9.5746606,7.1437895 a 1.8261872,1.8261872 0 0 1 1.3873864,1.2744598 c 0.08671,0.2919963 0.09962,0.6009315 0.03751,0.899381 A 1.8483693,1.8483693 0 0 1 9.2100708,10.769546 c -0.1766498,0 -0.3524927,-0.02541 -0.5214798,-0.07663 l -0.3226476,0.378305 -0.1528548,0.07058 H 7.8198614 v 0.604965 L 7.6182068,11.94842 h -0.604965 v 0.604966 L 6.8115845,12.75504 H 5.6016551 L 5.4,12.553386 V 11.62295 L 5.4588834,11.480581 7.4649466,9.4745175 A 1.8003754,1.8003754 0 0 1 7.3842845,8.9078672 1.8261872,1.8261872 0 0 1 9.5746606,7.1433864 Z m 0.5315624,2.9038315 a 1.4390096,1.4390096 0 0 0 0.499701,-0.8086361 l 0.0016,0.00202 A 1.428927,1.428927 0 0 0 8.9168394,7.5426765 1.4422362,1.4422362 0 0 0 7.7875717,8.9139301 c -0.00406,0.1839093 0.02823,0.3662056 0.096391,0.536402 L 7.8395965,9.6693295 5.8032846,11.706448 v 0.645296 h 0.8066452 v -0.604965 l 0.2016547,-0.201655 h 0.6049649 v -0.604965 l 0.2016551,-0.201655 h 0.502121 l 0.353299,-0.409763 0.2262568,-0.05646 a 1.3994853,1.3994853 0 0 0 0.5118003,0.09599 1.4390096,1.4390096 0 0 0 0.8945414,-0.320632 z M 9.7682493,8.9457782 a 0.40330989,0.40330989 0 1 0 -0.670301,-0.4476735 0.40330989,0.40330989 0 0 0 0.670301,0.4476735 z"
+ id="path1-6"
+ style="fill:#aaaaaa;fill-opacity:1;stroke-width:0.403309" /></svg>
diff --git a/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/resources/layer.xml b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/resources/layer.xml
index 03c6ebc..63cffaa 100644
--- a/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/resources/layer.xml
+++ b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/resources/layer.xml
@@ -48,6 +48,9 @@
<!--org.netbeans.modules.cloud.oracle.database.DatabaseNode.getDatabases()-->
<attr methodvalue="org.netbeans.modules.cloud.oracle.database.DatabaseNode.getDatabases" name="instanceCreate"/>
</file>
+ <file name="org-netbeans-modules-cloud-oracle-vault-VaultNode-getVaults.instance">
+ <attr methodvalue="org.netbeans.modules.cloud.oracle.vault.VaultNode.getVaults" name="instanceCreate"/>
+ </file>
<file name="org-netbeans-modules-cloud-oracle-devops-DevopsProjectNode-listDevopsProjects.instance">
<!--org.netbeans.modules.cloud.oracle.devops.DevopsProjectNode.listDevopsProjects()-->
<attr methodvalue="org.netbeans.modules.cloud.oracle.devops.DevopsProjectNode.listDevopsProjects" name="instanceCreate"/>
@@ -162,6 +165,34 @@
</file>
</folder>
</folder>
+ <folder name="Vault">
+ <folder name="Nodes">
+ <file name="org-netbeans-modules-cloud-oracle-vault-VaultNode-createNode.instance">
+ <attr methodvalue="org.netbeans.modules.cloud.oracle.vault.VaultNode.createNode" name="instanceCreate"/>
+ </file>
+ <file name="org-netbeans-modules-cloud-oracle-vault-SecretNode-getSecrets.instance">
+ <attr methodvalue="org.netbeans.modules.cloud.oracle.vault.SecretNode.getSecrets" name="instanceCreate"/>
+ </file>
+ <file name="org-netbeans-modules-cloud-oracle-vault-KeyNode-getKeys.instance">
+ <attr methodvalue="org.netbeans.modules.cloud.oracle.vault.KeyNode.getKeys" name="instanceCreate"/>
+ </file>
+ </folder>
+ <folder name="Key">
+ <folder name="Nodes">
+ <file name="org-netbeans-modules-cloud-oracle-vault-KeyNode-createNode.instance">
+ <attr methodvalue="org.netbeans.modules.cloud.oracle.vault.KeyNode.createNode" name="instanceCreate"/>
+ </file>
+ </folder>
+ </folder>
+ <folder name="Secret">
+ <folder name="Nodes">
+ <file name="org-netbeans-modules-cloud-oracle-vault-SecretNode-createNode.instance">
+ <attr methodvalue="org.netbeans.modules.cloud.oracle.vault.SecretNode.createNode" name="instanceCreate"/>
+ </file>
+ </folder>
+ </folder>
+
+ </folder>
<folder name="BuildRun">
<folder name="Nodes">
<file name="org-netbeans-modules-cloud-oracle-devops-BuildRunNode-createNode.instance">
diff --git a/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/resources/secret.svg b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/resources/secret.svg
new file mode 100644
index 0000000..adc4af5
--- /dev/null
+++ b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/resources/secret.svg
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+
+ 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.
+
+-->
+
+<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+
+<svg
+ version="1.1"
+ id="Vector_Icons"
+ x="0px"
+ y="0px"
+ width="16px"
+ height="16px"
+ viewBox="0 0 16 16"
+ style="enable-background:new 0 0 16 16;"
+ xml:space="preserve"
+ sodipodi:docname="secret.svg"
+ inkscape:version="1.3 (0e150ed, 2023-07-21)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"><defs
+ id="defs2" /><sodipodi:namedview
+ id="namedview2"
+ pagecolor="#ffffff"
+ bordercolor="#000000"
+ borderopacity="0.25"
+ inkscape:showpageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ inkscape:deskcolor="#d1d1d1"
+ inkscape:zoom="14.75"
+ inkscape:cx="7.9661017"
+ inkscape:cy="8"
+ inkscape:window-width="1312"
+ inkscape:window-height="449"
+ inkscape:window-x="335"
+ inkscape:window-y="400"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="Vector_Icons" /> <style
+ type="text/css"
+ id="style1"> .st0{fill:#FFFFFF;} .st1{opacity:0.25;} .st2{fill:#FAFAFA;} .st3{opacity:0.33;} .st4{fill:none;stroke:#474747;stroke-miterlimit:10;} .st5{opacity:0.42;} .st6{fill:#CAE3FF;} .st7{opacity:0.2;} .st8{opacity:0.03;} .st9{opacity:0.1;} .st10{opacity:0.15;} .st11{opacity:0.45;} .st12{fill:#FFE1B0;} .st13{fill:#B3DBFF;} .st14{fill:#FBDC7C;} .st15{fill:#FFDB43;} .st16{fill:#E79B00;} .st17{fill:#3883CE;} .st18{fill:none;stroke:#003399;stroke-width:1.375;stroke-miterlimit:10;} .st19{fill:#E8513D;} .st20{fill:#1E1E1E;} .st21{fill:#FFC36D;} .st22{fill:#9FCBFF;} .st23{fill:#E9F7FF;} .st24{fill:#62707C;} .st25{fill:#7A8896;} .st26{fill:#57BFFF;} .st27{fill:#E69D35;} .st28{fill:#9CFF73;} .st29{fill:#4891CC;} .st30{fill:#474747;} .st31{fill:#CCA05E;} .st32{opacity:0.67;} .st33{opacity:0.3;} .st34{fill:#EAEAEA;} .st35{fill:#FFE945;} .st36{fill:#FFCF8C;} .st37{fill:#FF5252;} .st38{opacity:0.12;} .st39{fill:#45A5F4;} .st40{fill:url(#SVGID_1_);} .st41{fill:url(#SVGID_2_);} .st42{opacity:0.05;} .st43{fill:#3D81F5;} .st44{fill:#CECECE;} .st45{fill:#B5B5B5;} .st46{opacity:0.4;} .st47{fill:#595959;} .st48{fill:#80FF80;} .st49{fill:#C8FF80;} .st50{fill:#FFEE80;} .st51{fill:#FFA680;} .st52{fill:#FF8080;} .st53{fill:none;} .st54{fill:#007AFF;} .st55{fill:#EFFF78;} .st56{fill:#FFDA00;} .st57{fill:#3EADFF;} .st58{opacity:0.67;fill:#FFFFFF;} .st59{fill:#2E92FF;} .st60{fill:#3AEA00;} .st61{fill:#303030;} </style> <path
+ fill-rule="evenodd"
+ clip-rule="evenodd"
+ d="m 11.469644,1.0072947 a 4.528,4.528 0 0 1 3.44,3.16 c 0.215,0.724 0.247,1.49 0.093,2.23 a 4.583,4.583 0 0 1 -4.437,3.6000005 c -0.438,0 -0.8739999,-0.063 -1.2929999,-0.19 l -0.8,0.9379998 -0.379,0.175 h -0.975 v 1.5 l -0.5,0.5 h -1.5 v 1.5 l -0.5,0.499999 h -3 l -0.5,-0.499999 v -2.307001 l 0.146,-0.352999 4.974,-4.9740003 a 4.464,4.464 0 0 1 -0.2,-1.405 4.528,4.528 0 0 1 5.4309999,-4.375 z m 1.318,7.2 a 3.568,3.568 0 0 0 1.239,-2.005 l 0.004,0.005 a 3.543,3.543 0 0 0 -4.1919999,-4.211 3.576,3.576 0 0 0 -2.8,3.4 c -0.01,0.456 0.07,0.908 0.239,1.33 l -0.11,0.543 -5.049,5.0510003 v 1.6 h 2 v -1.5 l 0.5,-0.5 h 1.5 v -1.5 l 0.5,-0.4999998 h 1.245 l 0.876,-1.0160005 0.561,-0.14 a 3.47,3.47 0 0 0 1.2689999,0.2380005 3.568,3.568 0 0 0 2.218,-0.7950005 z m -0.838,-2.732 a 1,1 0 1 0 -1.662,-1.11 1,1 0 0 0 1.662,1.11 z"
+ id="path1"
+ style="fill:#aaaaaa;fill-opacity:1" /></svg>
diff --git a/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/resources/vault.svg b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/resources/vault.svg
new file mode 100644
index 0000000..13a2c5e
--- /dev/null
+++ b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/resources/vault.svg
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+
+ 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.
+
+-->
+
+<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+
+<svg
+ version="1.1"
+ id="Vector_Icons"
+ x="0px"
+ y="0px"
+ width="16px"
+ height="16px"
+ viewBox="0 0 16 16"
+ style="enable-background:new 0 0 16 16;"
+ xml:space="preserve"
+ sodipodi:docname="vault.svg"
+ inkscape:version="1.3 (0e150ed, 2023-07-21)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"><defs
+ id="defs2"><linearGradient
+ id="swatch1"
+ inkscape:swatch="solid"><stop
+ style="stop-color:#eaeaea;stop-opacity:1;"
+ offset="0"
+ id="stop1" /></linearGradient></defs><sodipodi:namedview
+ id="namedview2"
+ pagecolor="#ffffff"
+ bordercolor="#000000"
+ borderopacity="0.25"
+ inkscape:showpageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ inkscape:deskcolor="#d1d1d1"
+ inkscape:zoom="20"
+ inkscape:cx="5.675"
+ inkscape:cy="6.525"
+ inkscape:window-width="1504"
+ inkscape:window-height="682"
+ inkscape:window-x="208"
+ inkscape:window-y="394"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="Vector_Icons" /> <style
+ type="text/css"
+ id="style1"> .st0{fill:#FFFFFF;} .st1{opacity:0.25;} .st2{fill:#FAFAFA;} .st3{opacity:0.33;} .st4{fill:none;stroke:#474747;stroke-miterlimit:10;} .st5{opacity:0.42;} .st6{fill:#CAE3FF;} .st7{opacity:0.2;} .st8{opacity:0.03;} .st9{opacity:0.1;} .st10{opacity:0.15;} .st11{opacity:0.45;} .st12{fill:#FFE1B0;} .st13{fill:#B3DBFF;} .st14{fill:#FBDC7C;} .st15{fill:#FFDB43;} .st16{fill:#E79B00;} .st17{fill:#3883CE;} .st18{fill:none;stroke:#003399;stroke-width:1.375;stroke-miterlimit:10;} .st19{fill:#E8513D;} .st20{fill:#1E1E1E;} .st21{fill:#FFC36D;} .st22{fill:#9FCBFF;} .st23{fill:#E9F7FF;} .st24{fill:#62707C;} .st25{fill:#7A8896;} .st26{fill:#57BFFF;} .st27{fill:#E69D35;} .st28{fill:#9CFF73;} .st29{fill:#4891CC;} .st30{fill:#474747;} .st31{fill:#CCA05E;} .st32{opacity:0.67;} .st33{opacity:0.3;} .st34{fill:#EAEAEA;} .st35{fill:#FFE945;} .st36{fill:#FFCF8C;} .st37{fill:#FF5252;} .st38{opacity:0.12;} .st39{fill:#45A5F4;} .st40{fill:url(#SVGID_1_);} .st41{fill:url(#SVGID_2_);} .st42{opacity:0.05;} .st43{fill:#3D81F5;} .st44{fill:#CECECE;} .st45{fill:#B5B5B5;} .st46{opacity:0.4;} .st47{fill:#595959;} .st48{fill:#80FF80;} .st49{fill:#C8FF80;} .st50{fill:#FFEE80;} .st51{fill:#FFA680;} .st52{fill:#FF8080;} .st53{fill:none;} .st54{fill:#007AFF;} .st55{fill:#EFFF78;} .st56{fill:#FFDA00;} .st57{fill:#3EADFF;} .st58{opacity:0.67;fill:#FFFFFF;} .st59{fill:#2E92FF;} .st60{fill:#3AEA00;} .st61{fill:#303030;} </style> <g
+ id="path14"><path
+ style="color:#000000;fill:#aaaaaa;fill-opacity:0.98;-inkscape-stroke:none;paint-order:stroke fill markers"
+ d="m 8.1230469,1.4667969 c -2.2137385,0 -3.96875,1.9199255 -3.96875,4.2070312 0,2.2871058 1.7550115,4.2070313 3.96875,4.2070313 2.2137381,0 3.9707031,-1.9199255 3.9707031,-4.2070313 0,-2.2871057 -1.756965,-4.2070312 -3.9707031,-4.2070312 z m 0,1.5 c 1.3433463,0 2.4707031,1.1749514 2.4707031,2.7070312 0,1.5320799 -1.1273568,2.7070313 -2.4707031,2.7070313 -1.3433463,0 -2.46875,-1.1749514 -2.46875,-2.7070313 0,-1.5320798 1.1254037,-2.7070312 2.46875,-2.7070312 z"
+ id="path3" /><path
+ style="color:#000000;fill:#ffffff;-inkscape-stroke:none;paint-order:stroke fill markers"
+ d="M 11.344011,5.6738701 A 3.2203391,3.4576271 0 0 1 8.1236715,9.1314971 3.2203391,3.4576271 0 0 1 4.9033325,5.6738701 3.2203391,3.4576271 0 0 1 8.1236715,2.216243 3.2203391,3.4576271 0 0 1 11.344011,5.6738701 Z"
+ id="path4" /></g><g
+ id="rect15"
+ transform="translate(0.05,0.15)"><path
+ style="color:#000000;fill:#aaaaaa;-inkscape-stroke:none;paint-order:stroke fill markers"
+ d="M 2.1015625,5.7460937 V 6.5175781 13.941406 H 14.191406 V 5.7460937 Z M 3.6464844,7.2890625 H 12.646484 V 12.396484 H 3.6464844 Z"
+ id="path1" /><path
+ style="color:#000000;fill:#fffffe;-inkscape-stroke:none;paint-order:stroke fill markers"
+ d="M 2.8737502,6.5174522 H 13.418947 V 13.169272 H 2.8737502 Z"
+ id="path2" /></g></svg>
diff --git a/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/vault/KeyItem.java b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/vault/KeyItem.java
new file mode 100644
index 0000000..927b474
--- /dev/null
+++ b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/vault/KeyItem.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.netbeans.modules.cloud.oracle.vault;
+
+import org.netbeans.modules.cloud.oracle.items.OCID;
+import org.netbeans.modules.cloud.oracle.items.OCIItem;
+
+/**
+ *
+ * @author Jan Horvath
+ */
+public class KeyItem extends OCIItem {
+ String compartmentId;
+
+ public KeyItem(OCID id, String name, String compartmentId) {
+ super(id, name);
+ this.compartmentId = compartmentId;
+ }
+
+ public KeyItem() {
+ super();
+ }
+
+ public String getCompartmentId() {
+ return compartmentId;
+ }
+
+ @Override
+ public int maxInProject() {
+ return Integer.MAX_VALUE;
+ }
+
+}
diff --git a/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/vault/KeyNode.java b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/vault/KeyNode.java
new file mode 100644
index 0000000..60380b8
--- /dev/null
+++ b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/vault/KeyNode.java
@@ -0,0 +1,90 @@
+/*
+ * 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.vault;
+
+import com.oracle.bmc.keymanagement.KmsManagementClient;
+import com.oracle.bmc.keymanagement.model.Vault;
+import com.oracle.bmc.keymanagement.requests.ListKeysRequest;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+import org.netbeans.modules.cloud.oracle.ChildrenProvider;
+import org.netbeans.modules.cloud.oracle.NodeProvider;
+import org.netbeans.modules.cloud.oracle.OCIManager;
+import org.netbeans.modules.cloud.oracle.OCINode;
+import org.netbeans.modules.cloud.oracle.items.OCID;
+import org.openide.nodes.Children;
+import org.openide.util.NbBundle;
+
+/**
+ *
+ * @author Jan Horvath
+ */
+@NbBundle.Messages({})
+public class KeyNode extends OCINode {
+
+ private static final String KEY_ICON = "org/netbeans/modules/cloud/oracle/resources/key.svg"; // NOI18N
+ private static final Logger LOG = Logger.getLogger(KeyNode.class.getName());
+
+ public KeyNode(KeyItem key) {
+ super(key, Children.LEAF);
+ setName(key.getName());
+ setDisplayName(key.getName());
+ setIconBaseWithExtension(KEY_ICON);
+ setShortDescription(key.getDescription());
+ }
+
+ public static NodeProvider<KeyItem> createNode() {
+ return KeyNode::new;
+ }
+
+ /**
+ * Retrieves list of Keys belonging to a given Vault.
+ *
+ * @param compartmentId OCID of the Vault
+ * @return List of {@code OCIItem} describing Keys in a given
+ * Vault
+ */
+ public static ChildrenProvider<VaultItem, KeyItem> getKeys() {
+ return vault -> {
+ Vault v = Vault.builder()
+ .compartmentId(vault.compartmentId)
+ .id(vault.getKey().getValue())
+ .managementEndpoint(vault.managementEndpoint)
+ .build();
+ KmsManagementClient client = KmsManagementClient.builder()
+ .vault(v)
+ .build(OCIManager.getDefault().getActiveProfile().getConfigProvider());
+ ListKeysRequest listKeysRequest = ListKeysRequest.builder()
+ .compartmentId(vault.getCompartmentId())
+ .limit(88)
+ .build();
+
+ return client.listKeys(listKeysRequest)
+ .getItems()
+ .stream()
+ .map(d -> new KeyItem(
+ OCID.of(d.getId(), "Vault/Key"), //NOI18N
+ d.getDisplayName(),
+ d.getCompartmentId())
+ )
+ .collect(Collectors.toList());
+ };
+ }
+
+}
diff --git a/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/vault/SecretItem.java b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/vault/SecretItem.java
new file mode 100644
index 0000000..74d7390
--- /dev/null
+++ b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/vault/SecretItem.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.netbeans.modules.cloud.oracle.vault;
+
+import org.netbeans.modules.cloud.oracle.items.OCID;
+import org.netbeans.modules.cloud.oracle.items.OCIItem;
+
+/**
+ *
+ * @author Jan Horvath
+ */
+public class SecretItem extends OCIItem {
+ String compartmentId;
+
+ public SecretItem(OCID id, String name, String compartmentId) {
+ super(id, name);
+ this.compartmentId = compartmentId;
+ }
+
+ public SecretItem() {
+ super();
+ }
+
+ public String getCompartmentId() {
+ return compartmentId;
+ }
+
+ @Override
+ public int maxInProject() {
+ return Integer.MAX_VALUE;
+ }
+
+}
diff --git a/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/vault/SecretNode.java b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/vault/SecretNode.java
new file mode 100644
index 0000000..976aa4c
--- /dev/null
+++ b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/vault/SecretNode.java
@@ -0,0 +1,79 @@
+/*
+ * 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.vault;
+
+import com.oracle.bmc.vault.VaultsClient;
+import com.oracle.bmc.vault.requests.ListSecretsRequest;
+import java.util.stream.Collectors;
+import org.netbeans.modules.cloud.oracle.ChildrenProvider;
+import org.netbeans.modules.cloud.oracle.NodeProvider;
+import static org.netbeans.modules.cloud.oracle.OCIManager.getDefault;
+import org.netbeans.modules.cloud.oracle.OCINode;
+import org.netbeans.modules.cloud.oracle.items.OCID;
+import org.openide.nodes.Children;
+
+/**
+ *
+ * @author Jan Horvath
+ */
+public class SecretNode extends OCINode {
+ private static final String SECRET_ICON = "org/netbeans/modules/cloud/oracle/resources/secret.svg"; // NOI18N
+
+ public SecretNode(SecretItem vault) {
+ super(vault, Children.LEAF);
+ setName(vault.getName());
+ setDisplayName(vault.getName());
+ setIconBaseWithExtension(SECRET_ICON);
+ setShortDescription(vault.getDescription());
+ }
+
+ public static NodeProvider<SecretItem> createNode() {
+ return SecretNode::new;
+ }
+
+ /**
+ * Retrieves list of Databases belonging to a given Compartment.
+ *
+ * @param compartmentId OCID of the Compartment
+ * @return List of {@code OCIItem} describing databases in a given
+ * Compartment
+ */
+ public static ChildrenProvider<VaultItem, SecretItem> getSecrets() {
+ return vault -> {
+ VaultsClient client = VaultsClient.builder().build(getDefault().getActiveProfile().getConfigProvider());
+
+ ListSecretsRequest listSecretsRequest = ListSecretsRequest.builder()
+ .compartmentId(vault.getCompartmentId())
+ .vaultId(vault.getKey().getValue())
+ .limit(88)
+ .build();
+
+ return client.listSecrets(listSecretsRequest)
+ .getItems()
+ .stream()
+ .map(d -> new SecretItem(
+ OCID.of(d.getId(), "Vault/Secret"), //NOI18N
+ d.getSecretName(),
+ d.getCompartmentId())
+ )
+ .collect(Collectors.toList());
+ };
+ }
+
+}
diff --git a/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/vault/VaultItem.java b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/vault/VaultItem.java
new file mode 100644
index 0000000..caba8cc
--- /dev/null
+++ b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/vault/VaultItem.java
@@ -0,0 +1,55 @@
+/*
+ * 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.vault;
+
+import org.netbeans.modules.cloud.oracle.items.OCID;
+import org.netbeans.modules.cloud.oracle.items.OCIItem;
+
+/**
+ *
+ * @author Jan Horvath
+ */
+public class VaultItem extends OCIItem {
+ String compartmentId;
+ String managementEndpoint;
+
+ public VaultItem(OCID id, String name, String compartmentId, String managementEndpoint) {
+ super(id, name);
+ this.compartmentId = compartmentId;
+ this.managementEndpoint = managementEndpoint;
+ }
+
+ public VaultItem() {
+ super();
+ }
+
+ public String getCompartmentId() {
+ return compartmentId;
+ }
+
+ public String getManagementEndpoint() {
+ return managementEndpoint;
+ }
+
+ @Override
+ public int maxInProject() {
+ return Integer.MAX_VALUE;
+ }
+
+}
diff --git a/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/vault/VaultNode.java b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/vault/VaultNode.java
new file mode 100644
index 0000000..d06b253
--- /dev/null
+++ b/enterprise/cloud.oracle/src/org/netbeans/modules/cloud/oracle/vault/VaultNode.java
@@ -0,0 +1,82 @@
+/*
+ * 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.vault;
+
+import com.oracle.bmc.keymanagement.KmsVaultClient;
+import com.oracle.bmc.keymanagement.requests.ListVaultsRequest;
+import java.util.stream.Collectors;
+import org.netbeans.modules.cloud.oracle.ChildrenProvider;
+import org.netbeans.modules.cloud.oracle.NodeProvider;
+import org.netbeans.modules.cloud.oracle.OCIManager;
+import org.netbeans.modules.cloud.oracle.OCINode;
+import org.netbeans.modules.cloud.oracle.compartment.CompartmentItem;
+import org.netbeans.modules.cloud.oracle.items.OCID;
+import org.openide.util.NbBundle;
+
+/**
+ *
+ * @author Jan Horvath
+ */
+@NbBundle.Messages({
+})
+public class VaultNode extends OCINode {
+ private static final String VAULT_ICON = "org/netbeans/modules/cloud/oracle/resources/vault.svg"; // NOI18N
+
+ public VaultNode(VaultItem vault) {
+ super(vault);
+ setName(vault.getName());
+ setDisplayName(vault.getName());
+ setIconBaseWithExtension(VAULT_ICON);
+ setShortDescription(vault.getDescription());
+ }
+
+ public static NodeProvider<VaultItem> createNode() {
+ return VaultNode::new;
+ }
+
+ /**
+ * Retrieves list of Databases belonging to a given Compartment.
+ *
+ * @param compartmentId OCID of the Compartment
+ * @return List of {@code OCIItem} describing databases in a given
+ * Compartment
+ */
+ public static ChildrenProvider<CompartmentItem, VaultItem> getVaults() {
+ return compartmentId -> {
+ KmsVaultClient client = KmsVaultClient.builder().build(OCIManager.getDefault().getActiveProfile().getConfigProvider());
+
+ ListVaultsRequest listVaultsRequest = ListVaultsRequest.builder()
+ .compartmentId(compartmentId.getKey().getValue())
+ .limit(88)
+ .build();
+
+ return client.listVaults(listVaultsRequest)
+ .getItems()
+ .stream()
+ .map(d -> new VaultItem(
+ OCID.of(d.getId(), "Vault"), //NOI18N
+ d.getDisplayName(),
+ d.getCompartmentId(),
+ d.getManagementEndpoint())
+ )
+ .collect(Collectors.toList());
+ };
+ }
+
+}
diff --git a/enterprise/cloud.oracle/test/unit/src/org/netbeans/modules/cloud/oracle/actions/AddDbConnectionToVaultTest.java b/enterprise/cloud.oracle/test/unit/src/org/netbeans/modules/cloud/oracle/actions/AddDbConnectionToVaultTest.java
new file mode 100644
index 0000000..cc9ccd1
--- /dev/null
+++ b/enterprise/cloud.oracle/test/unit/src/org/netbeans/modules/cloud/oracle/actions/AddDbConnectionToVaultTest.java
@@ -0,0 +1,70 @@
+/*
+ * 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.actions;
+
+import java.awt.event.ActionEvent;
+import java.util.Map;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+import org.netbeans.modules.cloud.oracle.items.OCIItem;
+import org.netbeans.modules.cloud.oracle.vault.KeyItem;
+import org.netbeans.modules.cloud.oracle.vault.VaultItem;
+
+/**
+ *
+ * @author honza
+ */
+public class AddDbConnectionToVaultTest {
+
+ public AddDbConnectionToVaultTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() {
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ /**
+ * Test of actionPerformed method, of class AddDbConnectionToVault.
+ */
+ @Test
+ public void datasourceName() {
+ String input = "DATASOURCES_DEFAULT_USERNAME";
+ String ds = AddDbConnectionToVault.extractDatasourceName(input);
+ assertEquals("DEFAULT", ds);
+
+ }
+
+
+}
diff --git a/java/java.lsp.server/nbcode/integration/src/org/netbeans/modules/nbcode/integration/layer.xml b/java/java.lsp.server/nbcode/integration/src/org/netbeans/modules/nbcode/integration/layer.xml
index 8a4529d..225467a 100644
--- a/java/java.lsp.server/nbcode/integration/src/org/netbeans/modules/nbcode/integration/layer.xml
+++ b/java/java.lsp.server/nbcode/integration/src/org/netbeans/modules/nbcode/integration/layer.xml
@@ -52,6 +52,7 @@
<attr name="instanceCreate" methodvalue="org.netbeans.modules.java.lsp.server.explorer.NodeActionsProvider.forFile"/>
<attr name="action:org.netbeans.modules.cloud.oracle.actions.DownloadWalletAction" stringvalue="Tools"/>
<attr name="action:org.netbeans.modules.cloud.oracle.actions.AddADBAction" stringvalue="Tools"/>
+ <attr name="action:org.netbeans.modules.cloud.oracle.actions.AddDbConnectionToVault" stringvalue="Tools"/>
<attr name="action:org.netbeans.modules.cloud.oracle.actions.CreateAutonomousDBAction" stringvalue="Tools"/>
<attr name="action:org.netbeans.modules.cloud.oracle.actions.OpenServiceConsoleAction" stringvalue="Tools"/>
<attr name="action:org.netbeans.modules.cloud.oracle.actions.CloudRefresh" stringvalue="Tools"/>
diff --git a/java/java.lsp.server/vscode/package-lock.json b/java/java.lsp.server/vscode/package-lock.json
index 7bd0d70..8243353 100644
--- a/java/java.lsp.server/vscode/package-lock.json
+++ b/java/java.lsp.server/vscode/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "apache-netbeans-java",
- "version": "0.1.0",
+ "version": "19.0.301",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "apache-netbeans-java",
- "version": "0.1.0",
+ "version": "19.0.301",
"license": "Apache 2.0",
"dependencies": {
"@vscode/debugadapter": "1.55.1",
diff --git a/java/java.lsp.server/vscode/package.json b/java/java.lsp.server/vscode/package.json
index 80841e6..52534721 100644
--- a/java/java.lsp.server/vscode/package.json
+++ b/java/java.lsp.server/vscode/package.json
@@ -609,6 +609,10 @@
"title": "Open Service Console"
},
{
+ "command": "nbls:Tools:org.netbeans.modules.cloud.oracle.actions.AddDbConnectionToVault",
+ "title": "Add to OCI Vault"
+ },
+ {
"command": "java.select.editor.projects",
"title": "Reveal active editor in Projects",
"category": "Project"
@@ -726,6 +730,10 @@
"when": "false"
},
{
+ "command": "nbls:Tools:org.netbeans.modules.cloud.oracle.actions.AddDbConnectionToVault",
+ "when": "false"
+ },
+ {
"command": "java.workspace.configureRunSettings",
"when": "false"
},
@@ -844,6 +852,10 @@
"when": "viewItem =~ /class:oracle.database.DatabaseItem/"
},
{
+ "command": "nbls:Tools:org.netbeans.modules.cloud.oracle.actions.AddDbConnectionToVault",
+ "when": "viewItem =~ /class:org.netbeans.api.db.explorer.DatabaseConnection/"
+ },
+ {
"command": "nbls:Tools:org.netbeans.modules.cloud.oracle.actions.CreateAutonomousDBAction",
"when": "viewItem =~ /class:oracle.compartment.CompartmentItem/"
},
@@ -950,6 +962,18 @@
"codeicon": "database"
},
{
+ "uriExpression": "nbres:/org/netbeans/modules/cloud/oracle/resources/vault.svg",
+ "codeicon": "lock"
+ },
+ {
+ "uriExpression": "nbres:/org/netbeans/modules/cloud/oracle/resources/key.svg",
+ "codeicon": "gist-secret"
+ },
+ {
+ "uriExpression": "nbres:/org/netbeans/modules/cloud/oracle/resources/secret.svg",
+ "codeicon": "key"
+ },
+ {
"uriExpression": "nbres:/org/netbeans/modules/cloud/oracle/resources/devops_project.svg",
"codeicon": "project"
},