diff --git a/plugins/scaleway/access_key.go b/plugins/scaleway/access_key.go new file mode 100644 index 000000000..6f7f2b5ce --- /dev/null +++ b/plugins/scaleway/access_key.go @@ -0,0 +1,147 @@ +package scaleway + +import ( + "context" + + "github.com/1Password/shell-plugins/sdk" + "github.com/1Password/shell-plugins/sdk/importer" + "github.com/1Password/shell-plugins/sdk/provision" + "github.com/1Password/shell-plugins/sdk/schema" + "github.com/1Password/shell-plugins/sdk/schema/credname" + "github.com/1Password/shell-plugins/sdk/schema/fieldname" +) + +func AccessKey() schema.CredentialType { + return schema.CredentialType{ + Name: credname.AccessKey, + DocsURL: sdk.URL("https://www.scaleway.com/en/docs/iam/how-to/create-api-keys/"), + ManagementURL: sdk.URL("https://console.scaleway.com/iam/api-keys"), + Fields: []schema.CredentialField{ + { + Name: fieldname.AccessKeyID, + MarkdownDescription: "Access key ID", + Secret: false, + Optional: false, + Composition: &schema.ValueComposition{ + Length: 20, + Charset: schema.Charset{ + Uppercase: true, + Digits: true, + }, + }, + }, + { + Name: fieldname.SecretAccessKey, + MarkdownDescription: "Secret key.", + Secret: true, + Optional: false, + Composition: &schema.ValueComposition{ + Length: 36, + Charset: schema.Charset{ + Lowercase: true, + Digits: true, + }, + }, + }, + { + Name: fieldname.DefaultRegion, + MarkdownDescription: "Default region.", + Secret: false, + Optional: true, + Composition: &schema.ValueComposition{ + Charset: schema.Charset{ + Lowercase: true, + Uppercase: true, + Digits: true, + }, + }, + }, + { + Name: fieldname.DefaultZone, + MarkdownDescription: "Default zone.", + Secret: false, + Optional: true, + Composition: &schema.ValueComposition{ + Charset: schema.Charset{ + Lowercase: true, + Uppercase: true, + Digits: true, + }, + }, + }, + { + Name: fieldname.ProjectID, + MarkdownDescription: "Project ID.", + Secret: false, + Optional: true, + Composition: &schema.ValueComposition{ + Charset: schema.Charset{ + Lowercase: true, + Uppercase: true, + Digits: true, + }, + }, + }, + { + Name: fieldname.OrgID, + MarkdownDescription: "Organization ID.", + Secret: false, + Optional: true, + Composition: &schema.ValueComposition{ + Charset: schema.Charset{ + Lowercase: true, + Uppercase: true, + Digits: true, + }, + }, + }, + }, + DefaultProvisioner: provision.EnvVars(defaultEnvVarMapping), + Importer: importer.TryAll( + importer.TryEnvVarPair(defaultEnvVarMapping), + TryScalewayConfigFile(), + )} +} + +var defaultEnvVarMapping = map[string]sdk.FieldName{ + "SCW_ACCESS_KEY": fieldname.AccessKeyID, + "SCW_SECRET_KEY": fieldname.SecretAccessKey, + "SCW_DEFAULT_REGION": fieldname.DefaultRegion, + "SCW_DEFAULT_ZONE": fieldname.DefaultZone, + "SCW_DEFAULT_PROJECT_ID": fieldname.ProjectID, + "SCW_DEFAULT_ORGANIZATION_ID": fieldname.OrgID, +} + +func TryScalewayConfigFile() sdk.Importer { + return importer.TryFile("~/.config/scw/config.yaml", func(ctx context.Context, contents importer.FileContents, in sdk.ImportInput, out *sdk.ImportAttempt) { + var config Config + if err := contents.ToYAML(&config); err != nil { + out.AddError(err) + return + } + + if config.AccessKey == "" || config.SecretKey == "" { + return + } + + out.AddCandidate(sdk.ImportCandidate{ + Fields: map[sdk.FieldName]string{ + fieldname.AccessKeyID: config.AccessKey, + fieldname.SecretAccessKey: config.SecretKey, + fieldname.DefaultRegion: config.DefaultRegion, + fieldname.DefaultZone: config.DefaultZone, + fieldname.ProjectID: config.ProjectID, + fieldname.OrgID: config.OrganizationID, + }, + }) + }) +} + +type Config struct { + AccessKey string `yaml:"access_key"` + SecretKey string `yaml:"secret_key"` + DefaultRegion string `yaml:"default_region,omitempty"` + DefaultZone string `yaml:"default_zone,omitempty"` + ProjectID string `yaml:"default_project_id,omitempty"` + OrganizationID string `yaml:"default_organization_id,omitempty"` +} diff --git a/plugins/scaleway/access_key_test.go b/plugins/scaleway/access_key_test.go new file mode 100644 index 000000000..a6ec74a0f --- /dev/null +++ b/plugins/scaleway/access_key_test.go @@ -0,0 +1,78 @@ +package scaleway + +import ( + "testing" + + "github.com/1Password/shell-plugins/sdk" + "github.com/1Password/shell-plugins/sdk/plugintest" + "github.com/1Password/shell-plugins/sdk/schema/fieldname" +) + +func TestAccessKeyProvisioner(t *testing.T) { + plugintest.TestProvisioner(t, AccessKey().DefaultProvisioner, map[string]plugintest.ProvisionCase{ + "default": { + ItemFields: map[sdk.FieldName]string{ + fieldname.AccessKeyID: "AABBCCDDEEFFGGHHIIJJ", + fieldname.SecretAccessKey: "c3a22663-2770-4428-8166-c214643cd70b", + fieldname.DefaultRegion: "fr-par", + fieldname.DefaultZone: "fr-par-1", + fieldname.ProjectID: "d3a22663-2770-4428-8166-c214643cd70c", + fieldname.OrgID: "e3a22663-2770-4428-8166-c214643cd70d", + }, + ExpectedOutput: sdk.ProvisionOutput{ + Environment: map[string]string{ + "SCW_ACCESS_KEY": "AABBCCDDEEFFGGHHIIJJ", + "SCW_SECRET_KEY": "c3a22663-2770-4428-8166-c214643cd70b", + "SCW_DEFAULT_REGION": "fr-par", + "SCW_DEFAULT_ZONE": "fr-par-1", + "SCW_DEFAULT_PROJECT_ID": "d3a22663-2770-4428-8166-c214643cd70c", + "SCW_DEFAULT_ORGANIZATION_ID": "e3a22663-2770-4428-8166-c214643cd70d", + }, + }, + }, + }) +} + +func TestAccessKeyImporter(t *testing.T) { + plugintest.TestImporter(t, AccessKey().Importer, map[string]plugintest.ImportCase{ + "environment": { + Environment: map[string]string{ + "SCW_ACCESS_KEY": "yolo", + "SCW_SECRET_KEY": "c3a22663-2770-4428-8166-c214643cd70b", + "SCW_DEFAULT_REGION": "fr-par", + "SCW_DEFAULT_ZONE": "fr-par-1", + "SCW_DEFAULT_PROJECT_ID": "01696acf-7a78-4d94-a129-5e135d0377cc", + "SCW_DEFAULT_ORGANIZATION_ID": "14800390-5df1-4a90-b38e-9b461bdcd108", + }, + ExpectedCandidates: []sdk.ImportCandidate{ + { + Fields: map[sdk.FieldName]string{ + fieldname.AccessKeyID: "yolo", + fieldname.SecretAccessKey: "c3a22663-2770-4428-8166-c214643cd70b", + fieldname.DefaultRegion: "fr-par", + fieldname.DefaultZone: "fr-par-1", + fieldname.ProjectID: "01696acf-7a78-4d94-a129-5e135d0377cc", + fieldname.OrgID: "14800390-5df1-4a90-b38e-9b461bdcd108", + }, + }, + }, + }, + "config file": { + Files: map[string]string{ + "~/.config/scw/config.yaml": plugintest.LoadFixture(t, "config"), + }, + ExpectedCandidates: []sdk.ImportCandidate{ + { + Fields: map[sdk.FieldName]string{ + fieldname.AccessKeyID: "yolo", + fieldname.SecretAccessKey: "c3a22663-2770-4428-8166-c214643cd70b", + fieldname.DefaultRegion: "fr-par", + fieldname.DefaultZone: "fr-par-1", + fieldname.ProjectID: "01696acf-7a78-4d94-a129-5e135d0377cc", + fieldname.OrgID: "14800390-5df1-4a90-b38e-9b461bdcd108", + }, + }, + }, + }, + }) +} diff --git a/plugins/scaleway/plugin.go b/plugins/scaleway/plugin.go new file mode 100644 index 000000000..180fc4e95 --- /dev/null +++ b/plugins/scaleway/plugin.go @@ -0,0 +1,22 @@ +package scaleway + +import ( + "github.com/1Password/shell-plugins/sdk" + "github.com/1Password/shell-plugins/sdk/schema" +) + +func New() schema.Plugin { + return schema.Plugin{ + Name: "scaleway", + Platform: schema.PlatformInfo{ + Name: "Scaleway", + Homepage: sdk.URL("https://scaleway.com"), + }, + Credentials: []schema.CredentialType{ + AccessKey(), + }, + Executables: []schema.Executable{ + ScalewayCLI(), + }, + } +} diff --git a/plugins/scaleway/scw.go b/plugins/scaleway/scw.go new file mode 100644 index 000000000..ee75b2c2e --- /dev/null +++ b/plugins/scaleway/scw.go @@ -0,0 +1,25 @@ +package scaleway + +import ( + "github.com/1Password/shell-plugins/sdk" + "github.com/1Password/shell-plugins/sdk/needsauth" + "github.com/1Password/shell-plugins/sdk/schema" + "github.com/1Password/shell-plugins/sdk/schema/credname" +) + +func ScalewayCLI() schema.Executable { + return schema.Executable{ + Name: "Scaleway CLI", + Runs: []string{"scw"}, + DocsURL: sdk.URL("https://www.scaleway.com/en/cli/"), + NeedsAuth: needsauth.IfAll( + needsauth.NotForHelpOrVersion(), + needsauth.NotWithoutArgs(), + ), + Uses: []schema.CredentialUsage{ + { + Name: credname.AccessKey, + }, + }, + } +} diff --git a/plugins/scaleway/test-fixtures/config b/plugins/scaleway/test-fixtures/config new file mode 100644 index 000000000..fe3b64176 --- /dev/null +++ b/plugins/scaleway/test-fixtures/config @@ -0,0 +1,7 @@ +# comment +access_key: yolo +secret_key: c3a22663-2770-4428-8166-c214643cd70b +default_organization_id: 14800390-5df1-4a90-b38e-9b461bdcd108 +default_project_id: 01696acf-7a78-4d94-a129-5e135d0377cc +default_region: fr-par +default_zone: fr-par-1 diff --git a/sdk/schema/fieldname/names.go b/sdk/schema/fieldname/names.go index 08cfa4e05..1ffc34a6d 100644 --- a/sdk/schema/fieldname/names.go +++ b/sdk/schema/fieldname/names.go @@ -28,6 +28,7 @@ const ( Credentials = sdk.FieldName("Credentials") Database = sdk.FieldName("Database") DefaultRegion = sdk.FieldName("Default Region") + DefaultZone = sdk.FieldName("Default Zone") Deployment = sdk.FieldName("Deployment") Email = sdk.FieldName("Email") Endpoint = sdk.FieldName("Endpoint")