From d01642831b1f125125d60cc8c14b9bd8dd40f9ab Mon Sep 17 00:00:00 2001 From: Fred Tibbitts III <44442080+fredtibbitts@users.noreply.github.com> Date: Fri, 4 Aug 2023 04:40:00 -0400 Subject: [PATCH] OCI: OKE Workload Identity support (#64) * Add support for OKE workload identity to the OCI provider Signed-off-by: Fred Tibbitts * Update README based on review Signed-off-by: Fred Tibbitts * Add changelog entry Signed-off-by: Fred Tibbitts * go mod tidy Signed-off-by: Fred Tibbitts --------- Signed-off-by: Fred Tibbitts --- CHANGELOG.md | 1 + README.md | 16 +++++++++++++++- go.mod | 2 +- go.sum | 5 +++-- providers/oci/oci.go | 26 ++++++++++++++++++++------ 5 files changed, 40 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 564faa91..b1385032 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ We use *breaking :warning:* to mark changes that are not backward compatible (re - [#61](https://github.com/thanos-io/objstore/pull/61) Add OpenTelemetry TracingBucket. > This also changes the behaviour of `client.NewBucket`. Now it returns, uninstrumented and untraced bucket. You can combine `objstore.WrapWithMetrics` and `tracing/{opentelemetry,opentracing}.WrapWithTraces` to have old behavior. +- [#64](https://github.com/thanos-io/objstore/pull/64) OCI: OKE Workload Identity support. ### Changed - [#38](https://github.com/thanos-io/objstore/pull/38) *: Upgrade minio-go version to `v7.0.45`. diff --git a/README.md b/README.md index c7388894..11b773a4 100644 --- a/README.md +++ b/README.md @@ -578,7 +578,7 @@ prefix: "" ### Oracle Cloud Infrastructure Object Storage -To configure Oracle Cloud Infrastructure (OCI) Object Storage as Thanos Object Store, you need to provide appropriate authentication credentials to your OCI tenancy. The OCI object storage client implementation for Thanos supports either the default keypair or instance principal authentication. +To configure Oracle Cloud Infrastructure (OCI) Object Storage as a Thanos Object Store, you need to provide appropriate authentication credentials to your OCI tenancy. The OCI object storage client implementation for Thanos supports default keypair, instance principal, and OKE workload identity authentication. #### API Signing Key @@ -642,6 +642,20 @@ config: You can also include any of the optional configuration just like the example in `Default Provider`. +#### OKE Workload Identity Provider + +For Example: + +```yaml +type: OCI +config: + provider: "oke-workload-identity" + bucket: "" + region: "" +``` + +The `bucket` and `region` fields are required. The `region` field identifies the bucket region. + ##### HuaweiCloud OBS To use HuaweiCloud OBS as an object store, you should apply for a HuaweiCloud Account to create an object storage bucket at first. More details: [HuaweiCloud OBS](https://support.huaweicloud.com/obs/index.html) diff --git a/go.mod b/go.mod index 5bf1fd24..8dc98880 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/minio/minio-go/v7 v7.0.61 github.com/ncw/swift v1.0.53 github.com/opentracing/opentracing-go v1.2.0 - github.com/oracle/oci-go-sdk/v65 v65.13.0 + github.com/oracle/oci-go-sdk/v65 v65.41.1 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.12.2 github.com/prometheus/common v0.36.0 diff --git a/go.sum b/go.sum index 21e06236..21367dc7 100644 --- a/go.sum +++ b/go.sum @@ -326,8 +326,8 @@ github.com/ncw/swift v1.0.53 h1:luHjjTNtekIEvHg5KdAFIBaH7bWfNkefwFnpDffSIks= github.com/ncw/swift v1.0.53/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/oracle/oci-go-sdk/v65 v65.13.0 h1:0+9ea5goYfhI3/MPfbIQU6yzHYWE6sCk6VuUepxk5Nk= -github.com/oracle/oci-go-sdk/v65 v65.13.0/go.mod h1:oyMrMa1vOzzKTmPN+kqrTR9y9kPA2tU1igN3NUSNTIE= +github.com/oracle/oci-go-sdk/v65 v65.41.1 h1:+lbosOyNiib3TGJDvLq1HwEAuFqkOjPJDIkyxM15WdQ= +github.com/oracle/oci-go-sdk/v65 v65.41.1/go.mod h1:MXMLMzHnnd9wlpgadPkdlkZ9YrwQmCOmbX5kjVEJodw= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -597,6 +597,7 @@ golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/providers/oci/oci.go b/providers/oci/oci.go index 2be3210a..b6c9680a 100644 --- a/providers/oci/oci.go +++ b/providers/oci/oci.go @@ -8,6 +8,7 @@ import ( "fmt" "io" "net/http" + "os" "strings" "testing" "time" @@ -30,9 +31,10 @@ const DirDelim = "/" type Provider string const ( - DefaultConfigProvider = Provider("default") - InstancePrincipalConfigProvider = Provider("instance-principal") - RawConfigProvider = Provider("raw") + defaultConfigProvider = Provider("default") + instancePrincipalConfigProvider = Provider("instance-principal") + rawConfigProvider = Provider("raw") + okeWorkloadIdentityConfigProvider = Provider("oke-workload-identity") ) var DefaultConfig = Config{ @@ -295,19 +297,31 @@ func NewBucket(logger log.Logger, ociConfig []byte) (*Bucket, error) { provider := Provider(strings.ToLower(config.Provider)) level.Info(logger).Log("msg", "creating OCI client", "provider", provider) switch provider { - case DefaultConfigProvider: + case defaultConfigProvider: configurationProvider = common.DefaultConfigProvider() - case InstancePrincipalConfigProvider: + case instancePrincipalConfigProvider: configurationProvider, err = auth.InstancePrincipalConfigurationProvider() if err != nil { return nil, errors.Wrapf(err, "unable to create OCI instance principal config provider") } - case RawConfigProvider: + case rawConfigProvider: if err := config.validateConfig(); err != nil { return nil, errors.Wrapf(err, "invalid oci configurations") } configurationProvider = common.NewRawConfigurationProvider(config.Tenancy, config.User, config.Region, config.Fingerprint, config.PrivateKey, &config.Passphrase) + case okeWorkloadIdentityConfigProvider: + if err := os.Setenv(auth.ResourcePrincipalVersionEnvVar, auth.ResourcePrincipalVersion2_2); err != nil { + return nil, errors.Wrapf(err, "unable to set environment variable: %s", auth.ResourcePrincipalVersionEnvVar) + } + if err := os.Setenv(auth.ResourcePrincipalRegionEnvVar, config.Region); err != nil { + return nil, errors.Wrapf(err, "unable to set environment variable: %s", auth.ResourcePrincipalRegionEnvVar) + } + + configurationProvider, err = auth.OkeWorkloadIdentityConfigurationProvider() + if err != nil { + return nil, errors.Wrapf(err, "unable to create OKE workload identity config provider") + } default: return nil, errors.Wrapf(err, fmt.Sprintf("unsupported OCI provider: %s", provider)) }