Skip to content

Commit

Permalink
add cross domain scoping
Browse files Browse the repository at this point in the history
Signed-off-by: Arno Uhlig <arno.uhlig@sap.com>
  • Loading branch information
auhlig committed May 7, 2019
1 parent af78279 commit e2e3b13
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 24 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ We use *breaking* word for marking changes that are not backward compatible (rel

## Unreleased

### Added

- [#1118](https://github.com/improbable-eng/thanos/pull/1118) swift: Added support for cross-domain authentication by introducing `userDomainID`, `userDomainName`, `projectDomainID`, `projectDomainName`. Mark `tenantID`, `tenantName` as deprecated and encourage usage of `projectID`, `projectName`.

## [v0.4.0](https://github.com/improbable-eng/thanos/releases/tag/v0.4.0) - 2019.05.3

:warning: **IMPORTANT** :warning: This is the last release that supports gossip. From Thanos v0.5.0, gossip will be completely removed.
Expand Down
10 changes: 8 additions & 2 deletions docs/storage.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,14 +260,20 @@ type: SWIFT
config:
auth_url: ""
username: ""
user_domain_name: ""
user_domain_id: ""
user_id: ""
password: ""
domain_id: ""
domain_name: ""
tenant_id: ""
tenant_name: ""
project_id: ""
project_name: ""
project_domain_id: ""
project_domain_name: ""
region_name: ""
container_name: ""
tenant_id: ""
tenant_name: ""
```

## Other minio supported S3 object storages
Expand Down
105 changes: 83 additions & 22 deletions pkg/objstore/swift/swift.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,43 @@ import (
"testing"
"time"

"github.com/improbable-eng/thanos/pkg/objstore"

"github.com/go-kit/kit/log"
"github.com/go-kit/kit/log/level"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack"
"github.com/gophercloud/gophercloud/openstack/objectstorage/v1/containers"
"github.com/gophercloud/gophercloud/openstack/objectstorage/v1/objects"
"github.com/gophercloud/gophercloud/pagination"
"github.com/improbable-eng/thanos/pkg/objstore"
"github.com/pkg/errors"
"gopkg.in/yaml.v2"
yaml "gopkg.in/yaml.v2"
)

// DirDelim is the delimiter used to model a directory structure in an object store bucket.
const DirDelim = "/"

type SwiftConfig struct {
AuthUrl string `yaml:"auth_url"`
Username string `yaml:"username"`
UserId string `yaml:"user_id"`
Password string `yaml:"password"`
DomainId string `yaml:"domain_id"`
DomainName string `yaml:"domain_name"`
TenantID string `yaml:"tenant_id"`
TenantName string `yaml:"tenant_name"`
RegionName string `yaml:"region_name"`
ContainerName string `yaml:"container_name"`
AuthUrl string `yaml:"auth_url"`
Username string `yaml:"username"`
UserDomainName string `yaml:"user_domain_name"`
UserDomainID string `yaml:"user_domain_id"`
UserId string `yaml:"user_id"`
Password string `yaml:"password"`
DomainId string `yaml:"domain_id"`
DomainName string `yaml:"domain_name"`
ProjectID string `yaml:"project_id"`
ProjectName string `yaml:"project_name"`
ProjectDomainID string `yaml:"project_domain_id"`
ProjectDomainName string `yaml:"project_domain_name"`
RegionName string `yaml:"region_name"`
ContainerName string `yaml:"container_name"`

// Deprecated: Please use `project_id` instead.
// The term `tenant` is used in the deprecated OpenStack Identity v2.
TenantID string `yaml:"tenant_id"`
// Deprecated: Please use `project_name` instead.
// The term `tenant` is used in the deprecated OpenStack Identity v2.
TenantName string `yaml:"tenant_name"`
}

type Container struct {
Expand All @@ -58,13 +69,57 @@ func NewContainer(logger log.Logger, conf []byte) (*Container, error) {
Password: sc.Password,
DomainID: sc.DomainId,
DomainName: sc.DomainName,
TenantID: sc.TenantID,
TenantName: sc.TenantName,
TenantID: sc.ProjectID,
TenantName: sc.ProjectName,

// Allow Gophercloud to re-authenticate automatically.
AllowReauth: true,
}

// The term `tenant` is used in the deprecated OpenStack Identity v2.
// In Identity v3 the term `project` is used instead.
switch {
case sc.TenantName != "":
level.Warn(logger).Log("msg", "usage of tenant_name is deprecated. use project_name instead")
authOpts.TenantName = sc.TenantName
case sc.TenantID != "":
level.Warn(logger).Log("msg", "usage of tenant_id is deprecated. use project_id instead")
authOpts.TenantID = sc.TenantID
case sc.ProjectName != "" || sc.ProjectID != "":
level.Info(logger).Log("msg", "using project_id or project_name")
}

// Support for cross-domain scoping (user in different domain than project).
// If a userDomainName or userDomainID is given, the user is scoped to this domain.
switch {
case sc.UserDomainName != "":
authOpts.DomainName = sc.UserDomainName
case sc.UserDomainID != "":
authOpts.DomainID = sc.UserDomainID
}

// A token can be scoped to a domain or project.
// The project can be in another domain than the user, which is indicated by setting either projectDomainName or projectDomainID.
switch {
case sc.ProjectDomainName != "":
authOpts.Scope = &gophercloud.AuthScope{
DomainName: sc.ProjectDomainName,
}
case sc.ProjectDomainID != "":
authOpts.Scope = &gophercloud.AuthScope{
DomainID: sc.ProjectDomainID,
}
}
if authOpts.Scope != nil {
level.Info(logger).Log("msg", "scoping to domain, project")
switch {
case sc.ProjectName != "":
authOpts.Scope.ProjectName = sc.ProjectName
case sc.ProjectID != "":
authOpts.Scope.ProjectID = sc.ProjectID
}
}

provider, err := openstack.AuthenticatedClient(authOpts)
if err != nil {
return nil, err
Expand Down Expand Up @@ -180,13 +235,19 @@ func (c *Container) deleteContainer(name string) error {

func configFromEnv() SwiftConfig {
c := SwiftConfig{
AuthUrl: os.Getenv("OS_AUTH_URL"),
Username: os.Getenv("OS_USERNAME"),
Password: os.Getenv("OS_PASSWORD"),
TenantID: os.Getenv("OS_TENANT_ID"),
TenantName: os.Getenv("OS_TENANT_NAME"),
RegionName: os.Getenv("OS_REGION_NAME"),
ContainerName: os.Getenv("OS_CONTAINER_NAME"),
AuthUrl: os.Getenv("OS_AUTH_URL"),
Username: os.Getenv("OS_USERNAME"),
Password: os.Getenv("OS_PASSWORD"),
RegionName: os.Getenv("OS_REGION_NAME"),
ContainerName: os.Getenv("OS_CONTAINER_NAME"),
ProjectID: os.Getenv("OS_PROJECT_ID"),
ProjectName: os.Getenv("OS_PROJECT_NAME"),
UserDomainID: os.Getenv("OS_USER_DOMAIN_ID"),
UserDomainName: os.Getenv("OS_USER_DOMAIN_NAME"),
ProjectDomainID: os.Getenv("OS_PROJET_DOMAIN_ID"),
ProjectDomainName: os.Getenv("OS_PROJECT_DOMAIN_NAME"),
TenantID: os.Getenv("OS_TENANT_ID"),
TenantName: os.Getenv("OS_TENANT_NAME"),
}

return c
Expand Down

0 comments on commit e2e3b13

Please sign in to comment.