Browse Source

Implement oracle validator (#1592)

* Implement oracle validator

Signed-off-by: Martin Schimandl <martin.schimandl@gmail.com>

* Add more granular OCI error handling

Signed-off-by: Martin Schimandl <martin.schimandl@gmail.com>

* Remove two newlines the linter does not like

Signed-off-by: Martin Schimandl <martin.schimandl@gmail.com>

Signed-off-by: Martin Schimandl <martin.schimandl@gmail.com>
Martin Schimandl 3 years ago
parent
commit
6ca30a762a
1 changed files with 49 additions and 4 deletions
  1. 49 4
      pkg/provider/oracle/oracle.go

+ 49 - 4
pkg/provider/oracle/oracle.go

@@ -21,6 +21,7 @@ import (
 
 	"github.com/oracle/oci-go-sdk/v56/common"
 	"github.com/oracle/oci-go-sdk/v56/common/auth"
+	"github.com/oracle/oci-go-sdk/v56/keymanagement"
 	"github.com/oracle/oci-go-sdk/v56/secrets"
 	"github.com/tidwall/gjson"
 	corev1 "k8s.io/api/core/v1"
@@ -59,14 +60,19 @@ var _ esv1beta1.SecretsClient = &VaultManagementService{}
 var _ esv1beta1.Provider = &VaultManagementService{}
 
 type VaultManagementService struct {
-	Client VMInterface
-	vault  string
+	Client         VMInterface
+	KmsVaultClient KmsVCInterface
+	vault          string
 }
 
 type VMInterface interface {
 	GetSecretBundleByName(ctx context.Context, request secrets.GetSecretBundleByNameRequest) (secrets.GetSecretBundleByNameResponse, error)
 }
 
+type KmsVCInterface interface {
+	GetVault(ctx context.Context, request keymanagement.GetVaultRequest) (response keymanagement.GetVaultResponse, err error)
+}
+
 // Empty GetAllSecrets.
 func (vms *VaultManagementService) GetAllSecrets(ctx context.Context, ref esv1beta1.ExternalSecretFind) (map[string][]byte, error) {
 	// TO be implemented
@@ -160,9 +166,17 @@ func (vms *VaultManagementService) NewClient(ctx context.Context, store esv1beta
 
 	secretManagementService.SetRegion(oracleSpec.Region)
 
+	kmsVaultClient, err := keymanagement.NewKmsVaultClientWithConfigurationProvider(configurationProvider)
+	if err != nil {
+		return nil, fmt.Errorf(errOracleClient, err)
+	}
+
+	kmsVaultClient.SetRegion(oracleSpec.Region)
+
 	return &VaultManagementService{
-		Client: secretManagementService,
-		vault:  oracleSpec.Vault,
+		Client:         secretManagementService,
+		KmsVaultClient: kmsVaultClient,
+		vault:          oracleSpec.Vault,
 	}, nil
 }
 
@@ -226,6 +240,37 @@ func (vms *VaultManagementService) Close(ctx context.Context) error {
 }
 
 func (vms *VaultManagementService) Validate() (esv1beta1.ValidationResult, error) {
+	_, err := vms.KmsVaultClient.GetVault(
+		context.Background(), keymanagement.GetVaultRequest{
+			VaultId: &vms.vault,
+		},
+	)
+	if err != nil {
+		failure, ok := common.IsServiceError(err)
+		if ok {
+			code := failure.GetCode()
+			switch code {
+			case "NotAuthenticated":
+				return esv1beta1.ValidationResultError, err
+			case "NotAuthorizedOrNotFound":
+				// User authentication was successful, but user might not have a permission like:
+				//
+				// Allow group external_secrets to read vaults in tenancy
+				//
+				// Which is fine, because to read secrets we only need:
+				//
+				// Allow group external_secrets to read secret-family in tenancy
+				//
+				// But we can't test for this permission without knowing the name of a secret
+				return esv1beta1.ValidationResultUnknown, err
+			default:
+				return esv1beta1.ValidationResultError, err
+			}
+		} else {
+			return esv1beta1.ValidationResultError, err
+		}
+	}
+
 	return esv1beta1.ValidationResultReady, nil
 }