diff --git a/plugins/hcloud/api_token.go b/plugins/hcloud/api_token.go new file mode 100644 index 000000000..fd26123fc --- /dev/null +++ b/plugins/hcloud/api_token.go @@ -0,0 +1,71 @@ +package hcloud + +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 APIToken() schema.CredentialType { + return schema.CredentialType{ + Name: credname.APIToken, + DocsURL: sdk.URL("https://github.com/hetznercloud/cli"), + ManagementURL: sdk.URL("https://console.hetzner.cloud/projects"), + Fields: []schema.CredentialField{ + { + Name: fieldname.Token, + MarkdownDescription: "Token used to authenticate to Hetzner Cloud.", + Secret: true, + Composition: &schema.ValueComposition{ + Length: 64, + Charset: schema.Charset{ + Uppercase: true, + Lowercase: true, + Digits: true, + }, + }, + }, + }, + DefaultProvisioner: provision.EnvVars(defaultEnvVarMapping), + Importer: importer.TryAll( + importer.TryEnvVarPair(defaultEnvVarMapping), + TryHetznerCloudConfigFile(), + )} +} + +var defaultEnvVarMapping = map[string]sdk.FieldName{ + "HCLOUD_TOKEN": fieldname.Token, +} + +func TryHetznerCloudConfigFile() sdk.Importer { + return importer.TryFile("~/.config/hcloud/cli.toml", func(ctx context.Context, contents importer.FileContents, in sdk.ImportInput, out *sdk.ImportAttempt) { + var config Config + if err := contents.ToTOML(&config); err != nil { + out.AddError(err) + return + } + + for _, configContext := range config.Contexts { + out.AddCandidate(sdk.ImportCandidate{ + Fields: map[sdk.FieldName]string{ + fieldname.Token: configContext.Token, + }, + NameHint: importer.SanitizeNameHint(configContext.Name), + }) + } + }) +} + +type Config struct { + Contexts []ConfigContext `toml:"contexts"` +} + +type ConfigContext struct { + Name string `toml:"name"` + Token string `toml:"token"` +} diff --git a/plugins/hcloud/api_token_test.go b/plugins/hcloud/api_token_test.go new file mode 100644 index 000000000..dda88e293 --- /dev/null +++ b/plugins/hcloud/api_token_test.go @@ -0,0 +1,26 @@ +package hcloud + +import ( + "testing" + + "github.com/1Password/shell-plugins/sdk" + "github.com/1Password/shell-plugins/sdk/plugintest" + "github.com/1Password/shell-plugins/sdk/schema/fieldname" +) + +func TestImportingTheHetznerConfig(t *testing.T) { + expectedFields := map[sdk.FieldName]string{ + fieldname.Token: "dcAuOpQaCNvjzsNPmeGXvegHBdq4Zamx8QjI8ibxfErzy34fjL4ZOITFvdP5SKct", + } + + plugintest.TestImporter(t, APIToken().Importer, map[string]plugintest.ImportCase{ + "Hcloud config file": { + Files: map[string]string{ + "~/.config/hcloud/cli.toml": plugintest.LoadFixture(t, "hcloud.toml"), + }, + ExpectedCandidates: []sdk.ImportCandidate{ + {Fields: expectedFields, NameHint: ""}, + }, + }, + }) +} diff --git a/plugins/hcloud/hcloud.go b/plugins/hcloud/hcloud.go new file mode 100644 index 000000000..3edf268ed --- /dev/null +++ b/plugins/hcloud/hcloud.go @@ -0,0 +1,22 @@ +package hcloud + +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 HetznerCloudCLI() schema.Executable { + return schema.Executable{ + Name: "Hetzner Cloud CLI", + Runs: []string{"hcloud"}, + DocsURL: sdk.URL("https://github.com/hetznercloud/cli"), + NeedsAuth: needsauth.NotForHelpOrVersion(), + Uses: []schema.CredentialUsage{ + { + Name: credname.APIToken, + }, + }, + } +} diff --git a/plugins/hcloud/plugin.go b/plugins/hcloud/plugin.go new file mode 100644 index 000000000..cd80b8c91 --- /dev/null +++ b/plugins/hcloud/plugin.go @@ -0,0 +1,22 @@ +package hcloud + +import ( + "github.com/1Password/shell-plugins/sdk" + "github.com/1Password/shell-plugins/sdk/schema" +) + +func New() schema.Plugin { + return schema.Plugin{ + Name: "hcloud", + Platform: schema.PlatformInfo{ + Name: "Hetzner Cloud", + Homepage: sdk.URL("https://console.hetzner.cloud"), + }, + Credentials: []schema.CredentialType{ + APIToken(), + }, + Executables: []schema.Executable{ + HetznerCloudCLI(), + }, + } +} diff --git a/plugins/hcloud/test-fixtures/hcloud.toml b/plugins/hcloud/test-fixtures/hcloud.toml new file mode 100644 index 000000000..8bba6190d --- /dev/null +++ b/plugins/hcloud/test-fixtures/hcloud.toml @@ -0,0 +1,5 @@ +active_context = 'default' + +[[contexts]] +name = 'default' +token = 'dcAuOpQaCNvjzsNPmeGXvegHBdq4Zamx8QjI8ibxfErzy34fjL4ZOITFvdP5SKct' \ No newline at end of file