diff --git a/command/agent/oci_end_to_end_test.go b/command/agent/oci_end_to_end_test.go
deleted file mode 100644
index e07d7ad09..000000000
--- a/command/agent/oci_end_to_end_test.go
+++ /dev/null
@@ -1,231 +0,0 @@
-// Copyright (c) HashiCorp, Inc.
-// SPDX-License-Identifier: BUSL-1.1
-
-package agent
-
-import (
- "context"
- "io/ioutil"
- "os"
- "testing"
- "time"
-
- hclog "github.com/hashicorp/go-hclog"
- vaultoci "github.com/hashicorp/vault-plugin-auth-oci"
- "github.com/hashicorp/vault/api"
- "github.com/hashicorp/vault/command/agentproxyshared/auth"
- agentoci "github.com/hashicorp/vault/command/agentproxyshared/auth/oci"
- "github.com/hashicorp/vault/command/agentproxyshared/sink"
- "github.com/hashicorp/vault/command/agentproxyshared/sink/file"
- "github.com/hashicorp/vault/helper/testhelpers"
- vaulthttp "github.com/hashicorp/vault/http"
- "github.com/hashicorp/vault/sdk/helper/logging"
- "github.com/hashicorp/vault/sdk/logical"
- "github.com/hashicorp/vault/vault"
-)
-
-const (
- envVarOCITestTenancyOCID = "OCI_TEST_TENANCY_OCID"
- envVarOCITestUserOCID = "OCI_TEST_USER_OCID"
- envVarOCITestFingerprint = "OCI_TEST_FINGERPRINT"
- envVarOCITestPrivateKeyPath = "OCI_TEST_PRIVATE_KEY_PATH"
- envVAROCITestOCIDList = "OCI_TEST_OCID_LIST"
-
- // The OCI SDK doesn't export its standard env vars so they're captured here.
- // These are used for the duration of the test to make sure the agent is able to
- // pick up creds from the env.
- //
- // To run this test, do not set these. Only the above ones need to be set.
- envVarOCITenancyOCID = "OCI_tenancy_ocid"
- envVarOCIUserOCID = "OCI_user_ocid"
- envVarOCIFingerprint = "OCI_fingerprint"
- envVarOCIPrivateKeyPath = "OCI_private_key_path"
-)
-
-func TestOCIEndToEnd(t *testing.T) {
- if !runAcceptanceTests {
- t.SkipNow()
- }
-
- // Ensure each cred is populated.
- credNames := []string{
- envVarOCITestTenancyOCID,
- envVarOCITestUserOCID,
- envVarOCITestFingerprint,
- envVarOCITestPrivateKeyPath,
- envVAROCITestOCIDList,
- }
- testhelpers.SkipUnlessEnvVarsSet(t, credNames)
-
- logger := logging.NewVaultLogger(hclog.Trace)
- coreConfig := &vault.CoreConfig{
- Logger: logger,
- CredentialBackends: map[string]logical.Factory{
- "oci": vaultoci.Factory,
- },
- }
- cluster := vault.NewTestCluster(t, coreConfig, &vault.TestClusterOptions{
- HandlerFunc: vaulthttp.Handler,
- })
- cluster.Start()
- defer cluster.Cleanup()
-
- vault.TestWaitActive(t, cluster.Cores[0].Core)
- client := cluster.Cores[0].Client
-
- // Setup Vault
- if err := client.Sys().EnableAuthWithOptions("oci", &api.EnableAuthOptions{
- Type: "oci",
- }); err != nil {
- t.Fatal(err)
- }
-
- if _, err := client.Logical().Write("auth/oci/config", map[string]interface{}{
- "home_tenancy_id": os.Getenv(envVarOCITestTenancyOCID),
- }); err != nil {
- t.Fatal(err)
- }
-
- if _, err := client.Logical().Write("auth/oci/role/test", map[string]interface{}{
- "ocid_list": os.Getenv(envVAROCITestOCIDList),
- }); err != nil {
- t.Fatal(err)
- }
-
- ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
-
- // We're going to feed oci auth creds via env variables.
- if err := setOCIEnvCreds(); err != nil {
- t.Fatal(err)
- }
- defer func() {
- if err := unsetOCIEnvCreds(); err != nil {
- t.Fatal(err)
- }
- }()
-
- vaultAddr := "http://" + cluster.Cores[0].Listeners[0].Addr().String()
-
- am, err := agentoci.NewOCIAuthMethod(&auth.AuthConfig{
- Logger: logger.Named("auth.oci"),
- MountPath: "auth/oci",
- Config: map[string]interface{}{
- "type": "apikey",
- "role": "test",
- },
- }, vaultAddr)
- if err != nil {
- t.Fatal(err)
- }
-
- ahConfig := &auth.AuthHandlerConfig{
- Logger: logger.Named("auth.handler"),
- Client: client,
- }
-
- ah := auth.NewAuthHandler(ahConfig)
- errCh := make(chan error)
- go func() {
- errCh <- ah.Run(ctx, am)
- }()
- defer func() {
- select {
- case <-ctx.Done():
- case err := <-errCh:
- if err != nil {
- t.Fatal(err)
- }
- }
- }()
-
- tmpFile, err := ioutil.TempFile("", "auth.tokensink.test.")
- if err != nil {
- t.Fatal(err)
- }
- tokenSinkFileName := tmpFile.Name()
- tmpFile.Close()
- os.Remove(tokenSinkFileName)
- t.Logf("output: %s", tokenSinkFileName)
-
- config := &sink.SinkConfig{
- Logger: logger.Named("sink.file"),
- Config: map[string]interface{}{
- "path": tokenSinkFileName,
- },
- WrapTTL: 10 * time.Second,
- }
-
- fs, err := file.NewFileSink(config)
- if err != nil {
- t.Fatal(err)
- }
- config.Sink = fs
-
- ss := sink.NewSinkServer(&sink.SinkServerConfig{
- Logger: logger.Named("sink.server"),
- Client: client,
- })
- go func() {
- errCh <- ss.Run(ctx, ah.OutputCh, []*sink.SinkConfig{config})
- }()
- defer func() {
- select {
- case <-ctx.Done():
- case err := <-errCh:
- if err != nil {
- t.Fatal(err)
- }
- }
- }()
-
- // This has to be after the other defers so it happens first. It allows
- // successful test runs to immediately cancel all of the runner goroutines
- // and unblock any of the blocking defer calls by the runner's DoneCh that
- // comes before this and avoid successful tests from taking the entire
- // timeout duration.
- defer cancel()
-
- if stat, err := os.Lstat(tokenSinkFileName); err == nil {
- t.Fatalf("expected err but got %s", stat)
- } else if !os.IsNotExist(err) {
- t.Fatal("expected notexist err")
- }
-
- // Wait 2 seconds for the env variables to be detected and an auth to be generated.
- time.Sleep(time.Second * 2)
-
- token, err := readToken(tokenSinkFileName)
- if err != nil {
- t.Fatal(err)
- }
-
- if token.Token == "" {
- t.Fatal("expected token but didn't receive it")
- }
-}
-
-func setOCIEnvCreds() error {
- if err := os.Setenv(envVarOCITenancyOCID, os.Getenv(envVarOCITestTenancyOCID)); err != nil {
- return err
- }
- if err := os.Setenv(envVarOCIUserOCID, os.Getenv(envVarOCITestUserOCID)); err != nil {
- return err
- }
- if err := os.Setenv(envVarOCIFingerprint, os.Getenv(envVarOCITestFingerprint)); err != nil {
- return err
- }
- return os.Setenv(envVarOCIPrivateKeyPath, os.Getenv(envVarOCITestPrivateKeyPath))
-}
-
-func unsetOCIEnvCreds() error {
- if err := os.Unsetenv(envVarOCITenancyOCID); err != nil {
- return err
- }
- if err := os.Unsetenv(envVarOCIUserOCID); err != nil {
- return err
- }
- if err := os.Unsetenv(envVarOCIFingerprint); err != nil {
- return err
- }
- return os.Unsetenv(envVarOCIPrivateKeyPath)
-}
diff --git a/command/agentproxyshared/auth/oci/oci.go b/command/agentproxyshared/auth/oci/oci.go
deleted file mode 100644
index 402940653..000000000
--- a/command/agentproxyshared/auth/oci/oci.go
+++ /dev/null
@@ -1,264 +0,0 @@
-// Copyright (c) HashiCorp, Inc.
-// SPDX-License-Identifier: BUSL-1.1
-
-package oci
-
-import (
- "context"
- "errors"
- "fmt"
- "net/http"
- "net/url"
- "os"
- "os/user"
- "path"
- "sync"
- "time"
-
- "github.com/hashicorp/go-hclog"
- "github.com/hashicorp/go-secure-stdlib/parseutil"
- "github.com/hashicorp/vault/api"
- "github.com/hashicorp/vault/command/agentproxyshared/auth"
- "github.com/oracle/oci-go-sdk/common"
- ociAuth "github.com/oracle/oci-go-sdk/common/auth"
-)
-
-const (
- typeAPIKey = "apikey"
- typeInstance = "instance"
-
- /*
-
- IAM creds can be inferred from instance metadata or the container
- identity service, and those creds expire at varying intervals with
- new creds becoming available at likewise varying intervals. Let's
- default to polling once a minute so all changes can be picked up
- rather quickly. This is configurable, however.
-
- */
- defaultCredCheckFreqSeconds = 60 * time.Second
-
- defaultConfigFileName = "config"
- defaultConfigDirName = ".oci"
- configFilePathEnvVarName = "OCI_CONFIG_FILE"
- secondaryConfigDirName = ".oraclebmc"
-)
-
-func NewOCIAuthMethod(conf *auth.AuthConfig, vaultAddress string) (auth.AuthMethod, error) {
- if conf == nil {
- return nil, errors.New("empty config")
- }
- if conf.Config == nil {
- return nil, errors.New("empty config data")
- }
-
- a := &ociMethod{
- logger: conf.Logger,
- vaultAddress: vaultAddress,
- mountPath: conf.MountPath,
- credsFound: make(chan struct{}),
- stopCh: make(chan struct{}),
- }
-
- typeRaw, ok := conf.Config["type"]
- if !ok {
- return nil, errors.New("missing 'type' value")
- }
- authType, ok := typeRaw.(string)
- if !ok {
- return nil, errors.New("could not convert 'type' config value to string")
- }
-
- roleRaw, ok := conf.Config["role"]
- if !ok {
- return nil, errors.New("missing 'role' value")
- }
- a.role, ok = roleRaw.(string)
- if !ok {
- return nil, errors.New("could not convert 'role' config value to string")
- }
-
- // Check for an optional custom frequency at which we should poll for creds.
- credCheckFreqSec := defaultCredCheckFreqSeconds
- if checkFreqRaw, ok := conf.Config["credential_poll_interval"]; ok {
- checkFreq, err := parseutil.ParseDurationSecond(checkFreqRaw)
- if err != nil {
- return nil, fmt.Errorf("could not parse credential_poll_interval: %v", err)
- }
- credCheckFreqSec = checkFreq
- }
-
- switch {
- case a.role == "":
- return nil, errors.New("'role' value is empty")
- case authType == "":
- return nil, errors.New("'type' value is empty")
- case authType != typeAPIKey && authType != typeInstance:
- return nil, errors.New("'type' value is invalid")
- case authType == typeAPIKey:
- defaultConfigFile := getDefaultConfigFilePath()
- homeFolder := getHomeFolder()
- secondaryConfigFile := path.Join(homeFolder, secondaryConfigDirName, defaultConfigFileName)
-
- environmentProvider := common.ConfigurationProviderEnvironmentVariables("OCI", "")
- defaultFileProvider, _ := common.ConfigurationProviderFromFile(defaultConfigFile, "")
- secondaryFileProvider, _ := common.ConfigurationProviderFromFile(secondaryConfigFile, "")
-
- provider, _ := common.ComposingConfigurationProvider([]common.ConfigurationProvider{environmentProvider, defaultFileProvider, secondaryFileProvider})
- a.configurationProvider = provider
- case authType == typeInstance:
- configurationProvider, err := ociAuth.InstancePrincipalConfigurationProvider()
- if err != nil {
- return nil, fmt.Errorf("failed to create instance principal configuration provider: %v", err)
- }
- a.configurationProvider = configurationProvider
- }
-
- // Do an initial population of the creds because we want to err right away if we can't
- // even get a first set.
- creds, err := a.configurationProvider.KeyID()
- if err != nil {
- return nil, err
- }
- a.lastCreds = creds
-
- go a.pollForCreds(credCheckFreqSec)
-
- return a, nil
-}
-
-type ociMethod struct {
- logger hclog.Logger
- vaultAddress string
- mountPath string
-
- configurationProvider common.ConfigurationProvider
- role string
-
- // These are used to share the latest creds safely across goroutines.
- credLock sync.Mutex
- lastCreds string
-
- // Notifies the outer environment that it should call Authenticate again.
- credsFound chan struct{}
-
- // Detects that the outer environment is closing.
- stopCh chan struct{}
-}
-
-func (a *ociMethod) Authenticate(context.Context, *api.Client) (string, http.Header, map[string]interface{}, error) {
- a.credLock.Lock()
- defer a.credLock.Unlock()
-
- a.logger.Trace("beginning authentication")
-
- requestPath := fmt.Sprintf("/v1/%s/login/%s", a.mountPath, a.role)
- requestURL := fmt.Sprintf("%s%s", a.vaultAddress, requestPath)
-
- request, err := http.NewRequest("GET", requestURL, nil)
- if err != nil {
- return "", nil, nil, fmt.Errorf("error creating authentication request: %w", err)
- }
-
- request.Header.Set("Date", time.Now().UTC().Format(http.TimeFormat))
-
- signer := common.DefaultRequestSigner(a.configurationProvider)
-
- err = signer.Sign(request)
- if err != nil {
- return "", nil, nil, fmt.Errorf("error signing authentication request: %w", err)
- }
-
- parsedVaultAddress, err := url.Parse(a.vaultAddress)
- if err != nil {
- return "", nil, nil, fmt.Errorf("unable to parse vault address: %w", err)
- }
-
- request.Header.Set("Host", parsedVaultAddress.Host)
- request.Header.Set("(request-target)", fmt.Sprintf("%s %s", "get", requestPath))
-
- data := map[string]interface{}{
- "request_headers": request.Header,
- }
-
- return fmt.Sprintf("%s/login/%s", a.mountPath, a.role), nil, data, nil
-}
-
-func (a *ociMethod) NewCreds() chan struct{} {
- return a.credsFound
-}
-
-func (a *ociMethod) CredSuccess() {}
-
-func (a *ociMethod) Shutdown() {
- close(a.credsFound)
- close(a.stopCh)
-}
-
-func (a *ociMethod) pollForCreds(frequency time.Duration) {
- ticker := time.NewTicker(frequency)
- defer ticker.Stop()
- for {
- select {
- case <-a.stopCh:
- a.logger.Trace("shutdown triggered, stopping OCI auth handler")
- return
- case <-ticker.C:
- if err := a.checkCreds(); err != nil {
- a.logger.Warn("unable to retrieve current creds, retaining last creds", "error", err)
- }
- }
- }
-}
-
-func (a *ociMethod) checkCreds() error {
- a.credLock.Lock()
- defer a.credLock.Unlock()
-
- a.logger.Trace("checking for new credentials")
- currentCreds, err := a.configurationProvider.KeyID()
- if err != nil {
- return err
- }
- // These will always have different pointers regardless of whether their
- // values are identical, hence the use of DeepEqual.
- if currentCreds == a.lastCreds {
- a.logger.Trace("credentials are unchanged")
- return nil
- }
- a.lastCreds = currentCreds
- a.logger.Trace("new credentials detected, triggering Authenticate")
- a.credsFound <- struct{}{}
- return nil
-}
-
-func getHomeFolder() string {
- current, e := user.Current()
- if e != nil {
- // Give up and try to return something sensible
- home, err := os.UserHomeDir()
- if err != nil {
- return ""
- }
- return home
- }
- return current.HomeDir
-}
-
-func getDefaultConfigFilePath() string {
- homeFolder := getHomeFolder()
- defaultConfigFile := path.Join(homeFolder, defaultConfigDirName, defaultConfigFileName)
- if _, err := os.Stat(defaultConfigFile); err == nil {
- return defaultConfigFile
- }
-
- // Read configuration file path from OCI_CONFIG_FILE env var
- fallbackConfigFile, existed := os.LookupEnv(configFilePathEnvVarName)
- if !existed {
- return defaultConfigFile
- }
- if _, err := os.Stat(fallbackConfigFile); os.IsNotExist(err) {
- return defaultConfigFile
- }
- return fallbackConfigFile
-}
diff --git a/command/agentproxyshared/helpers.go b/command/agentproxyshared/helpers.go
index 97442dc63..cfe08e544 100644
--- a/command/agentproxyshared/helpers.go
+++ b/command/agentproxyshared/helpers.go
@@ -19,7 +19,6 @@ import (
"github.com/hashicorp/vault/command/agentproxyshared/auth/jwt"
"github.com/hashicorp/vault/command/agentproxyshared/auth/kerberos"
"github.com/hashicorp/vault/command/agentproxyshared/auth/kubernetes"
- "github.com/hashicorp/vault/command/agentproxyshared/auth/oci"
token_file "github.com/hashicorp/vault/command/agentproxyshared/auth/token-file"
"github.com/hashicorp/vault/command/agentproxyshared/cache"
"github.com/hashicorp/vault/command/agentproxyshared/cache/cacheboltdb"
@@ -44,8 +43,6 @@ func GetAutoAuthMethodFromConfig(autoAuthMethodType string, authConfig *auth.Aut
return kubernetes.NewKubernetesAuthMethod(authConfig)
case "approle":
return approle.NewApproleAuthMethod(authConfig)
- case "oci":
- return oci.NewOCIAuthMethod(authConfig, vaultAddress)
case "token_file":
return token_file.NewTokenFileAuthMethod(authConfig)
case "pcf": // Deprecated.
diff --git a/command/commands.go b/command/commands.go
index fa71f8aa4..4eeeea942 100644
--- a/command/commands.go
+++ b/command/commands.go
@@ -30,7 +30,6 @@ import (
credCF "github.com/hashicorp/vault-plugin-auth-cf"
credOIDC "github.com/hashicorp/vault-plugin-auth-jwt"
credKerb "github.com/hashicorp/vault-plugin-auth-kerberos"
- credOCI "github.com/hashicorp/vault-plugin-auth-oci"
credCert "github.com/hashicorp/vault/builtin/credential/cert"
credGitHub "github.com/hashicorp/vault/builtin/credential/github"
credLdap "github.com/hashicorp/vault/builtin/credential/ldap"
@@ -42,7 +41,6 @@ import (
logicalDb "github.com/hashicorp/vault/builtin/logical/database"
physConsul "github.com/hashicorp/vault/physical/consul"
- physOCI "github.com/hashicorp/vault/physical/oci"
physRaft "github.com/hashicorp/vault/physical/raft"
physFile "github.com/hashicorp/vault/sdk/physical/file"
physInmem "github.com/hashicorp/vault/sdk/physical/inmem"
@@ -171,7 +169,6 @@ var (
"inmem_transactional_ha": physInmem.NewTransactionalInmemHA,
"inmem_transactional": physInmem.NewTransactionalInmem,
"inmem": physInmem.NewInmem,
- "oci": physOCI.NewBackend,
"raft": physRaft.NewRaftBackend,
}
@@ -191,7 +188,6 @@ func initCommands(ui, serverCmdUi cli.Ui, runOpts *RunOptions) map[string]cli.Co
"github": &credGitHub.CLIHandler{},
"kerberos": &credKerb.CLIHandler{},
"ldap": &credLdap.CLIHandler{},
- "oci": &credOCI.CLIHandler{},
"oidc": &credOIDC.CLIHandler{},
"okta": &credOkta.CLIHandler{},
"pcf": &credCF.CLIHandler{}, // Deprecated.
diff --git a/go.mod b/go.mod
index 9e5605c3b..1209a5cf0 100644
--- a/go.mod
+++ b/go.mod
@@ -63,7 +63,6 @@ require (
github.com/hashicorp/go-kms-wrapping/v2 v2.0.10
github.com/hashicorp/go-kms-wrapping/wrappers/aead/v2 v2.0.7-1
github.com/hashicorp/go-kms-wrapping/wrappers/awskms/v2 v2.0.7
- github.com/hashicorp/go-kms-wrapping/wrappers/ocikms/v2 v2.0.7
github.com/hashicorp/go-kms-wrapping/wrappers/transit/v2 v2.0.7
github.com/hashicorp/go-memdb v1.3.4
github.com/hashicorp/go-msgpack v1.1.5
@@ -103,7 +102,6 @@ require (
github.com/hashicorp/vault-plugin-auth-jwt v0.16.1
github.com/hashicorp/vault-plugin-auth-kerberos v0.10.0
github.com/hashicorp/vault-plugin-auth-kubernetes v0.16.0
- github.com/hashicorp/vault-plugin-auth-oci v0.14.0
github.com/hashicorp/vault-plugin-mock v0.16.1
github.com/hashicorp/vault-plugin-secrets-ad v0.16.0
github.com/hashicorp/vault-plugin-secrets-kubernetes v0.5.0
@@ -139,7 +137,6 @@ require (
github.com/natefinch/atomic v0.0.0-20150920032501-a62ce929ffcc
github.com/oklog/run v1.1.0
github.com/okta/okta-sdk-golang/v2 v2.12.1
- github.com/oracle/oci-go-sdk v24.3.0+incompatible
github.com/ory/dockertest v3.3.5+incompatible
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/pires/go-proxyproto v0.6.1
@@ -324,7 +321,6 @@ require (
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b // indirect
github.com/opencontainers/runc v1.2.0-rc.1 // indirect
- github.com/oracle/oci-go-sdk/v60 v60.0.0 // indirect
github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c // indirect
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect
github.com/pierrec/lz4 v2.6.1+incompatible // indirect
@@ -339,7 +335,6 @@ require (
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect
github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d // indirect
- github.com/sony/gobreaker v0.4.2-0.20210216022020-dd874f9dd33b // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/objx v0.5.2 // indirect
diff --git a/go.sum b/go.sum
index 4f032f7fa..f75c9d71a 100644
--- a/go.sum
+++ b/go.sum
@@ -1896,8 +1896,6 @@ github.com/hashicorp/go-kms-wrapping/wrappers/aead/v2 v2.0.7-1 h1:ZV26VJYcITBom0
github.com/hashicorp/go-kms-wrapping/wrappers/aead/v2 v2.0.7-1/go.mod h1:b99cDSA+OzcyRoBZroSf174/ss/e6gUuS45wue9ZQfc=
github.com/hashicorp/go-kms-wrapping/wrappers/awskms/v2 v2.0.7 h1:E3eEWpkofgPNrYyYznfS1+drq4/jFcqHQVNcL7WhUCo=
github.com/hashicorp/go-kms-wrapping/wrappers/awskms/v2 v2.0.7/go.mod h1:j5vefRoguQUG7iM4reS/hKIZssU1lZRqNPM5Wow6UnM=
-github.com/hashicorp/go-kms-wrapping/wrappers/ocikms/v2 v2.0.7 h1:KeG3QGrbxbr2qAqCJdf3NR4ijAYwdcWLTmwSbR0yusM=
-github.com/hashicorp/go-kms-wrapping/wrappers/ocikms/v2 v2.0.7/go.mod h1:rXxYzjjGw4HltEwxPp9zYSRIo6R+rBf1MSPk01bvodc=
github.com/hashicorp/go-kms-wrapping/wrappers/transit/v2 v2.0.7 h1:G25tZFw/LrAzJWxvS0/BFI7V1xAP/UsAIsgBwiE0mwo=
github.com/hashicorp/go-kms-wrapping/wrappers/transit/v2 v2.0.7/go.mod h1:hxNA5oTfAvwPacWVg1axtF/lvTafwlAa6a6K4uzWHhw=
github.com/hashicorp/go-memdb v1.3.4 h1:XSL3NR682X/cVk2IeV0d70N4DZ9ljI885xAEU8IoK3c=
@@ -2033,8 +2031,6 @@ github.com/hashicorp/vault-plugin-auth-kerberos v0.10.0 h1:YH2x9kIV0jKXk22tVkpyd
github.com/hashicorp/vault-plugin-auth-kerberos v0.10.0/go.mod h1:I6ulXug4oxx77DFYjqI1kVl+72TgXEo3Oju4tTOVfU4=
github.com/hashicorp/vault-plugin-auth-kubernetes v0.16.0 h1:vuXNJvtMyoqQ01Sfwf2TNcJNkGcxP1vD3C7gpvuVkCU=
github.com/hashicorp/vault-plugin-auth-kubernetes v0.16.0/go.mod h1:onx9W/rDwENQkN+1yEnJvS51PVkkGAPOBXasne7lnnk=
-github.com/hashicorp/vault-plugin-auth-oci v0.14.0 h1:B7uyigqgUAO3gebvi8mMmsq7l4QAG0bLEP6rAKyDVuw=
-github.com/hashicorp/vault-plugin-auth-oci v0.14.0/go.mod h1:SYdTtQhzMxqOCbdC0E0UOrkc4eGXXcJmXXbe1MHVPtE=
github.com/hashicorp/vault-plugin-mock v0.16.1 h1:5QQvSUHxDjEEbrd2REOeacqyJnCLPD51IQzy71hx8P0=
github.com/hashicorp/vault-plugin-mock v0.16.1/go.mod h1:83G4JKlOwUtxVourn5euQfze3ZWyXcUiLj2wqrKSDIM=
github.com/hashicorp/vault-plugin-secrets-ad v0.16.0 h1:6RCpd2PbBvmi5xmxXhggE0Xv+/Gag896/NNZeMKH+8A=
@@ -2525,10 +2521,6 @@ github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuh
github.com/opencontainers/selinux v1.10.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
-github.com/oracle/oci-go-sdk v24.3.0+incompatible h1:x4mcfb4agelf1O4/1/auGlZ1lr97jXRSSN5MxTgG/zU=
-github.com/oracle/oci-go-sdk v24.3.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888=
-github.com/oracle/oci-go-sdk/v60 v60.0.0 h1:EJAWjEi4SY5Raha6iUzq4LTQ0uM5YFw/wat/L1ehIEM=
-github.com/oracle/oci-go-sdk/v60 v60.0.0/go.mod h1:krz+2gkSzlSL/L4PvP0Z9pZpag9HYLNtsMd1PmxlA2w=
github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA=
github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs=
github.com/ory/dockertest/v3 v3.10.0 h1:4K3z2VMe8Woe++invjaTB7VRyQXQy5UY+loujO4aNE4=
@@ -2724,8 +2716,6 @@ github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d h1:bVQRCxQv
github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d/go.mod h1:Cw4GTlQccdRGSEf6KiMju767x0NEHE0YIVPJSaXjlsw=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
-github.com/sony/gobreaker v0.4.2-0.20210216022020-dd874f9dd33b h1:br+bPNZsJWKicw/5rALEo67QHs5weyD5tf8WST+4sJ0=
-github.com/sony/gobreaker v0.4.2-0.20210216022020-dd874f9dd33b/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
diff --git a/helper/builtinplugins/registry.go b/helper/builtinplugins/registry.go
index 9e1e7c54b..d87d7cfb2 100644
--- a/helper/builtinplugins/registry.go
+++ b/helper/builtinplugins/registry.go
@@ -11,7 +11,6 @@ import (
credJWT "github.com/hashicorp/vault-plugin-auth-jwt"
credKerb "github.com/hashicorp/vault-plugin-auth-kerberos"
credKube "github.com/hashicorp/vault-plugin-auth-kubernetes"
- credOCI "github.com/hashicorp/vault-plugin-auth-oci"
logicalAd "github.com/hashicorp/vault-plugin-secrets-ad/plugin"
logicalKube "github.com/hashicorp/vault-plugin-secrets-kubernetes"
logicalKv "github.com/hashicorp/vault-plugin-secrets-kv"
@@ -92,7 +91,6 @@ func newRegistry() *registry {
"kerberos": {Factory: credKerb.Factory},
"kubernetes": {Factory: credKube.Factory},
"ldap": {Factory: credLdap.Factory},
- "oci": {Factory: credOCI.Factory},
"oidc": {Factory: credJWT.Factory},
"okta": {Factory: credOkta.Factory},
"pcf": {
diff --git a/internalshared/configutil/kms.go b/internalshared/configutil/kms.go
index 998048b59..f2c08abf9 100644
--- a/internalshared/configutil/kms.go
+++ b/internalshared/configutil/kms.go
@@ -14,7 +14,6 @@ import (
"github.com/hashicorp/go-hclog"
wrapping "github.com/hashicorp/go-kms-wrapping/v2"
aeadwrapper "github.com/hashicorp/go-kms-wrapping/wrappers/aead/v2"
- "github.com/hashicorp/go-kms-wrapping/wrappers/ocikms/v2"
"github.com/hashicorp/go-kms-wrapping/wrappers/transit/v2"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/go-secure-stdlib/parseutil"
@@ -171,11 +170,6 @@ func configureWrapper(configKMS *KMS, infoKeys *[]string, info *map[string]strin
case wrapping.WrapperTypeAead:
wrapper, kmsInfo, err = GetAEADKMSFunc(configKMS, opts...)
- case wrapping.WrapperTypeOciKms:
- if keyId, ok := configKMS.Config["key_id"]; ok {
- opts = append(opts, wrapping.WithKeyId(keyId))
- }
- wrapper, kmsInfo, err = GetOCIKMSKMSFunc(configKMS, opts...)
case wrapping.WrapperTypeTransit:
wrapper, kmsInfo, err = GetTransitKMSFunc(configKMS, opts...)
@@ -217,22 +211,6 @@ func GetAEADKMSFunc(kms *KMS, opts ...wrapping.Option) (wrapping.Wrapper, map[st
return wrapper, info, nil
}
-func GetOCIKMSKMSFunc(kms *KMS, opts ...wrapping.Option) (wrapping.Wrapper, map[string]string, error) {
- wrapper := ocikms.NewWrapper()
- wrapperInfo, err := wrapper.SetConfig(context.Background(), append(opts, wrapping.WithConfigMap(kms.Config))...)
- if err != nil {
- return nil, nil, err
- }
- info := make(map[string]string)
- if wrapperInfo != nil {
- info["OCI KMS KeyID"] = wrapperInfo.Metadata[ocikms.KmsConfigKeyId]
- info["OCI KMS Crypto Endpoint"] = wrapperInfo.Metadata[ocikms.KmsConfigCryptoEndpoint]
- info["OCI KMS Management Endpoint"] = wrapperInfo.Metadata[ocikms.KmsConfigManagementEndpoint]
- info["OCI KMS Principal Type"] = wrapperInfo.Metadata["principal_type"]
- }
- return wrapper, info, nil
-}
-
var GetTransitKMSFunc = func(kms *KMS, opts ...wrapping.Option) (wrapping.Wrapper, map[string]string, error) {
wrapper := transit.NewWrapper()
wrapperInfo, err := wrapper.SetConfig(context.Background(), append(opts, wrapping.WithConfigMap(kms.Config))...)
diff --git a/physical/oci/oci.go b/physical/oci/oci.go
deleted file mode 100644
index 3665813d0..000000000
--- a/physical/oci/oci.go
+++ /dev/null
@@ -1,384 +0,0 @@
-// Copyright © 2019, Oracle and/or its affiliates.
-package oci
-
-import (
- "bytes"
- "errors"
- "fmt"
- "io/ioutil"
- "net/http"
- "sort"
- "strconv"
- "strings"
- "time"
-
- "github.com/armon/go-metrics"
- log "github.com/hashicorp/go-hclog"
- "github.com/hashicorp/go-secure-stdlib/strutil"
- "github.com/hashicorp/go-uuid"
- "github.com/hashicorp/vault/sdk/physical"
- "github.com/oracle/oci-go-sdk/common"
- "github.com/oracle/oci-go-sdk/common/auth"
- "github.com/oracle/oci-go-sdk/objectstorage"
- "golang.org/x/net/context"
-)
-
-// Verify Backend satisfies the correct interfaces
-var _ physical.Backend = (*Backend)(nil)
-
-const (
- // Limits maximum outstanding requests
- MaxNumberOfPermits = 256
-)
-
-var (
- metricDelete = []string{"oci", "delete"}
- metricGet = []string{"oci", "get"}
- metricList = []string{"oci", "list"}
- metricPut = []string{"oci", "put"}
- metricDeleteFull = []string{"oci", "deleteFull"}
- metricGetFull = []string{"oci", "getFull"}
- metricListFull = []string{"oci", "listFull"}
- metricPutFull = []string{"oci", "putFull"}
-
- metricDeleteHa = []string{"oci", "deleteHa"}
- metricGetHa = []string{"oci", "getHa"}
- metricPutHa = []string{"oci", "putHa"}
-
- metricDeleteAcquirePool = []string{"oci", "deleteAcquirePool"}
- metricGetAcquirePool = []string{"oci", "getAcquirePool"}
- metricListAcquirePool = []string{"oci", "listAcquirePool"}
- metricPutAcquirePool = []string{"oci", "putAcquirePool"}
-
- metricDeleteFailed = []string{"oci", "deleteFailed"}
- metricGetFailed = []string{"oci", "getFailed"}
- metricListFailed = []string{"oci", "listFailed"}
- metricPutFailed = []string{"oci", "putFailed"}
- metricHaWatchLockRetriable = []string{"oci", "haWatchLockRetriable"}
- metricPermitsUsed = []string{"oci", "permitsUsed"}
-
- metric5xx = []string{"oci", "5xx"}
-)
-
-type Backend struct {
- client *objectstorage.ObjectStorageClient
- bucketName string
- logger log.Logger
- permitPool *physical.PermitPool
- namespaceName string
- haEnabled bool
- lockBucketName string
-}
-
-func NewBackend(conf map[string]string, logger log.Logger) (physical.Backend, error) {
- bucketName := conf["bucket_name"]
- if bucketName == "" {
- return nil, errors.New("missing bucket name")
- }
-
- namespaceName := conf["namespace_name"]
- if bucketName == "" {
- return nil, errors.New("missing namespace name")
- }
-
- lockBucketName := ""
- haEnabled := false
- var err error
- haEnabledStr := conf["ha_enabled"]
- if haEnabledStr != "" {
- haEnabled, err = strconv.ParseBool(haEnabledStr)
- if err != nil {
- return nil, fmt.Errorf("failed to parse HA enabled: %w", err)
- }
-
- if haEnabled {
- lockBucketName = conf["lock_bucket_name"]
- if lockBucketName == "" {
- return nil, errors.New("missing lock bucket name")
- }
- }
- }
-
- authTypeAPIKeyBool := false
- authTypeAPIKeyStr := conf["auth_type_api_key"]
- if authTypeAPIKeyStr != "" {
- authTypeAPIKeyBool, err = strconv.ParseBool(authTypeAPIKeyStr)
- if err != nil {
- return nil, fmt.Errorf("failed parsing auth_type_api_key parameter: %w", err)
- }
- }
-
- var cp common.ConfigurationProvider
- if authTypeAPIKeyBool {
- cp = common.DefaultConfigProvider()
- } else {
- cp, err = auth.InstancePrincipalConfigurationProvider()
- if err != nil {
- return nil, fmt.Errorf("failed creating InstancePrincipalConfigurationProvider: %w", err)
- }
- }
-
- objectStorageClient, err := objectstorage.NewObjectStorageClientWithConfigurationProvider(cp)
- if err != nil {
- return nil, fmt.Errorf("failed creating NewObjectStorageClientWithConfigurationProvider: %w", err)
- }
-
- region := conf["region"]
- if region != "" {
- objectStorageClient.SetRegion(region)
- }
-
- logger.Debug("configuration",
- "bucket_name", bucketName,
- "region", region,
- "namespace_name", namespaceName,
- "ha_enabled", haEnabled,
- "lock_bucket_name", lockBucketName,
- "auth_type_api_key", authTypeAPIKeyBool,
- )
-
- return &Backend{
- client: &objectStorageClient,
- bucketName: bucketName,
- logger: logger,
- permitPool: physical.NewPermitPool(MaxNumberOfPermits),
- namespaceName: namespaceName,
- haEnabled: haEnabled,
- lockBucketName: lockBucketName,
- }, nil
-}
-
-func (o *Backend) Put(ctx context.Context, entry *physical.Entry) error {
- o.logger.Debug("PUT started")
- defer metrics.MeasureSince(metricPutFull, time.Now())
- startAcquirePool := time.Now()
- metrics.SetGauge(metricPermitsUsed, float32(o.permitPool.CurrentPermits()))
- o.permitPool.Acquire()
- defer o.permitPool.Release()
- metrics.MeasureSince(metricPutAcquirePool, startAcquirePool)
-
- defer metrics.MeasureSince(metricPut, time.Now())
- size := int64(len(entry.Value))
- opcClientRequestId, err := uuid.GenerateUUID()
- if err != nil {
- metrics.IncrCounter(metricPutFailed, 1)
- o.logger.Error("failed to generate UUID")
- return fmt.Errorf("failed to generate UUID: %w", err)
- }
-
- o.logger.Debug("PUT", "opc-client-request-id", opcClientRequestId)
- request := objectstorage.PutObjectRequest{
- NamespaceName: &o.namespaceName,
- BucketName: &o.bucketName,
- ObjectName: &entry.Key,
- ContentLength: &size,
- PutObjectBody: ioutil.NopCloser(bytes.NewReader(entry.Value)),
- OpcMeta: nil,
- OpcClientRequestId: &opcClientRequestId,
- }
-
- resp, err := o.client.PutObject(ctx, request)
- if resp.RawResponse != nil && resp.RawResponse.Body != nil {
- defer resp.RawResponse.Body.Close()
- }
-
- if err != nil {
- metrics.IncrCounter(metricPutFailed, 1)
- return fmt.Errorf("failed to put data: %w", err)
- }
-
- o.logRequest("PUT", resp.RawResponse, resp.OpcClientRequestId, resp.OpcRequestId, err)
- o.logger.Debug("PUT completed")
-
- return nil
-}
-
-func (o *Backend) Get(ctx context.Context, key string) (*physical.Entry, error) {
- o.logger.Debug("GET started")
- defer metrics.MeasureSince(metricGetFull, time.Now())
- metrics.SetGauge(metricPermitsUsed, float32(o.permitPool.CurrentPermits()))
- startAcquirePool := time.Now()
- o.permitPool.Acquire()
- defer o.permitPool.Release()
- metrics.MeasureSince(metricGetAcquirePool, startAcquirePool)
-
- defer metrics.MeasureSince(metricGet, time.Now())
- opcClientRequestId, err := uuid.GenerateUUID()
- if err != nil {
- o.logger.Error("failed to generate UUID")
- return nil, fmt.Errorf("failed to generate UUID: %w", err)
- }
- o.logger.Debug("GET", "opc-client-request-id", opcClientRequestId)
- request := objectstorage.GetObjectRequest{
- NamespaceName: &o.namespaceName,
- BucketName: &o.bucketName,
- ObjectName: &key,
- OpcClientRequestId: &opcClientRequestId,
- }
-
- resp, err := o.client.GetObject(ctx, request)
- if resp.RawResponse != nil && resp.RawResponse.Body != nil {
- defer resp.RawResponse.Body.Close()
- }
- o.logRequest("GET", resp.RawResponse, resp.OpcClientRequestId, resp.OpcRequestId, err)
-
- if err != nil {
- if resp.RawResponse != nil && resp.RawResponse.StatusCode == http.StatusNotFound {
- return nil, nil
- }
- metrics.IncrCounter(metricGetFailed, 1)
- return nil, fmt.Errorf("failed to read Value: %w", err)
- }
-
- body, err := ioutil.ReadAll(resp.Content)
- if err != nil {
- metrics.IncrCounter(metricGetFailed, 1)
- return nil, fmt.Errorf("failed to decode Value into bytes: %w", err)
- }
-
- o.logger.Debug("GET completed")
-
- return &physical.Entry{
- Key: key,
- Value: body,
- }, nil
-}
-
-func (o *Backend) Delete(ctx context.Context, key string) error {
- o.logger.Debug("DELETE started")
- defer metrics.MeasureSince(metricDeleteFull, time.Now())
- metrics.SetGauge(metricPermitsUsed, float32(o.permitPool.CurrentPermits()))
- startAcquirePool := time.Now()
- o.permitPool.Acquire()
- defer o.permitPool.Release()
- metrics.MeasureSince(metricDeleteAcquirePool, startAcquirePool)
-
- defer metrics.MeasureSince(metricDelete, time.Now())
- opcClientRequestId, err := uuid.GenerateUUID()
- if err != nil {
- o.logger.Error("Delete: error generating UUID")
- return fmt.Errorf("failed to generate UUID: %w", err)
- }
- o.logger.Debug("Delete", "opc-client-request-id", opcClientRequestId)
- request := objectstorage.DeleteObjectRequest{
- NamespaceName: &o.namespaceName,
- BucketName: &o.bucketName,
- ObjectName: &key,
- OpcClientRequestId: &opcClientRequestId,
- }
-
- resp, err := o.client.DeleteObject(ctx, request)
- if resp.RawResponse != nil && resp.RawResponse.Body != nil {
- defer resp.RawResponse.Body.Close()
- }
-
- o.logRequest("DELETE", resp.RawResponse, resp.OpcClientRequestId, resp.OpcRequestId, err)
-
- if err != nil {
- if resp.RawResponse != nil && resp.RawResponse.StatusCode == http.StatusNotFound {
- return nil
- }
- metrics.IncrCounter(metricDeleteFailed, 1)
- return fmt.Errorf("failed to delete Key: %w", err)
- }
- o.logger.Debug("DELETE completed")
-
- return nil
-}
-
-func (o *Backend) List(ctx context.Context, prefix string) ([]string, error) {
- o.logger.Debug("LIST started")
- defer metrics.MeasureSince(metricListFull, time.Now())
- metrics.SetGauge(metricPermitsUsed, float32(o.permitPool.CurrentPermits()))
- startAcquirePool := time.Now()
- o.permitPool.Acquire()
- defer o.permitPool.Release()
-
- metrics.MeasureSince(metricListAcquirePool, startAcquirePool)
- defer metrics.MeasureSince(metricList, time.Now())
- var keys []string
- delimiter := "/"
- var start *string
-
- for {
- opcClientRequestId, err := uuid.GenerateUUID()
- if err != nil {
- o.logger.Error("List: error generating UUID")
- return nil, fmt.Errorf("failed to generate UUID %w", err)
- }
- o.logger.Debug("LIST", "opc-client-request-id", opcClientRequestId)
- request := objectstorage.ListObjectsRequest{
- NamespaceName: &o.namespaceName,
- BucketName: &o.bucketName,
- Prefix: &prefix,
- Delimiter: &delimiter,
- Start: start,
- OpcClientRequestId: &opcClientRequestId,
- }
-
- resp, err := o.client.ListObjects(ctx, request)
- o.logRequest("LIST", resp.RawResponse, resp.OpcClientRequestId, resp.OpcRequestId, err)
-
- if err != nil {
- metrics.IncrCounter(metricListFailed, 1)
- return nil, fmt.Errorf("failed to list using prefix: %w", err)
- }
-
- for _, commonPrefix := range resp.Prefixes {
- commonPrefix := strings.TrimPrefix(commonPrefix, prefix)
- keys = append(keys, commonPrefix)
- }
-
- for _, object := range resp.Objects {
- key := strings.TrimPrefix(*object.Name, prefix)
- keys = append(keys, key)
- }
-
- // Duplicate keys are not expected
- keys = strutil.RemoveDuplicates(keys, false)
-
- if resp.NextStartWith == nil {
- resp.RawResponse.Body.Close()
- break
- }
-
- start = resp.NextStartWith
- resp.RawResponse.Body.Close()
- }
-
- sort.Strings(keys)
- o.logger.Debug("LIST completed")
- return keys, nil
-}
-
-func (o *Backend) logRequest(operation string, response *http.Response, clientOpcRequestIdPtr *string, opcRequestIdPtr *string, err error) {
- statusCode := 0
- clientOpcRequestId := " "
- opcRequestId := " "
-
- if response != nil {
- statusCode = response.StatusCode
- if statusCode/100 == 5 {
- metrics.IncrCounter(metric5xx, 1)
- }
- }
-
- if clientOpcRequestIdPtr != nil {
- clientOpcRequestId = *clientOpcRequestIdPtr
- }
-
- if opcRequestIdPtr != nil {
- opcRequestId = *opcRequestIdPtr
- }
-
- statusCodeStr := "No response"
- if statusCode != 0 {
- statusCodeStr = strconv.Itoa(statusCode)
- }
-
- logLine := fmt.Sprintf("%s client:opc-request-id %s opc-request-id: %s status-code: %s",
- operation, clientOpcRequestId, opcRequestId, statusCodeStr)
- if err != nil && statusCode/100 == 5 {
- o.logger.Error(logLine, "error", err)
- }
-}
diff --git a/physical/oci/oci_ha.go b/physical/oci/oci_ha.go
deleted file mode 100644
index a4c6ad52e..000000000
--- a/physical/oci/oci_ha.go
+++ /dev/null
@@ -1,551 +0,0 @@
-// Copyright © 2019, Oracle and/or its affiliates.
-package oci
-
-import (
- "bytes"
- "context"
- "encoding/json"
- "errors"
- "fmt"
- "io/ioutil"
- "net/http"
- "sync"
- "sync/atomic"
- "time"
-
- "github.com/armon/go-metrics"
- "github.com/hashicorp/go-uuid"
- "github.com/hashicorp/vault/sdk/physical"
- "github.com/oracle/oci-go-sdk/objectstorage"
-)
-
-// The lock implementation below prioritizes ensuring that there are not 2 primary at any given point in time
-// over high availability of the primary instance
-
-// Verify Backend satisfies the correct interfaces
-var (
- _ physical.HABackend = (*Backend)(nil)
- _ physical.Lock = (*Lock)(nil)
-)
-
-const (
- // LockRenewInterval is the time to wait between lock renewals.
- LockRenewInterval = 3 * time.Second
-
- // LockRetryInterval is the amount of time to wait if the lock fails before trying again.
- LockRetryInterval = 5 * time.Second
-
- // LockWatchRetryInterval is the amount of time to wait if a watch fails before trying again.
- LockWatchRetryInterval = 2 * time.Second
-
- // LockTTL is the default lock TTL.
- LockTTL = 15 * time.Second
-
- // LockWatchRetryMax is the number of times to retry a failed watch before signaling that leadership is lost.
- LockWatchRetryMax = 4
-
- // LockCacheMinAcceptableAge is minimum cache age in seconds to determine that its safe for a secondary instance
- // to acquire lock.
- LockCacheMinAcceptableAge = 45 * time.Second
-
- // LockWriteRetriesOnFailures is the number of retries that are made on write 5xx failures.
- LockWriteRetriesOnFailures = 4
-
- ObjectStorageCallsReadTimeout = 3 * time.Second
-
- ObjectStorageCallsWriteTimeout = 3 * time.Second
-)
-
-type LockCache struct {
- // ETag values are unique identifiers generated by the OCI service and changed every time the object is modified.
- etag string
- lastUpdate time.Time
- lockRecord *LockRecord
-}
-
-type Lock struct {
- // backend is the underlying physical backend.
- backend *Backend
-
- // Key is the name of the Key. Value is the Value of the Key.
- key, value string
-
- // held is a boolean indicating if the lock is currently held.
- held bool
-
- // Identity is the internal Identity of this Key (unique to this server instance).
- identity string
-
- internalLock sync.Mutex
-
- // stopCh is the channel that stops all operations. It may be closed in the
- // event of a leader loss or graceful shutdown. stopped is a boolean
- // indicating if we are stopped - it exists to prevent double closing the
- // channel. stopLock is a mutex around the locks.
- stopCh chan struct{}
- stopped bool
- stopLock sync.Mutex
-
- lockRecordCache atomic.Value
-
- // Allow modifying the Lock durations for ease of unit testing.
- renewInterval time.Duration
- retryInterval time.Duration
- ttl time.Duration
- watchRetryInterval time.Duration
- watchRetryMax int
-}
-
-type LockRecord struct {
- Key string
- Value string
- Identity string
-}
-
-var (
- metricLockUnlock = []string{"oci", "lock", "unlock"}
- metricLockLock = []string{"oci", "lock", "lock"}
- metricLockValue = []string{"oci", "lock", "Value"}
- metricLeaderValue = []string{"oci", "leader", "Value"}
-)
-
-func (b *Backend) HAEnabled() bool {
- return b.haEnabled
-}
-
-// LockWith acquires a mutual exclusion based on the given Key.
-func (b *Backend) LockWith(key, value string) (physical.Lock, error) {
- identity, err := uuid.GenerateUUID()
- if err != nil {
- return nil, fmt.Errorf("Lock with: %w", err)
- }
- return &Lock{
- backend: b,
- key: key,
- value: value,
- identity: identity,
- stopped: true,
-
- renewInterval: LockRenewInterval,
- retryInterval: LockRetryInterval,
- ttl: LockTTL,
- watchRetryInterval: LockWatchRetryInterval,
- watchRetryMax: LockWatchRetryMax,
- }, nil
-}
-
-func (l *Lock) Lock(stopCh <-chan struct{}) (<-chan struct{}, error) {
- l.backend.logger.Debug("Lock() called")
- defer metrics.MeasureSince(metricLockLock, time.Now().UTC())
- l.internalLock.Lock()
- defer l.internalLock.Unlock()
- if l.held {
- return nil, errors.New("lock already held")
- }
-
- // Attempt to lock - this function blocks until a lock is acquired or an error
- // occurs.
- acquired, err := l.attemptLock(stopCh)
- if err != nil {
- return nil, fmt.Errorf("lock: %w", err)
- }
- if !acquired {
- return nil, nil
- }
-
- // We have the lock now
- l.held = true
-
- // Build the locks
- l.stopLock.Lock()
- l.stopCh = make(chan struct{})
- l.stopped = false
- l.stopLock.Unlock()
-
- // Periodically renew and watch the lock
- go l.renewLock()
- go l.watchLock()
-
- return l.stopCh, nil
-}
-
-// attemptLock attempts to acquire a lock. If the given channel is closed, the
-// acquisition attempt stops. This function returns when a lock is acquired or
-// an error occurs.
-func (l *Lock) attemptLock(stopCh <-chan struct{}) (bool, error) {
- l.backend.logger.Debug("AttemptLock() called")
- ticker := time.NewTicker(l.retryInterval)
- defer ticker.Stop()
-
- for {
- select {
- case <-ticker.C:
- acquired, err := l.writeLock()
- if err != nil {
- return false, fmt.Errorf("attempt lock: %w", err)
- }
- if !acquired {
- continue
- }
-
- return true, nil
- case <-stopCh:
- return false, nil
- }
- }
-}
-
-// renewLock renews the given lock until the channel is closed.
-func (l *Lock) renewLock() {
- l.backend.logger.Debug("RenewLock() called")
- ticker := time.NewTicker(l.renewInterval)
- defer ticker.Stop()
-
- for {
- select {
- case <-ticker.C:
- l.writeLock()
- case <-l.stopCh:
- return
- }
- }
-}
-
-func loadLockRecordCache(l *Lock) *LockCache {
- lockRecordCache := l.lockRecordCache.Load()
- if lockRecordCache == nil {
- return nil
- }
- return lockRecordCache.(*LockCache)
-}
-
-// watchLock checks whether the lock has changed in the table and closes the
-// leader channel accordingly. If an error occurs during the check, watchLock
-// will retry the operation and then close the leader channel if it can't
-// succeed after retries.
-func (l *Lock) watchLock() {
- l.backend.logger.Debug("WatchLock() called")
- retries := 0
- ticker := time.NewTicker(l.watchRetryInterval)
- defer ticker.Stop()
-
-OUTER:
- for {
- // Check if the channel is already closed
- select {
- case <-l.stopCh:
- l.backend.logger.Debug("WatchLock():Stop lock signaled/closed.")
- break OUTER
- default:
- }
-
- // Check if we've exceeded retries
- if retries >= l.watchRetryMax-1 {
- l.backend.logger.Debug("WatchLock: Failed to get lock data from object storage. Giving up the lease after max retries")
- break OUTER
- }
-
- // Wait for the timer
- select {
- case <-ticker.C:
- case <-l.stopCh:
- break OUTER
- }
-
- lockRecordCache := loadLockRecordCache(l)
- if (lockRecordCache == nil) ||
- (lockRecordCache.lockRecord == nil) ||
- (lockRecordCache.lockRecord.Identity != l.identity) ||
- (time.Now().Sub(lockRecordCache.lastUpdate) > l.ttl) {
- l.backend.logger.Debug("WatchLock: Lock record cache is nil, stale or does not belong to self.")
- break OUTER
- }
-
- lockRecord, _, err := l.get(context.Background())
- if err != nil {
- retries++
- l.backend.logger.Debug("WatchLock: Failed to get lock data from object storage. Retrying..")
- metrics.SetGauge(metricHaWatchLockRetriable, 1)
- continue
- }
-
- if (lockRecord == nil) || (lockRecord.Identity != l.identity) {
- l.backend.logger.Debug("WatchLock: Lock record cache is nil or does not belong to self.")
- break OUTER
- }
-
- // reset retries counter on success
- retries = 0
- l.backend.logger.Debug("WatchLock() successful")
- metrics.SetGauge(metricHaWatchLockRetriable, 0)
- }
-
- l.stopLock.Lock()
- defer l.stopLock.Unlock()
- if !l.stopped {
- l.stopped = true
- l.backend.logger.Debug("Closing the stop channel to give up leadership.")
- close(l.stopCh)
- }
-}
-
-func (l *Lock) Unlock() error {
- l.backend.logger.Debug("Unlock() called")
- defer metrics.MeasureSince(metricLockUnlock, time.Now().UTC())
-
- l.internalLock.Lock()
- defer l.internalLock.Unlock()
- if !l.held {
- return nil
- }
-
- // Stop any existing locking or renewal attempts
- l.stopLock.Lock()
- if !l.stopped {
- l.stopped = true
- close(l.stopCh)
- }
- l.stopLock.Unlock()
-
- // We are no longer holding the lock
- l.held = false
-
- // Get current lock record
- currentLockRecord, etag, err := l.get(context.Background())
- if err != nil {
- return fmt.Errorf("error reading lock record: %w", err)
- }
-
- if currentLockRecord != nil && currentLockRecord.Identity == l.identity {
-
- defer metrics.MeasureSince(metricDeleteHa, time.Now())
- opcClientRequestId, err := uuid.GenerateUUID()
- if err != nil {
- l.backend.logger.Debug("Unlock: error generating UUID")
- return fmt.Errorf("failed to generate UUID: %w", err)
- }
- l.backend.logger.Debug("Unlock", "opc-client-request-id", opcClientRequestId)
- request := objectstorage.DeleteObjectRequest{
- NamespaceName: &l.backend.namespaceName,
- BucketName: &l.backend.lockBucketName,
- ObjectName: &l.key,
- IfMatch: &etag,
- OpcClientRequestId: &opcClientRequestId,
- }
-
- response, err := l.backend.client.DeleteObject(context.Background(), request)
- l.backend.logRequest("deleteHA", response.RawResponse, response.OpcClientRequestId, response.OpcRequestId, err)
-
- if err != nil {
- metrics.IncrCounter(metricDeleteFailed, 1)
- return fmt.Errorf("write lock: %w", err)
- }
- }
-
- return nil
-}
-
-func (l *Lock) Value() (bool, string, error) {
- l.backend.logger.Debug("Value() called")
- defer metrics.MeasureSince(metricLockValue, time.Now().UTC())
-
- lockRecord, _, err := l.get(context.Background())
- if err != nil {
- return false, "", err
- }
- if lockRecord == nil {
- return false, "", err
- }
- return true, lockRecord.Value, nil
-}
-
-// get retrieves the Value for the lock.
-func (l *Lock) get(ctx context.Context) (*LockRecord, string, error) {
- l.backend.logger.Debug("Called getLockRecord()")
-
- // Read lock Key
-
- defer metrics.MeasureSince(metricGetHa, time.Now())
- opcClientRequestId, err := uuid.GenerateUUID()
- if err != nil {
- l.backend.logger.Error("getHa: error generating UUID")
- return nil, "", fmt.Errorf("failed to generate UUID: %w", err)
- }
- l.backend.logger.Debug("getHa", "opc-client-request-id", opcClientRequestId)
-
- request := objectstorage.GetObjectRequest{
- NamespaceName: &l.backend.namespaceName,
- BucketName: &l.backend.lockBucketName,
- ObjectName: &l.key,
- OpcClientRequestId: &opcClientRequestId,
- }
-
- ctx, cancel := context.WithTimeout(ctx, ObjectStorageCallsReadTimeout)
- defer cancel()
-
- response, err := l.backend.client.GetObject(ctx, request)
- l.backend.logRequest("getHA", response.RawResponse, response.OpcClientRequestId, response.OpcRequestId, err)
-
- if err != nil {
- if response.RawResponse != nil && response.RawResponse.StatusCode == http.StatusNotFound {
- return nil, "", nil
- }
-
- metrics.IncrCounter(metricGetFailed, 1)
- l.backend.logger.Error("Error calling GET", "err", err)
- return nil, "", fmt.Errorf("failed to read Value for %q: %w", l.key, err)
- }
-
- defer response.RawResponse.Body.Close()
-
- body, err := ioutil.ReadAll(response.Content)
- if err != nil {
- metrics.IncrCounter(metricGetFailed, 1)
- l.backend.logger.Error("Error reading content", "err", err)
- return nil, "", fmt.Errorf("failed to decode Value into bytes: %w", err)
- }
-
- var lockRecord LockRecord
- err = json.Unmarshal(body, &lockRecord)
- if err != nil {
- metrics.IncrCounter(metricGetFailed, 1)
- l.backend.logger.Error("Error un-marshalling content", "err", err)
- return nil, "", fmt.Errorf("failed to read Value for %q: %w", l.key, err)
- }
-
- return &lockRecord, *response.ETag, nil
-}
-
-func (l *Lock) writeLock() (bool, error) {
- l.backend.logger.Debug("WriteLock() called")
-
- // Create a transaction to read and the update (maybe)
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- // The transaction will be retried, and it could sit in a queue behind, say,
- // the delete operation. To stop the transaction, we close the context when
- // the associated stopCh is received.
- go func() {
- select {
- case <-l.stopCh:
- cancel()
- case <-ctx.Done():
- }
- }()
-
- lockRecordCache := loadLockRecordCache(l)
- if (lockRecordCache == nil) || lockRecordCache.lockRecord == nil ||
- lockRecordCache.lockRecord.Identity != l.identity ||
- time.Now().Sub(lockRecordCache.lastUpdate) > l.ttl {
- // case secondary
- currentLockRecord, currentEtag, err := l.get(ctx)
- if err != nil {
- return false, fmt.Errorf("error reading lock record: %w", err)
- }
-
- if (lockRecordCache == nil) || lockRecordCache.etag != currentEtag {
- // update cached lock record
- l.lockRecordCache.Store(&LockCache{
- etag: currentEtag,
- lastUpdate: time.Now().UTC(),
- lockRecord: currentLockRecord,
- })
-
- lockRecordCache = loadLockRecordCache(l)
- }
-
- // Current lock record being null implies that there is no leader. In this case we want to try acquiring lock.
- if currentLockRecord != nil && time.Now().Sub(lockRecordCache.lastUpdate) < LockCacheMinAcceptableAge {
- return false, nil
- }
- // cache is old enough and current, try acquiring lock as secondary
- }
-
- newLockRecord := &LockRecord{
- Key: l.key,
- Value: l.value,
- Identity: l.identity,
- }
-
- newLockRecordJson, err := json.Marshal(newLockRecord)
- if err != nil {
- return false, fmt.Errorf("error reading lock record: %w", err)
- }
-
- defer metrics.MeasureSince(metricPutHa, time.Now())
-
- opcClientRequestId, err := uuid.GenerateUUID()
- if err != nil {
- l.backend.logger.Error("putHa: error generating UUID")
- return false, fmt.Errorf("failed to generate UUID: %w", err)
- }
- l.backend.logger.Debug("putHa", "opc-client-request-id", opcClientRequestId)
- size := int64(len(newLockRecordJson))
- putRequest := objectstorage.PutObjectRequest{
- NamespaceName: &l.backend.namespaceName,
- BucketName: &l.backend.lockBucketName,
- ObjectName: &l.key,
- ContentLength: &size,
- PutObjectBody: ioutil.NopCloser(bytes.NewReader(newLockRecordJson)),
- OpcMeta: nil,
- OpcClientRequestId: &opcClientRequestId,
- }
-
- if lockRecordCache.etag == "" {
- noneMatch := "*"
- putRequest.IfNoneMatch = &noneMatch
- } else {
- putRequest.IfMatch = &lockRecordCache.etag
- }
-
- newtEtag := ""
- for i := 1; i <= LockWriteRetriesOnFailures; i++ {
- writeCtx, writeCancel := context.WithTimeout(ctx, ObjectStorageCallsWriteTimeout)
- defer writeCancel()
-
- putObjectResponse, putObjectError := l.backend.client.PutObject(writeCtx, putRequest)
- l.backend.logRequest("putHA", putObjectResponse.RawResponse, putObjectResponse.OpcClientRequestId, putObjectResponse.OpcRequestId, putObjectError)
-
- if putObjectError == nil {
- newtEtag = *putObjectResponse.ETag
- putObjectResponse.RawResponse.Body.Close()
- break
- }
-
- err = putObjectError
-
- if putObjectResponse.RawResponse == nil {
- metrics.IncrCounter(metricPutFailed, 1)
- l.backend.logger.Error("PUT", "err", err)
- break
- }
-
- putObjectResponse.RawResponse.Body.Close()
-
- // Retry if the return code is 5xx
- if (putObjectResponse.RawResponse.StatusCode / 100) == 5 {
- metrics.IncrCounter(metricPutFailed, 1)
- l.backend.logger.Warn("PUT. Retrying..", "err", err)
- time.Sleep(time.Duration(100*i) * time.Millisecond)
- } else {
- l.backend.logger.Error("PUT", "err", err)
- break
- }
- }
-
- if err != nil {
- return false, fmt.Errorf("write lock: %w", err)
- }
-
- l.backend.logger.Debug("Lock written", string(newLockRecordJson))
-
- l.lockRecordCache.Store(&LockCache{
- etag: newtEtag,
- lastUpdate: time.Now().UTC(),
- lockRecord: newLockRecord,
- })
-
- metrics.SetGauge(metricLeaderValue, 1)
- return true, nil
-}
diff --git a/physical/oci/oci_ha_test.go b/physical/oci/oci_ha_test.go
deleted file mode 100644
index b7213b9ce..000000000
--- a/physical/oci/oci_ha_test.go
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright © 2019, Oracle and/or its affiliates.
-package oci
-
-import (
- "os"
- "testing"
-
- "github.com/hashicorp/go-uuid"
- "github.com/hashicorp/vault/sdk/physical"
- "github.com/oracle/oci-go-sdk/common"
- "github.com/oracle/oci-go-sdk/objectstorage"
-)
-
-func TestOCIHABackend(t *testing.T) {
- // Skip tests if we are not running acceptance tests
- if os.Getenv("VAULT_ACC") == "" {
- t.SkipNow()
- }
-
- if !hasOCICredentials() {
- t.Skip("Skipping because OCI credentials could not be resolved. See https://pkg.go.dev/github.com/oracle/oci-go-sdk/common#DefaultConfigProvider for information on how to set up OCI credentials.")
- }
-
- bucketName, _ := uuid.GenerateUUID()
- configProvider := common.DefaultConfigProvider()
- objectStorageClient, _ := objectstorage.NewObjectStorageClientWithConfigurationProvider(configProvider)
- namespaceName := getNamespaceName(objectStorageClient, t)
-
- createBucket(bucketName, getTenancyOcid(configProvider, t), namespaceName, objectStorageClient, t)
- defer deleteBucket(namespaceName, bucketName, objectStorageClient, t)
-
- backend := createBackend(bucketName, namespaceName, "true", bucketName, t)
- ha, ok := backend.(physical.HABackend)
- if !ok {
- t.Fatalf("does not implement")
- }
-
- physical.ExerciseHABackend(t, ha, ha)
-}
diff --git a/physical/oci/oci_test.go b/physical/oci/oci_test.go
deleted file mode 100644
index e20b808fd..000000000
--- a/physical/oci/oci_test.go
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright © 2019, Oracle and/or its affiliates.
-package oci
-
-import (
- "os"
- "testing"
-
- log "github.com/hashicorp/go-hclog"
- "github.com/hashicorp/go-uuid"
- "github.com/hashicorp/vault/sdk/helper/logging"
- "github.com/hashicorp/vault/sdk/physical"
- "github.com/oracle/oci-go-sdk/common"
- "github.com/oracle/oci-go-sdk/objectstorage"
- "golang.org/x/net/context"
-)
-
-func TestOCIBackend(t *testing.T) {
- // Skip tests if we are not running acceptance tests
- if os.Getenv("VAULT_ACC") == "" {
- t.SkipNow()
- }
-
- if !hasOCICredentials() {
- t.Skip("Skipping because OCI credentials could not be resolved. See https://pkg.go.dev/github.com/oracle/oci-go-sdk/common#DefaultConfigProvider for information on how to set up OCI credentials.")
- }
-
- bucketName, _ := uuid.GenerateUUID()
- configProvider := common.DefaultConfigProvider()
- objectStorageClient, _ := objectstorage.NewObjectStorageClientWithConfigurationProvider(configProvider)
- namespaceName := getNamespaceName(objectStorageClient, t)
-
- createBucket(bucketName, getTenancyOcid(configProvider, t), namespaceName, objectStorageClient, t)
- defer deleteBucket(namespaceName, bucketName, objectStorageClient, t)
-
- backend := createBackend(bucketName, namespaceName, "false", "", t)
- physical.ExerciseBackend(t, backend)
- physical.ExerciseBackend_ListPrefix(t, backend)
-}
-
-func createBucket(bucketName string, tenancyOcid string, namespaceName string, objectStorageClient objectstorage.ObjectStorageClient, t *testing.T) {
- createBucketRequest := objectstorage.CreateBucketRequest{
- NamespaceName: &namespaceName,
- }
- createBucketRequest.CompartmentId = &tenancyOcid
- createBucketRequest.Name = &bucketName
- createBucketRequest.Metadata = make(map[string]string)
- createBucketRequest.PublicAccessType = objectstorage.CreateBucketDetailsPublicAccessTypeNopublicaccess
- _, err := objectStorageClient.CreateBucket(context.Background(), createBucketRequest)
- if err != nil {
- t.Fatalf("Failed to create bucket: %v", err)
- }
-}
-
-func deleteBucket(nameSpaceName string, bucketName string, objectStorageClient objectstorage.ObjectStorageClient, t *testing.T) {
- request := objectstorage.DeleteBucketRequest{
- NamespaceName: &nameSpaceName,
- BucketName: &bucketName,
- }
- _, err := objectStorageClient.DeleteBucket(context.Background(), request)
- if err != nil {
- t.Fatalf("Failed to delete bucket: %v", err)
- }
-}
-
-func getTenancyOcid(configProvider common.ConfigurationProvider, t *testing.T) (tenancyOcid string) {
- tenancyOcid, err := configProvider.TenancyOCID()
- if err != nil {
- t.Fatalf("Failed to get tenancy ocid: %v", err)
- }
- return tenancyOcid
-}
-
-func createBackend(bucketName string, namespaceName string, haEnabledStr string, lockBucketName string, t *testing.T) physical.Backend {
- backend, err := NewBackend(map[string]string{
- "auth_type_api_key": "true",
- "bucket_name": bucketName,
- "namespace_name": namespaceName,
- "ha_enabled": haEnabledStr,
- "lock_bucket_name": lockBucketName,
- }, logging.NewVaultLogger(log.Trace))
- if err != nil {
- t.Fatalf("Failed to create new backend: %v", err)
- }
- return backend
-}
-
-func getNamespaceName(objectStorageClient objectstorage.ObjectStorageClient, t *testing.T) string {
- response, err := objectStorageClient.GetNamespace(context.Background(), objectstorage.GetNamespaceRequest{})
- if err != nil {
- t.Fatalf("Failed to get namespaceName: %v", err)
- }
- nameSpaceName := *response.Value
- return nameSpaceName
-}
-
-func hasOCICredentials() bool {
- configProvider := common.DefaultConfigProvider()
-
- _, err := configProvider.KeyID()
- if err != nil {
- return false
- }
-
- return true
-}
diff --git a/scripts/gen_openapi.sh b/scripts/gen_openapi.sh
index 683a93817..afe93ed64 100755
--- a/scripts/gen_openapi.sh
+++ b/scripts/gen_openapi.sh
@@ -59,7 +59,6 @@ vault auth enable "jwt"
vault auth enable "kerberos"
vault auth enable "kubernetes"
vault auth enable "ldap"
-vault auth enable "oci"
vault auth enable "okta"
vault auth enable "radius"
vault auth enable "userpass"
diff --git a/ui/app/templates/components/database-connection.hbs b/ui/app/templates/components/database-connection.hbs
index 946668629..d047302f7 100644
--- a/ui/app/templates/components/database-connection.hbs
+++ b/ui/app/templates/components/database-connection.hbs
@@ -86,14 +86,6 @@
{{#if (eq @mode "create")}}
- {{#if (eq @model.plugin_name "vault-plugin-database-oracle")}}
-