From 8c79150355e917aafb08cabb29f5c9715414c48e Mon Sep 17 00:00:00 2001 From: Henrique Gontijo Date: Mon, 18 Nov 2019 09:38:32 -0800 Subject: [PATCH] Add bitbucketserver_plugin_config resource to allow managing plugins configuration. Plugin configuration documentation. --- bitbucket/data_plugin_config.go | 83 ++++++++++++++++++++ bitbucket/data_plugin_config_test.go | 29 +++++++ bitbucket/provider.go | 5 +- bitbucket/resource_plugin_config.go | 92 +++++++++++++++++++++++ bitbucket/resource_plugin_config_test.go | 30 ++++++++ docusaurus/docs/resource_plugin_config.md | 34 +++++++++ docusaurus/website/i18n/en.json | 3 + docusaurus/website/sidebars.json | 1 + 8 files changed, 276 insertions(+), 1 deletion(-) create mode 100644 bitbucket/data_plugin_config.go create mode 100644 bitbucket/data_plugin_config_test.go create mode 100644 bitbucket/resource_plugin_config.go create mode 100644 bitbucket/resource_plugin_config_test.go create mode 100644 docusaurus/docs/resource_plugin_config.md diff --git a/bitbucket/data_plugin_config.go b/bitbucket/data_plugin_config.go new file mode 100644 index 0000000..7a16ecf --- /dev/null +++ b/bitbucket/data_plugin_config.go @@ -0,0 +1,83 @@ +package bitbucket + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/url" + + "github.com/hashicorp/terraform/helper/schema" +) + +type PluginConfig struct { + ValidLicense bool `json:"validLicense"` + ValuesRaw json.RawMessage `json:"values"` + Values string +} + +func dataSourcePluginConfig() *schema.Resource { + return &schema.Resource{ + Read: dataSourcePluginConfigRead, + + Schema: map[string]*schema.Schema{ + "key": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "validlicense": { + Type: schema.TypeBool, + Optional: true, + Required: false, + ForceNew: true, + }, + "values": { + Type: schema.TypeString, + Optional: true, + Required: false, + ForceNew: true, + }, + }, + } +} + +func dataSourcePluginConfigRead(d *schema.ResourceData, m interface{}) error { + d.SetId(d.Get("key").(string)) + + pluginConfig, err := readPluginConfig(m, d.Id()) + if err != nil { + return err + } + err = d.Set("validlicense", pluginConfig.ValidLicense) + if err != nil { + return err + } + err = d.Set("values", pluginConfig.Values) + if err != nil { + return err + } + return nil +} + +func readPluginConfig(m interface{}, id string) (PluginConfig, error) { + client := m.(*BitbucketServerProvider).BitbucketClient + resourceURL := fmt.Sprintf("/rest/%s/1.0/config", url.QueryEscape(id)) + + resp, err := client.Get(resourceURL) + if err != nil { + return PluginConfig{}, err + } + var pluginConfig PluginConfig + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return PluginConfig{}, err + } + + err = json.Unmarshal(body, &pluginConfig) + if err != nil { + return PluginConfig{}, err + } + pluginConfig.Values = string(pluginConfig.ValuesRaw) + return pluginConfig, nil +} diff --git a/bitbucket/data_plugin_config_test.go b/bitbucket/data_plugin_config_test.go new file mode 100644 index 0000000..5660bcc --- /dev/null +++ b/bitbucket/data_plugin_config_test.go @@ -0,0 +1,29 @@ +package bitbucket + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccBitbucketPluginConfig_basic(t *testing.T) { + config := ` + data "bitbucketserver_plugin_config" "test" { + key = "oidc" + } + ` + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("data.bitbucketserver_plugin_config.test", "id", "oidc"), + resource.TestCheckResourceAttr("data.bitbucketserver_plugin_config.test", "validlicense", "true"), + ), + }, + }, + }) +} diff --git a/bitbucket/provider.go b/bitbucket/provider.go index a4fe949..c8af8c3 100644 --- a/bitbucket/provider.go +++ b/bitbucket/provider.go @@ -1,10 +1,11 @@ package bitbucket import ( - "github.com/gavinbunney/terraform-provider-bitbucketserver/bitbucket/marketplace" "net/http" "strings" + "github.com/gavinbunney/terraform-provider-bitbucketserver/bitbucket/marketplace" + "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/terraform" ) @@ -37,6 +38,7 @@ func Provider() terraform.ResourceProvider { "bitbucketserver_groups": dataSourceGroups(), "bitbucketserver_group_users": dataSourceGroupUsers(), "bitbucketserver_plugin": dataSourcePlugin(), + "bitbucketserver_plugin_config": dataSourcePluginConfig(), "bitbucketserver_project_hooks": dataSourceProjectHooks(), "bitbucketserver_project_permissions_groups": dataSourceProjectPermissionsGroups(), "bitbucketserver_project_permissions_users": dataSourceProjectPermissionsUsers(), @@ -52,6 +54,7 @@ func Provider() terraform.ResourceProvider { "bitbucketserver_license": resourceLicense(), "bitbucketserver_mail_server": resourceMailServer(), "bitbucketserver_plugin": resourcePlugin(), + "bitbucketserver_plugin_config": resourcePluginConfig(), "bitbucketserver_project": resourceProject(), "bitbucketserver_project_hook": resourceProjectHook(), "bitbucketserver_project_permissions_group": resourceProjectPermissionsGroup(), diff --git a/bitbucket/resource_plugin_config.go b/bitbucket/resource_plugin_config.go new file mode 100644 index 0000000..369e760 --- /dev/null +++ b/bitbucket/resource_plugin_config.go @@ -0,0 +1,92 @@ +package bitbucket + +import ( + "bytes" + "fmt" + "net/url" + + "github.com/hashicorp/terraform/helper/schema" +) + +func resourcePluginConfig() *schema.Resource { + return &schema.Resource{ + Create: resourcePluginConfigCreateOrUpdate, + Read: resourcePluginConfigRead, + Delete: resourcePluginConfigDelete, + Update: resourcePluginConfigCreateOrUpdate, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "key": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "validlicense": { + Type: schema.TypeBool, + Default: true, + Optional: true, + ForceNew: false, + }, + "values": { + Type: schema.TypeString, + Required: true, + ForceNew: false, + }, + }, + } +} + +func resourcePluginConfigCreateOrUpdate(d *schema.ResourceData, m interface{}) error { + client := m.(*BitbucketServerProvider).BitbucketClient + key := d.Get("key").(string) + values := d.Get("values").(string) + config := []byte(values) + payload := &bytes.Buffer{} + _, err := payload.Write(config) + if err != nil { + panic(err) + } + + _, err = client.Put(fmt.Sprintf("/rest/%s/1.0/config", url.QueryEscape(key)), payload) + if err != nil { + return err + } + + d.SetId(key) + + return resourcePluginConfigRead(d, m) +} + +func resourcePluginConfigRead(d *schema.ResourceData, m interface{}) error { + err := d.Set("key", d.Id()) + if err != nil { + return err + } + + key := d.Get("key").(string) + + pluginConfig, err := readPluginConfig(m, key) + if err != nil { + return err + } + + err = d.Set("validlicense", pluginConfig.ValidLicense) + if err != nil { + return err + } + + err = d.Set("values", pluginConfig.Values) + if err != nil { + return err + } + + return nil +} + +func resourcePluginConfigDelete(d *schema.ResourceData, m interface{}) error { + // Delete is a no-op + return nil +} diff --git a/bitbucket/resource_plugin_config_test.go b/bitbucket/resource_plugin_config_test.go new file mode 100644 index 0000000..efc0aa8 --- /dev/null +++ b/bitbucket/resource_plugin_config_test.go @@ -0,0 +1,30 @@ +package bitbucket + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccBitbucketPluginConfig(t *testing.T) { + config := ` + resource "bitbucketserver_plugin_config" "test" { + key = "oidc" + values = "{\"state\":\"OPTIONAL\",\"autoLogin\":\"DISABLED\",\"restAuthSso\":false,\"disableWebSudo\":false,\"issuerUrl\":\"https://example.oktapreview.com/oauth2/1234567890abcdf\",\"authUrl\":\"https://example.oktapreview.com/oauth2/1234567890abcdf/v1/authorize\",\"tokenUrl\":\"https://example.oktapreview.com/oauth2/1234567890abcdf/v1/token\",\"logoutUrl\":\"https://example.oktapreview.com/oauth2/1234567890abcdf/v1/logout\",\"checkSessionIFrameUrl\":\"\",\"jwkSetUrl\":\"https://example.oktapreview.com/oauth2/1234567890abcdf/v1/keys\",\"usernameClaim\":\"preferred_username\",\"clientId\":\"123123123123123123\",\"clientSecret\":\"12312312312312312312312123123123123123123123123\",\"additionalAuthReqParams\":{\"scope\":\"groups\"},\"ssoButtonText\":\"OpenID Connect SSO\",\"redirectUrl\":\"\",\"createUsers\":true,\"createGroups\":false,\"updateUserInfo\":true,\"groupsClaim\":\"groups\",\"updateGroups\":true,\"requireGroups\":false,\"defaultGroups\":[],\"additionalGroups\":[\"stash-users\"]}" + } + ` + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("bitbucketserver_plugin_config.test", "key", "oidc"), + resource.TestCheckResourceAttr("bitbucketserver_plugin_config.test", "values", "{\"state\":\"OPTIONAL\",\"autoLogin\":\"DISABLED\",\"restAuthSso\":false,\"disableWebSudo\":false,\"issuerUrl\":\"https://example.oktapreview.com/oauth2/1234567890abcdf\",\"authUrl\":\"https://example.oktapreview.com/oauth2/1234567890abcdf/v1/authorize\",\"tokenUrl\":\"https://example.oktapreview.com/oauth2/1234567890abcdf/v1/token\",\"logoutUrl\":\"https://example.oktapreview.com/oauth2/1234567890abcdf/v1/logout\",\"checkSessionIFrameUrl\":\"\",\"jwkSetUrl\":\"https://example.oktapreview.com/oauth2/1234567890abcdf/v1/keys\",\"usernameClaim\":\"preferred_username\",\"clientId\":\"123123123123123123\",\"clientSecret\":\"12312312312312312312312123123123123123123123123\",\"additionalAuthReqParams\":{\"scope\":\"groups\"},\"ssoButtonText\":\"OpenID Connect SSO\",\"redirectUrl\":\"\",\"createUsers\":true,\"createGroups\":false,\"updateUserInfo\":true,\"groupsClaim\":\"groups\",\"updateGroups\":true,\"requireGroups\":false,\"defaultGroups\":[],\"additionalGroups\":[\"stash-users\"]}"), + ), + }, + }, + }) +} diff --git a/docusaurus/docs/resource_plugin_config.md b/docusaurus/docs/resource_plugin_config.md new file mode 100644 index 0000000..d025b70 --- /dev/null +++ b/docusaurus/docs/resource_plugin_config.md @@ -0,0 +1,34 @@ +--- +id: bitbucketserver_plugin_config +title: bitbucketserver_plugin_config +--- + +Configure plugins. + +## Example Usage + +```hcl +resource "bitbucketserver_plugin_config" "mypluginconfig" { + key = "my-plugin-key" + values = "{"\key\": \"value\"}" +} +``` + +## Argument Reference + +* `key` - Required. Unique key of the plugin. This is not the same used by plugin install. +* `values` - Required. Plugin configuration in JSON format. + +## Attribute Reference + +* `key` - Unique key of the plugin. This is not the same used by plugin install. +* `validlicense` - Indicates if the plugins has a valid license. +* `values` - Plugin configuration in JSON format. + +## Import + +Import a plugin config reference via the key: + +``` +terraform import bitbucketserver_plugin_config.mypluginkey my-plugin-key +``` diff --git a/docusaurus/website/i18n/en.json b/docusaurus/website/i18n/en.json index 181e87b..73078b2 100644 --- a/docusaurus/website/i18n/en.json +++ b/docusaurus/website/i18n/en.json @@ -64,6 +64,9 @@ "bitbucketserver_mail_server": { "title": "bitbucketserver_mail_server" }, + "bitbucketserver_plugin_config": { + "title": "bitbucketserver_plugin_config" + }, "bitbucketserver_plugin": { "title": "bitbucketserver_plugin" }, diff --git a/docusaurus/website/sidebars.json b/docusaurus/website/sidebars.json index a0711d0..c9a802b 100755 --- a/docusaurus/website/sidebars.json +++ b/docusaurus/website/sidebars.json @@ -26,6 +26,7 @@ "bitbucketserver_license", "bitbucketserver_mail_server", "bitbucketserver_plugin", + "bitbucketserver_plugin_config", "bitbucketserver_project", "bitbucketserver_project_hook", "bitbucketserver_project_permissions_group",