Skip to content

Commit

Permalink
Add OCI Object Storage Bucket support
Browse files Browse the repository at this point in the history
Address comment from GiedriusS

Signed-off-by: aaron.tam <aaron.tam@oracle.com>
  • Loading branch information
aaron.tam committed Nov 21, 2021
1 parent 3d17f6e commit c6c1e11
Show file tree
Hide file tree
Showing 8 changed files with 767 additions and 1 deletion.
75 changes: 75 additions & 0 deletions docs/storage.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ Current object storage client implementations:
| [Tencent COS](#tencent-cos) | Beta | Production Usage | no | @jojohappy,@hanjm |
| [AliYun OSS](#aliyun-oss) | Beta | Production Usage | no | @shaulboozhiao,@wujinhu |
| [Local Filesystem](#filesystem) | Stable | Testing and Demo only | yes | @bwplotka |
| [OCI Object Storage](#oci) | Beta | Production Usage | yes | @aarontams,@ericrrath |

**Missing support to some object storage?** Check out [how to add your client section](#how-to-add-a-new-client-to-thanos)

Expand Down Expand Up @@ -449,6 +450,80 @@ config:
directory: ""
```

### OCI

[Oracle Cloud Infrastructure](https://www.oracle.com/cloud). To configure OCI Object Storage as Thanos Object Store, you need access to OCI Object Storage.
You can get a free OCI Cloud Services by following the [Oracle Cloud Free Tier](https://www.oracle.com/cloud/free) page.
More information about [Overview of Object Storage](https://docs.cloud.oracle.com/en-us/iaas/Content/Object/Concepts/objectstorageoverview.htm).

OCI Object Storage supports three different providers, default, instance principle, and raw.
The default HTTP Client comes with this Thanos OCI Object Storage should be able to handle most of the use cases.

By default, like other clients, Thanos OCI Object Storage client will store the data from a single prometheus instance to the top directory of the bucket.
This means each bucket can only store one prometheus instance data.

To support multiple prometheus instances with a single bucket, a new `object_base_path` option is introduced in OCI Object Storage client.
If defined, the value will be used as the prefix of the prometheus data in OCI bucket.

For example, if you want to use the same bucket for 2 prometheus instances, you can define `object_base_path` as `/path/for/prometheus1`
for the first prometheus instance, and `/path/for/prometheus2` for the second prometheus instance.

#### Default Provider
The default config provider will look for configurations in 3 places: file in `$HOME/.oci/config`, `$HOME/.obmcs/config`, and
variables names starting with the string TF_VAR. If the same configuration is found in multiple places the provider will
prefer the first one.

For Example:
```yaml
type: OCI
config:
provider: "default"
bucket: ""
compartment_ocid: ""
object_base_path: "" // Optional object base path (prefix) in OCI bucket.
part_size: "" // Optional part size to override the OCI default of 128 MiB, value is in bytes.
max_request_retries: "" // Optional maximum number of retries for a request.
http_config:
idle_conn_timeout: 1m30s // Optional maximum amount of time an idle (keep-alive) connection will remain idle before closing itself. Zero means no limit.
response_header_timeout: 2m // Optional amount of time to wait for a server's response headers after fully writing the request.
tls_handshake_timeout: 10s // Optional maximum amount of time waiting to wait for a TLS handshake. Zero means no timeout.
expect_continue_timeout: 1s // Optional amount of time to wait for a server's first response headers. Zero means no timeout and causes the body to be sent immediately.
insecure_skip_verify: false // Optional. If true, crypto/tls accepts any certificate presented by the server and any host name in that certificate.
max_idle_conns: 100 // Optional maximum number of idle (keep-alive) connections across all hosts. Zero means no limit.
max_idle_conns_per_host: 100 // Optional maximum idle (keep-alive) connections to keep per-host. If zero, DefaultMaxIdleConnsPerHost=2 is used.
max_conns_per_host: 0 // Optional maximum total number of connections per host.
disable_compression: false // Optional. If true, prevents the Transport from requesting compression.
```


#### Instance Principle Provider
For Example:
```yaml
type: OCI
config:
provider: "instance-principal"
bucket: ""
compartment_ocid: ""
```
You can also include any of the optional configuration just like the example in `Default Provider`.

#### Raw Provider
For Example:
```yaml
type: OCI
config:
provider: "raw"
bucket: ""
compartment_ocid: ""
tenancy_ocid: ""
user_ocid: ""
region: ""
fingerprint: ""
privatekey: ""
passphrase: "" // Optional passphrase to encrypt the private API Signing key
```
You can also include any of the optional configuration just like the example in `Default Provider`.

### How to add a new client to Thanos?

Following checklist allows adding new Go code client to supported providers:
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ require (
github.com/olekukonko/tablewriter v0.0.2
github.com/opentracing/basictracer-go v1.0.0
github.com/opentracing/opentracing-go v1.2.0
github.com/oracle/oci-go-sdk/v46 v46.2.0
github.com/pkg/errors v0.9.1
github.com/pmezard/go-difflib v1.0.0
github.com/prometheus/alertmanager v0.23.1-0.20210914172521-e35efbddb66a
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1386,6 +1386,8 @@ github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJ
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
github.com/openzipkin/zipkin-go v0.2.5/go.mod h1:KpXfKdgRDnnhsxw4pNIH9Md5lyFqKUa4YDFlwRYAMyE=
github.com/oracle/oci-go-sdk/v46 v46.2.0 h1:yCb/AKio4q7jHgq7ktbGqwkOloOopW3Oy/P2UG2B6Is=
github.com/oracle/oci-go-sdk/v46 v46.2.0/go.mod h1:DwFVvDNhpY+iZ2bD2ITEqENhO6/iBRttbJky49HRH6A=
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
Expand Down
4 changes: 4 additions & 0 deletions pkg/objstore/client/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/thanos-io/thanos/pkg/objstore/cos"
"github.com/thanos-io/thanos/pkg/objstore/filesystem"
"github.com/thanos-io/thanos/pkg/objstore/gcs"
"github.com/thanos-io/thanos/pkg/objstore/oci"
"github.com/thanos-io/thanos/pkg/objstore/oss"
"github.com/thanos-io/thanos/pkg/objstore/s3"
"github.com/thanos-io/thanos/pkg/objstore/swift"
Expand All @@ -36,6 +37,7 @@ const (
COS ObjProvider = "COS"
ALIYUNOSS ObjProvider = "ALIYUNOSS"
BOS ObjProvider = "BOS"
OCI ObjProvider = "OCI"
)

type BucketConfig struct {
Expand Down Expand Up @@ -75,6 +77,8 @@ func NewBucket(logger log.Logger, confContentYaml []byte, reg prometheus.Registe
bucket, err = filesystem.NewBucketFromConfig(config)
case string(BOS):
bucket, err = bos.NewBucket(logger, config, component)
case string(OCI):
bucket, err = oci.NewBucket(logger, config)
default:
return nil, errors.Errorf("bucket with type %s is not supported", bucketConf.Type)
}
Expand Down
17 changes: 16 additions & 1 deletion pkg/objstore/objtesting/foreach.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ import (
"github.com/thanos-io/thanos/pkg/objstore/azure"
"github.com/thanos-io/thanos/pkg/objstore/cos"
"github.com/thanos-io/thanos/pkg/objstore/gcs"
"github.com/thanos-io/thanos/pkg/objstore/oci"
"github.com/thanos-io/thanos/pkg/objstore/oss"
"github.com/thanos-io/thanos/pkg/objstore/s3"
"github.com/thanos-io/thanos/pkg/objstore/swift"
"github.com/thanos-io/thanos/pkg/testutil"
)

// IsObjStoreSkipped returns true if given provider ID is found in THANOS_TEST_OBJSTORE_SKIP array delimited by comma e.g:
// THANOS_TEST_OBJSTORE_SKIP=GCS,S3,AZURE,SWIFT,COS,ALIYUNOSS,BOS.
// THANOS_TEST_OBJSTORE_SKIP=GCS,S3,AZURE,SWIFT,COS,ALIYUNOSS,BOS.OCI.
func IsObjStoreSkipped(t *testing.T, provider client.ObjProvider) bool {
if e, ok := os.LookupEnv("THANOS_TEST_OBJSTORE_SKIP"); ok {
obstores := strings.Split(e, ",")
Expand Down Expand Up @@ -162,4 +163,18 @@ func ForeachStore(t *testing.T, testFn func(t *testing.T, bkt objstore.Bucket))
testFn(t, bkt)
})
}

// Optional OCI.
if !IsObjStoreSkipped(t, client.OCI) {
t.Run("oci", func(t *testing.T) {
bkt, closeFn, err := oci.NewTestBucket(t)
testutil.Ok(t, err)

t.Parallel()
defer closeFn()

testFn(t, bkt)
})
}

}

0 comments on commit c6c1e11

Please sign in to comment.