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" />&#10;<style
+   type="text/css"
+   id="style1">&#10;	.st0{fill:#FFFFFF;}&#10;	.st1{opacity:0.25;}&#10;	.st2{fill:#FAFAFA;}&#10;	.st3{opacity:0.33;}&#10;	.st4{fill:none;stroke:#474747;stroke-miterlimit:10;}&#10;	.st5{opacity:0.42;}&#10;	.st6{fill:#CAE3FF;}&#10;	.st7{opacity:0.2;}&#10;	.st8{opacity:0.03;}&#10;	.st9{opacity:0.1;}&#10;	.st10{opacity:0.15;}&#10;	.st11{opacity:0.45;}&#10;	.st12{fill:#FFE1B0;}&#10;	.st13{fill:#B3DBFF;}&#10;	.st14{fill:#FBDC7C;}&#10;	.st15{fill:#FFDB43;}&#10;	.st16{fill:#E79B00;}&#10;	.st17{fill:#3883CE;}&#10;	.st18{fill:none;stroke:#003399;stroke-width:1.375;stroke-miterlimit:10;}&#10;	.st19{fill:#E8513D;}&#10;	.st20{fill:#1E1E1E;}&#10;	.st21{fill:#FFC36D;}&#10;	.st22{fill:#9FCBFF;}&#10;	.st23{fill:#E9F7FF;}&#10;	.st24{fill:#62707C;}&#10;	.st25{fill:#7A8896;}&#10;	.st26{fill:#57BFFF;}&#10;	.st27{fill:#E69D35;}&#10;	.st28{fill:#9CFF73;}&#10;	.st29{fill:#4891CC;}&#10;	.st30{fill:#474747;}&#10;	.st31{fill:#CCA05E;}&#10;	.st32{opacity:0.67;}&#10;	.st33{opacity:0.3;}&#10;	.st34{fill:#EAEAEA;}&#10;	.st35{fill:#FFE945;}&#10;	.st36{fill:#FFCF8C;}&#10;	.st37{fill:#FF5252;}&#10;	.st38{opacity:0.12;}&#10;	.st39{fill:#45A5F4;}&#10;	.st40{fill:url(#SVGID_1_);}&#10;	.st41{fill:url(#SVGID_2_);}&#10;	.st42{opacity:0.05;}&#10;	.st43{fill:#3D81F5;}&#10;	.st44{fill:#CECECE;}&#10;	.st45{fill:#B5B5B5;}&#10;	.st46{opacity:0.4;}&#10;	.st47{fill:#595959;}&#10;	.st48{fill:#80FF80;}&#10;	.st49{fill:#C8FF80;}&#10;	.st50{fill:#FFEE80;}&#10;	.st51{fill:#FFA680;}&#10;	.st52{fill:#FF8080;}&#10;	.st53{fill:none;}&#10;	.st54{fill:#007AFF;}&#10;	.st55{fill:#EFFF78;}&#10;	.st56{fill:#FFDA00;}&#10;	.st57{fill:#3EADFF;}&#10;	.st58{opacity:0.67;fill:#FFFFFF;}&#10;	.st59{fill:#2E92FF;}&#10;	.st60{fill:#3AEA00;}&#10;	.st61{fill:#303030;}&#10;</style>&#10;&#10;&#10;<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" />&#10;<style
+   type="text/css"
+   id="style1">&#10;	.st0{fill:#FFFFFF;}&#10;	.st1{opacity:0.25;}&#10;	.st2{fill:#FAFAFA;}&#10;	.st3{opacity:0.33;}&#10;	.st4{fill:none;stroke:#474747;stroke-miterlimit:10;}&#10;	.st5{opacity:0.42;}&#10;	.st6{fill:#CAE3FF;}&#10;	.st7{opacity:0.2;}&#10;	.st8{opacity:0.03;}&#10;	.st9{opacity:0.1;}&#10;	.st10{opacity:0.15;}&#10;	.st11{opacity:0.45;}&#10;	.st12{fill:#FFE1B0;}&#10;	.st13{fill:#B3DBFF;}&#10;	.st14{fill:#FBDC7C;}&#10;	.st15{fill:#FFDB43;}&#10;	.st16{fill:#E79B00;}&#10;	.st17{fill:#3883CE;}&#10;	.st18{fill:none;stroke:#003399;stroke-width:1.375;stroke-miterlimit:10;}&#10;	.st19{fill:#E8513D;}&#10;	.st20{fill:#1E1E1E;}&#10;	.st21{fill:#FFC36D;}&#10;	.st22{fill:#9FCBFF;}&#10;	.st23{fill:#E9F7FF;}&#10;	.st24{fill:#62707C;}&#10;	.st25{fill:#7A8896;}&#10;	.st26{fill:#57BFFF;}&#10;	.st27{fill:#E69D35;}&#10;	.st28{fill:#9CFF73;}&#10;	.st29{fill:#4891CC;}&#10;	.st30{fill:#474747;}&#10;	.st31{fill:#CCA05E;}&#10;	.st32{opacity:0.67;}&#10;	.st33{opacity:0.3;}&#10;	.st34{fill:#EAEAEA;}&#10;	.st35{fill:#FFE945;}&#10;	.st36{fill:#FFCF8C;}&#10;	.st37{fill:#FF5252;}&#10;	.st38{opacity:0.12;}&#10;	.st39{fill:#45A5F4;}&#10;	.st40{fill:url(#SVGID_1_);}&#10;	.st41{fill:url(#SVGID_2_);}&#10;	.st42{opacity:0.05;}&#10;	.st43{fill:#3D81F5;}&#10;	.st44{fill:#CECECE;}&#10;	.st45{fill:#B5B5B5;}&#10;	.st46{opacity:0.4;}&#10;	.st47{fill:#595959;}&#10;	.st48{fill:#80FF80;}&#10;	.st49{fill:#C8FF80;}&#10;	.st50{fill:#FFEE80;}&#10;	.st51{fill:#FFA680;}&#10;	.st52{fill:#FF8080;}&#10;	.st53{fill:none;}&#10;	.st54{fill:#007AFF;}&#10;	.st55{fill:#EFFF78;}&#10;	.st56{fill:#FFDA00;}&#10;	.st57{fill:#3EADFF;}&#10;	.st58{opacity:0.67;fill:#FFFFFF;}&#10;	.st59{fill:#2E92FF;}&#10;	.st60{fill:#3AEA00;}&#10;	.st61{fill:#303030;}&#10;</style>&#10;&#10;&#10;<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" />&#10;<style
+   type="text/css"
+   id="style1">&#10;	.st0{fill:#FFFFFF;}&#10;	.st1{opacity:0.25;}&#10;	.st2{fill:#FAFAFA;}&#10;	.st3{opacity:0.33;}&#10;	.st4{fill:none;stroke:#474747;stroke-miterlimit:10;}&#10;	.st5{opacity:0.42;}&#10;	.st6{fill:#CAE3FF;}&#10;	.st7{opacity:0.2;}&#10;	.st8{opacity:0.03;}&#10;	.st9{opacity:0.1;}&#10;	.st10{opacity:0.15;}&#10;	.st11{opacity:0.45;}&#10;	.st12{fill:#FFE1B0;}&#10;	.st13{fill:#B3DBFF;}&#10;	.st14{fill:#FBDC7C;}&#10;	.st15{fill:#FFDB43;}&#10;	.st16{fill:#E79B00;}&#10;	.st17{fill:#3883CE;}&#10;	.st18{fill:none;stroke:#003399;stroke-width:1.375;stroke-miterlimit:10;}&#10;	.st19{fill:#E8513D;}&#10;	.st20{fill:#1E1E1E;}&#10;	.st21{fill:#FFC36D;}&#10;	.st22{fill:#9FCBFF;}&#10;	.st23{fill:#E9F7FF;}&#10;	.st24{fill:#62707C;}&#10;	.st25{fill:#7A8896;}&#10;	.st26{fill:#57BFFF;}&#10;	.st27{fill:#E69D35;}&#10;	.st28{fill:#9CFF73;}&#10;	.st29{fill:#4891CC;}&#10;	.st30{fill:#474747;}&#10;	.st31{fill:#CCA05E;}&#10;	.st32{opacity:0.67;}&#10;	.st33{opacity:0.3;}&#10;	.st34{fill:#EAEAEA;}&#10;	.st35{fill:#FFE945;}&#10;	.st36{fill:#FFCF8C;}&#10;	.st37{fill:#FF5252;}&#10;	.st38{opacity:0.12;}&#10;	.st39{fill:#45A5F4;}&#10;	.st40{fill:url(#SVGID_1_);}&#10;	.st41{fill:url(#SVGID_2_);}&#10;	.st42{opacity:0.05;}&#10;	.st43{fill:#3D81F5;}&#10;	.st44{fill:#CECECE;}&#10;	.st45{fill:#B5B5B5;}&#10;	.st46{opacity:0.4;}&#10;	.st47{fill:#595959;}&#10;	.st48{fill:#80FF80;}&#10;	.st49{fill:#C8FF80;}&#10;	.st50{fill:#FFEE80;}&#10;	.st51{fill:#FFA680;}&#10;	.st52{fill:#FF8080;}&#10;	.st53{fill:none;}&#10;	.st54{fill:#007AFF;}&#10;	.st55{fill:#EFFF78;}&#10;	.st56{fill:#FFDA00;}&#10;	.st57{fill:#3EADFF;}&#10;	.st58{opacity:0.67;fill:#FFFFFF;}&#10;	.st59{fill:#2E92FF;}&#10;	.st60{fill:#3AEA00;}&#10;	.st61{fill:#303030;}&#10;</style>&#10;&#10;&#10;<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"
 			},