Skip to content

Commit

Permalink
Move to keystone auth
Browse files Browse the repository at this point in the history
  • Loading branch information
TruePack committed Aug 10, 2023
1 parent b3efc5d commit c36d2be
Show file tree
Hide file tree
Showing 86 changed files with 862 additions and 1,191 deletions.
7 changes: 4 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ require (
github.com/selectel/craas-go v0.3.0
github.com/selectel/dbaas-go v0.9.0
github.com/selectel/domains-go v0.4.0
github.com/selectel/go-selvpcclient/v2 v2.1.1
github.com/selectel/go-selvpcclient/v3 v3.0.1
github.com/selectel/mks-go v0.12.0
github.com/stretchr/testify v1.7.2
)
Expand All @@ -21,7 +21,8 @@ require (
github.com/fatih/color v1.13.0 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/gophercloud/gophercloud v1.0.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/gophercloud/gophercloud v1.5.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-checkpoint v0.5.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
Expand Down Expand Up @@ -54,7 +55,7 @@ require (
github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect
github.com/vmihailenco/tagparser v0.1.1 // indirect
github.com/zclconf/go-cty v1.12.1 // indirect
golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167 // indirect
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 // indirect
golang.org/x/net v0.7.0 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/text v0.7.0 // indirect
Expand Down
16 changes: 9 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,15 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/gophercloud/gophercloud v1.0.0 h1:9nTGx0jizmHxDobe4mck89FyQHVyA3CaXLIUSGJjP9k=
github.com/gophercloud/gophercloud v1.0.0/go.mod h1:Q8fZtyi5zZxPS/j9aj3sSxtvj41AdQMDwyo1myduD5c=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/gophercloud/gophercloud v1.5.0 h1:cDN6XFCLKiiqvYpjQLq9AiM7RDRbIC9450WpPH+yvXo=
github.com/gophercloud/gophercloud v1.5.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU=
Expand Down Expand Up @@ -172,8 +175,8 @@ github.com/selectel/dbaas-go v0.9.0 h1:IAmiyxkRtfLZg1JUdIhcsE5jpdBvsZibPCqyhB+yV
github.com/selectel/dbaas-go v0.9.0/go.mod h1:8D945oFzpx94v08zIb4s1bRTPCdPoNVnBu4umMYFJrQ=
github.com/selectel/domains-go v0.4.0 h1:mVUeJK8oW9XMizft7Vu4OCyvjbzq4+o+zHgzJ2ZxnIY=
github.com/selectel/domains-go v0.4.0/go.mod h1:AhXhwyMSTkpEWFiBLUvzFP76W+WN+ZblwmjLJLt7y58=
github.com/selectel/go-selvpcclient/v2 v2.1.1 h1:dW8AEDeDkMCBb94NMCiNq/vK4n+f6kcGKsUuMwBcq+A=
github.com/selectel/go-selvpcclient/v2 v2.1.1/go.mod h1:kFPnYYxcgJHybnmYEmZ9S+G0MNe8wBmYhhCkEqYjAuc=
github.com/selectel/go-selvpcclient/v3 v3.0.1 h1:hlRKXMKZ3igzEd6NPaxF/ncDpsNMB+v2swa0lrsQP+g=
github.com/selectel/go-selvpcclient/v3 v3.0.1/go.mod h1:NM7IXhh1IzqZ88DOw1Qc5Ez3tULLViXo95l5+rKPuyQ=
github.com/selectel/mks-go v0.12.0 h1:nLWHK8BXkhFlXvjFqf7WRrdAfvmrOhQzDSLx7BGa6aM=
github.com/selectel/mks-go v0.12.0/go.mod h1:FcFqF3WvZIhztyAt1+ZySKf0zWmCEvg9e2gRwxVyQOw=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
Expand Down Expand Up @@ -207,9 +210,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167 h1:O8uGbHCqlTp2P6QJSLmCojM4mN6UemYv8K+dCnmHmu0=
golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
Expand Down
116 changes: 99 additions & 17 deletions selectel/config.go
Original file line number Diff line number Diff line change
@@ -1,44 +1,132 @@
package selectel

import (
"context"
"errors"
"strings"
"fmt"
"sync"

"github.com/hashicorp/go-retryablehttp"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
domainsV1 "github.com/selectel/domains-go/pkg/v1"
"github.com/selectel/go-selvpcclient/v2/selvpcclient"
"github.com/selectel/go-selvpcclient/v2/selvpcclient/quotamanager"
"github.com/selectel/go-selvpcclient/v2/selvpcclient/resell"
resellV2 "github.com/selectel/go-selvpcclient/v2/selvpcclient/resell/v2"
"github.com/selectel/go-selvpcclient/v3/selvpcclient"
"github.com/selectel/go-selvpcclient/v3/selvpcclient/clients"
)

var cfgSingletone *Config

Check failure on line 17 in selectel/config.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gofumpt`-ed (gofumpt)
var once sync.Once

// Config contains all available configuration options.
type Config struct {
Token string
Endpoint string
ProjectID string
Region string
ProjectID string

Context context.Context
AuthURL string
AuthUsername string
AuthPassword string
AuthUserDomainName string
AuthDomainName string
AuthProjectID string // Optional, if set use project-scoped
clientsCache map[string]*selvpcclient.Client
lock sync.Mutex
}

func getConfig(d *schema.ResourceData) (*Config, diag.Diagnostics) {
var err error

once.Do(func() {
cfgSingletone = &Config{
Token: d.Get("token").(string),
Endpoint: d.Get("endpoint").(string),
AuthURL: d.Get("auth_url").(string),
AuthUsername: d.Get("auth_username").(string),
AuthPassword: d.Get("auth_password").(string),
AuthUserDomainName: d.Get("auth_user_domain_name").(string),
AuthDomainName: d.Get("auth_domain_name").(string),
}
if v, ok := d.GetOk("auth_url"); ok {
cfgSingletone.AuthURL = v.(string)
}
if v, ok := d.GetOk("auth_user_domain_name"); ok {
cfgSingletone.AuthUserDomainName = v.(string)
}
if v, ok := d.GetOk("auth_project_id"); ok {
cfgSingletone.AuthProjectID = v.(string)
}
if v, ok := d.GetOk("project_id"); ok {
cfgSingletone.ProjectID = v.(string)
}
if v, ok := d.GetOk("region"); ok {
cfgSingletone.Region = v.(string)
}

err = cfgSingletone.Validate()

Check failure on line 68 in selectel/config.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gofumpt`-ed (gofumpt)
})
if err != nil {
return nil, diag.FromErr(err)
}

return cfgSingletone, nil
}

// Validate performs config validation.
func (c *Config) Validate() error {
if c.Token == "" {
return errors.New("token must be specified")
}
if c.Endpoint == "" {
c.Endpoint = strings.Join([]string{resell.Endpoint, resellV2.APIVersion}, "/")

client, err := c.GetSelVPCClient()
if err != nil {
return fmt.Errorf("can't get selvpc client in validate config: %w", err)
}

if c.Region != "" {
if err := validateRegion(c.Region); err != nil {
if err := validateRegion(client, clients.ResellServiceType, c.Region); err != nil {
return err
}
}

return nil
}

func (c *Config) resellV2Client() *selvpcclient.ServiceClient {
return resellV2.NewV2ResellClientWithEndpoint(c.Token, c.Endpoint)
func (c *Config) GetSelVPCClient() (*selvpcclient.Client, error) {
return c.GetSelVPCClientWithProjectScope(c.AuthProjectID)
}

func (c *Config) GetSelVPCClientWithProjectScope(projectID string) (*selvpcclient.Client, error) {
c.lock.Lock()
defer c.lock.Unlock()

if client, ok := c.clientsCache[fmt.Sprintf("client_%s", projectID)]; ok {
return client, nil
}

opts := &selvpcclient.ClientOptions{
DomainName: c.AuthDomainName,
Username: c.AuthUsername,
Password: c.AuthPassword,
ProjectID: projectID,
AuthURL: c.AuthURL,
UserDomainName: c.AuthUserDomainName,
}

client, err := selvpcclient.NewClient(opts)
if err != nil {
return nil, err
}

if c.clientsCache == nil {
c.clientsCache = map[string]*selvpcclient.Client{}
}

c.clientsCache[fmt.Sprintf("client_%s", c.AuthProjectID)] = client

return client, nil
}

func (c *Config) domainsV1Client() *domainsV1.ServiceClient {
Expand All @@ -52,9 +140,3 @@ func (c *Config) domainsV1Client() *domainsV1.ServiceClient {

return domainsClient
}

func (c *Config) quotaManagerRegionalClient(
identity quotamanager.IdentityManagerInterface,
) *quotamanager.QuotaRegionalClient {
return quotamanager.NewQuotaRegionalClient(selvpcclient.NewHTTPClient(), identity)
}
26 changes: 5 additions & 21 deletions selectel/config_test.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,13 @@
package selectel

import (
"os"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/stretchr/testify/assert"
)

func TestValidate(t *testing.T) {
config := &Config{
Token: "secret",
Region: "ru-3",
}

err := config.Validate()

assert.NoError(t, err)
}

func TestValidateNoToken(t *testing.T) {
config := &Config{}

Expand All @@ -27,15 +18,8 @@ func TestValidateNoToken(t *testing.T) {
assert.EqualError(t, actual, expected)
}

func TestValidateErrRegion(t *testing.T) {
config := &Config{
Token: "secret",
Region: "unknown region",
func checkEnvTfAcc(t *testing.T) {

Check failure on line 21 in selectel/config_test.go

View workflow job for this annotation

GitHub Actions / lint

func `checkEnvTfAcc` is unused (unused)
if os.Getenv(resource.EnvTfAcc) == "" {
t.Skipf("Acceptance tests skipped unless env '%s' set", resource.EnvTfAcc)
}

expected := "region is invalid: unknown region"

actual := config.Validate()

assert.EqualError(t, actual, expected)
}
49 changes: 46 additions & 3 deletions selectel/craas.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@ package selectel
import (
"context"
"fmt"
"net/url"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
v1 "github.com/selectel/craas-go/pkg"
"github.com/selectel/craas-go/pkg/v1/registry"
"github.com/selectel/go-selvpcclient/v3/selvpcclient"
)

const (
craasV1Endpoint = "https://cr.selcloud.ru/api/v1"
craasV1RegistryHostName = "cr.selcloud.ru"
craasV1TokenUsername = "token"
craasV1TokenUsername = "token"
)

func waitForCRaaSRegistryV1StableState(
Expand Down Expand Up @@ -59,3 +61,44 @@ func craasRegistryV1StateRefreshFunc(
return r, string(r.Status), nil
}
}

func getCRaaSClient(d *schema.ResourceData, meta interface{}) (*v1.ServiceClient, diag.Diagnostics) {
config := meta.(*Config)
selvpcClient, err := config.GetSelVPCClientWithProjectScope(d.Get("project_id").(string))
if err != nil {
return nil, diag.FromErr(fmt.Errorf("can't get project-scope selvpc client for craas: %w", err))
}

endpoint, diagErr := getEndpointForCRaaS(selvpcClient)
if diagErr != nil {
return nil, diag.FromErr(fmt.Errorf("can't get endpoint to init craas client: %w", err))
}

craasClient := v1.NewCRaaSClientV1(selvpcClient.GetXAuthToken(), endpoint)

return craasClient, nil
}

// https://cr.selcloud.ru/api/v1 -> https://cr.selcloud.ru
func getHostNameForCRaaS(endpoint string) (string, error) {
parsedEndpoint, err := url.Parse(endpoint)
if err != nil {
return "", fmt.Errorf("cant parse url for craas endpoint: %w", err)
}
return fmt.Sprintf("%s://%s", parsedEndpoint.Scheme, parsedEndpoint.Host), nil

Check failure on line 88 in selectel/craas.go

View workflow job for this annotation

GitHub Actions / lint

return with no blank line before (nlreturn)
}

func getEndpointForCRaaS(selvpcClient *selvpcclient.Client) (string, error) {
endpoints, err := selvpcClient.Catalog.GetEndpoints(CRaaS)
if err != nil {
return "", fmt.Errorf("can't get endpoint to for craas: %w", err)
}

// There is no actual regionality for CRaaS, but we need to support any environments where the region is
// called whatever
if len(endpoints) > 1 {
return "", fmt.Errorf("unexpectedly received more than one endpoint for craas")
}

return endpoints[0].URL, nil
}
42 changes: 42 additions & 0 deletions selectel/craas_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package selectel

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
v1 "github.com/selectel/craas-go/pkg"
"github.com/stretchr/testify/assert"
)

func newCRaaSTestClient(rs *terraform.ResourceState, testAccProvider *schema.Provider) (*v1.ServiceClient, error) {
config := testAccProvider.Meta().(*Config)

var projectID string

if id, ok := rs.Primary.Attributes["project_id"]; ok {
projectID = id
}

selvpcClient, err := config.GetSelVPCClientWithProjectScope(projectID)
if err != nil {
return nil, fmt.Errorf("can't get selvpc client for craas acc tests: %w", err)
}

craasEndpoint, err := getEndpointForCRaaS(selvpcClient)
if err != nil {
return nil, fmt.Errorf("can't get endpoint for craas acc tests: %w", err)
}

craasClient := v1.NewCRaaSClientV1(selvpcClient.GetXAuthToken(), craasEndpoint)

return craasClient, nil
}

func TestGetHostNameForCRaaS(t *testing.T) {
expected := "https://cr.selcloud.ru"
actual, err := getHostNameForCRaaS("https://cr.selcloud.ru/api/v1")
assert.NoError(t, err)
assert.Equal(t, expected, actual)
}
Loading

0 comments on commit c36d2be

Please sign in to comment.