Skip to content

Commit

Permalink
Add support to use oauth credentials (edixos#20)
Browse files Browse the repository at this point in the history
Signed-off-by: ekarlso <[email protected]>
Co-authored-by: ekarlso <[email protected]>
Signed-off-by: ekarlso <[email protected]>
  • Loading branch information
ekarlso and ekarlso committed Oct 7, 2024
1 parent 0f45615 commit fb11ac5
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 14 deletions.
44 changes: 43 additions & 1 deletion config/databases/config.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,48 @@
package databases

import "github.com/crossplane/upjet/pkg/config"
import (
"errors"
"fmt"

"github.com/crossplane/upjet/pkg/config"
)

const (
shortGroup = "databases"
)

var ErrTransformEndpointToConnection = errors.New("Error enriching Connection Details")

func addConnectionInfo(attr map[string]any) (map[string][]byte, error) {
conn := map[string][]byte{}

if endpointData, ok := attr["endpoints"]; ok {
if endpoints, ok := endpointData.([]map[string]interface{}); ok {
for idx, endpoint := range endpoints {
for key, value := range endpoint {
endpointKey := fmt.Sprintf("endpoint_%d_%s", idx, key)

val := fmt.Sprintf("%s", value)
attr[endpointKey] = val
fmt.Printf("Endpoint %s -> %s", endpointKey, val)
}
}
} else {
return nil, fmt.Errorf("Could not decode endpoints: %w", ErrTransformEndpointToConnection)
}
} else {
return nil, fmt.Errorf("Could not find endpoints: %w", ErrTransformEndpointToConnection)
}

return conn, nil
}

// Configure configures individual resources by adding custom ResourceConfigurators.
func Configure(p *config.Provider) {
p.AddResourceConfigurator("ovh_cloud_project_database", func(r *config.Resource) {
r.ShortGroup = shortGroup
r.Sensitive.AdditionalConnectionDetailsFn = addConnectionInfo
r.UseAsync = true
})
p.AddResourceConfigurator("ovh_cloud_project_database_database", func(r *config.Resource) {
r.ShortGroup = shortGroup
Expand Down Expand Up @@ -94,7 +127,16 @@ func Configure(p *config.Provider) {
r.References["cluster_id"] = config.Reference{
TerraformName: "ovh_cloud_project_database",
}

r.Sensitive.AdditionalConnectionDetailsFn = func(attr map[string]any) (map[string][]byte, error) {
conn := map[string][]byte{}

conn["username"] = []byte(attr["name"].(string))

return conn, nil
}
})

p.AddResourceConfigurator("ovh_cloud_project_database_user", func(r *config.Resource) {
r.ShortGroup = shortGroup
r.References["cluster_id"] = config.Reference{
Expand Down
48 changes: 48 additions & 0 deletions config/databases/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package databases

import (
"testing"

"github.com/stretchr/testify/assert"
)

type Endpoints = []map[string]any

func TestAddEndpointInformation(t *testing.T) {
attrs := map[string]any{
"endpoints": Endpoints{
{
"uri": "rediss://<username>:<password>@redis-526fe66a-od8a8be8e.database.cloud.ovh.net:20185",
"domain": "redis-526fe66a-od8a8be8e.database.cloud.ovh.net",
"port": 20185,
},
},
}

conn, err := addConnectionInfo(attrs)

assert.Nil(t, err)
assert.NotNil(t, conn)

assert.Len(t, conn, 3)
assert.Equal(t, []byte("rediss://<username>:<password>@redis-526fe66a-od8a8be8e.database.cloud.ovh.net:20185"), conn["endpoint_0_uri"])
assert.Equal(t, []byte("redis-526fe66a-od8a8be8e.database.cloud.ovh.net"), conn["endpoint_0_domain"])
assert.Equal(t, []byte("20185"), conn["endpoint_0_port"])
}

func TestAddEndpointInformationFailedDecode(t *testing.T) {
attrs := map[string]any{
"endpointss": Endpoints{
{
"uri": "rediss://<username>:<password>@redis-526fe66a-od8a8be8e.database.cloud.ovh.net:20185",
"domain": "redis-526fe66a-od8a8be8e.database.cloud.ovh.net",
"port": 20185,
},
},
}

conn, err := addConnectionInfo(attrs)

assert.NotNil(t, err)
assert.Nil(t, conn)
}
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ require (
github.com/go-openapi/jsonpointer v0.19.6 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.3 // indirect
github.com/go-viper/mapstructure/v2 v2.2.1
github.com/gobuffalo/flect v1.0.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
Expand Down Expand Up @@ -83,13 +84,15 @@ require (
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/muvaf/typewriter v0.0.0-20220131201631-921e94e8e8d7 // indirect
github.com/oklog/run v1.0.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.18.0 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/common v0.45.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cobra v1.8.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/testify v1.9.0 // indirect
github.com/tmccombs/hcl2json v0.3.3 // indirect
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M=
github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8=
github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/gobuffalo/flect v1.0.2 h1:eqjPGSo2WmjgY2XlpGwo2NXgL3RucAKo4k4qQMNA5sA=
github.com/gobuffalo/flect v1.0.2/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
Expand Down Expand Up @@ -236,6 +238,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tmccombs/hcl2json v0.3.3 h1:+DLNYqpWE0CsOQiEZu+OZm5ZBImake3wtITYxQ8uLFQ=
github.com/tmccombs/hcl2json v0.3.3/go.mod h1:Y2chtz2x9bAeRTvSibVRVgbLJhLJXKlUeIvjeVdnm4w=
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
Expand Down
59 changes: 46 additions & 13 deletions internal/clients/ovh.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,18 @@ const (
errTrackUsage = "cannot track ProviderConfig usage"
errExtractCredentials = "cannot extract credentials"
errUnmarshalCredentials = "cannot unmarshal ovh credentials as JSON"
errNoValidCredentials = "cannot find valid credentials"
)

type OVHCredentials struct {
Endpoint string `json:"endpoint"`
ApplicationKey string `json:"application_key,omitempty"`
ApplicationSecret string `json:"application_secret,omitempty"`
ConsumerKey string `json:"consumer_key,omitempty"`
ClientID string `json:"client_id,omitempty"`
ClientSecret string `json:"client_secret,omitempty"`
}

// TerraformSetupBuilder builds Terraform a terraform.SetupFn function which
// returns Terraform provider setup configuration
func TerraformSetupBuilder(version, providerSource, providerVersion string) terraform.SetupFn {
Expand All @@ -53,22 +63,45 @@ func TerraformSetupBuilder(version, providerSource, providerVersion string) terr
return ps, errors.Wrap(err, errTrackUsage)
}

data, err := resource.CommonCredentialExtractor(ctx, pc.Spec.Credentials.Source, client, pc.Spec.Credentials.CommonCredentialSelectors)
cfg, err := configureClient(ctx, pc, client)
if err != nil {
return ps, errors.Wrap(err, errExtractCredentials)
}
creds := map[string]string{}
if err := json.Unmarshal(data, &creds); err != nil {
return ps, errors.Wrap(err, errUnmarshalCredentials)
return ps, err
}

// Set credentials in Terraform provider configuration.
ps.Configuration = map[string]any{
"endpoint": creds["endpoint"],
"application_key": creds["application_key"],
"application_secret": creds["application_secret"],
"consumer_key": creds["consumer_key"],
}
ps.Configuration = cfg

return ps, nil
}
}

func configureClient(ctx context.Context, pc *v1beta1.ProviderConfig, client client.Client) (map[string]any, error) {
data, err := resource.CommonCredentialExtractor(ctx, pc.Spec.Credentials.Source, client, pc.Spec.Credentials.CommonCredentialSelectors)
if err != nil {
return nil, errors.Wrap(err, errExtractCredentials)
}

var creds OVHCredentials
if err := json.Unmarshal(data, &creds); err != nil {
return nil, errors.Wrap(err, errUnmarshalCredentials)
}

// Set credentials in Terraform provider configuration.
cfg := map[string]any{
"endpoint": creds.Endpoint,
}

if creds.ApplicationKey != "" && creds.ApplicationSecret != "" && creds.ConsumerKey != "" {
cfg["application_key"] = creds.ApplicationKey
cfg["application_secret"] = creds.ApplicationSecret
cfg["consumer_key"] = creds.ConsumerKey
return cfg, nil
}

if creds.ClientID != "" && creds.ClientSecret != "" {
cfg["client_id"] = creds.ClientID
cfg["client_secret"] = creds.ClientSecret
return cfg, nil
}

return cfg, errors.New(errNoValidCredentials)
}

0 comments on commit fb11ac5

Please sign in to comment.