Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Endpoint to secret #23

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 55 additions & 1 deletion config/databases/config.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,60 @@
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 endpoints, ok := attr["endpoints"]; ok {
if endpointList, ok := endpoints.([]any); ok {
for idx, item := range endpointList {
if endpoint, ok := item.(map[string]any); ok {
for key, value := range endpoint {
endpointKey := fmt.Sprintf("endpoint_%d_%s", idx, key)

var val []byte
switch value.(type) {
case float64:
val = []byte(fmt.Sprintf("%.0f", value))
case bool:
val = []byte(fmt.Sprintf("%b", value))
case string:
val = []byte(fmt.Sprintf("%s", value))
default:
continue
}

conn[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 +139,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"
"github.com/stretchr/testify/require"
)

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

conn, err := addConnectionInfo(attrs)

require.NoError(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": []map[string]any{
{
"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)

require.Error(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)
}
Loading