diff --git a/github/data_source_github_organization_custom_properties.go b/github/data_source_github_organization_custom_properties.go new file mode 100644 index 0000000000..a67cf466bb --- /dev/null +++ b/github/data_source_github_organization_custom_properties.go @@ -0,0 +1,71 @@ +package github + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func dataSourceGithubOrganizationCustomProperties() *schema.Resource { + return &schema.Resource{ + Read: dataSourceGithubOrganizationCustomPropertiesRead, + + Schema: map[string]*schema.Schema{ + "property_name": { + Type: schema.TypeString, + Required: true, + }, + "value_type": { + Type: schema.TypeString, + Optional: true, + }, + "required": { + Type: schema.TypeBool, + Optional: true, + }, + "default_value": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "allowed_values": { + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + } +} + +func dataSourceGithubOrganizationCustomPropertiesRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*Owner).v3client + ctx := context.Background() + orgName := meta.(*Owner).name + + err := checkOrganization(meta) + if err != nil { + return err + } + + propertyAttributes, _, err := client.Organizations.GetCustomProperty(ctx, orgName, d.Get("property_name").(string)) + if err != nil { + return fmt.Errorf("error querying GitHub custom properties %s: %s", orgName, err) + } + + d.SetId("org-custom-properties") + d.Set("allowed_values", propertyAttributes.AllowedValues) + d.Set("default_value", propertyAttributes.DefaultValue) + d.Set("description", propertyAttributes.Description) + d.Set("property_name", propertyAttributes.PropertyName) + d.Set("required", propertyAttributes.Required) + d.Set("value_type", propertyAttributes.ValueType) + + return nil +} diff --git a/github/provider.go b/github/provider.go index 70441a0349..958a34edee 100644 --- a/github/provider.go +++ b/github/provider.go @@ -131,6 +131,7 @@ func Provider() terraform.ResourceProvider { "github_membership": resourceGithubMembership(), "github_organization_block": resourceOrganizationBlock(), "github_organization_custom_role": resourceGithubOrganizationCustomRole(), + "github_organization_custom_properties": resourceGithubOrganizationCustomProperties(), "github_organization_project": resourceGithubOrganizationProject(), "github_organization_security_manager": resourceGithubOrganizationSecurityManager(), "github_organization_ruleset": resourceGithubOrganizationRuleset(), @@ -202,6 +203,7 @@ func Provider() terraform.ResourceProvider { "github_membership": dataSourceGithubMembership(), "github_organization": dataSourceGithubOrganization(), "github_organization_custom_role": dataSourceGithubOrganizationCustomRole(), + "github_organization_custom_properties": dataSourceGithubOrganizationCustomProperties(), "github_organization_external_identities": dataSourceGithubOrganizationExternalIdentities(), "github_organization_ip_allow_list": dataSourceGithubOrganizationIpAllowList(), "github_organization_team_sync_groups": dataSourceGithubOrganizationTeamSyncGroups(), diff --git a/github/resource_github_organisation_custom_properties.go b/github/resource_github_organisation_custom_properties.go new file mode 100644 index 0000000000..aa598642fa --- /dev/null +++ b/github/resource_github_organisation_custom_properties.go @@ -0,0 +1,141 @@ +package github + +import ( + "context" + + "github.com/google/go-github/v57/github" + "github.com/hashicorp/terraform-plugin-sdk/helper/customdiff" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func resourceGithubOrganizationCustomProperties() *schema.Resource { + return &schema.Resource{ + Create: resourceGithubCustomPropertiesCreate, + Read: resourceGithubCustomPropertiesRead, + Update: resourceGithubCustomPropertiesUpdate, + Delete: resourceGithubCustomPropertiesDelete, + Importer: &schema.ResourceImporter{ + State: resourceGithubCustomPropertiesImport, + }, + + CustomizeDiff: customdiff.Sequence( + customdiff.ComputedIf("slug", func(d *schema.ResourceDiff, meta interface{}) bool { + return d.HasChange("name") + }), + ), + + Schema: map[string]*schema.Schema{ + "property_name": { + Type: schema.TypeString, + Required: true, + Description: "The name of the custom property", + }, + "value_type": { + Type: schema.TypeString, + Optional: true, + Description: "The type of the custom property", + }, + "required": { + Type: schema.TypeBool, + Optional: true, + Description: "Whether the custom property is required", + }, + "default_value": { + Type: schema.TypeString, + Description: "The default value of the custom property", + Optional: true, + Computed: true, + }, + "description": { + Description: "The description of the custom property", + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "allowed_values": { + Description: "The allowed values of the custom property", + Type: schema.TypeList, + Optional: true, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + } +} + +func resourceGithubCustomPropertiesCreate(d *schema.ResourceData, meta interface{}) error { + ctx := context.Background() + client := meta.(*Owner).v3client + ownerName := meta.(*Owner).name + + propertyName := d.Get("property_name").(string) + valueType := d.Get("value_type").(string) + required := d.Get("required").(bool) + defaultValue := d.Get("default_value").(string) + description := d.Get("description").(string) + allowedValues := d.Get("allowed_values").([]interface{}) + var allowedValuesString []string + for _, v := range allowedValues { + allowedValuesString = append(allowedValuesString, v.(string)) + } + + customProperty, _, err := client.Organizations.CreateOrUpdateCustomProperty(ctx, ownerName, d.Get("property_name").(string), &github.CustomProperty{ + PropertyName: &propertyName, + ValueType: valueType, + Required: &required, + DefaultValue: &defaultValue, + Description: &description, + AllowedValues: allowedValuesString, + }) + if err != nil { + return err + } + + d.SetId(*customProperty.PropertyName) + return resourceGithubCustomPropertiesRead(d, meta) +} + +func resourceGithubCustomPropertiesRead(d *schema.ResourceData, meta interface{}) error { + ctx := context.Background() + client := meta.(*Owner).v3client + ownerName := meta.(*Owner).name + + customProperty, _, err := client.Organizations.GetCustomProperty(ctx, ownerName, d.Get("property_name").(string)) + if err != nil { + return err + } + + d.SetId(*customProperty.PropertyName) + d.Set("allowed_values", customProperty.AllowedValues) + d.Set("default_value", customProperty.DefaultValue) + d.Set("description", customProperty.Description) + d.Set("property_name", customProperty.PropertyName) + d.Set("required", customProperty.Required) + d.Set("value_type", customProperty.ValueType) + + return nil +} + +func resourceGithubCustomPropertiesUpdate(d *schema.ResourceData, meta interface{}) error { + if err := resourceGithubCustomPropertiesCreate(d, meta); err != nil { + return err + } + return resourceGithubTeamRead(d, meta) +} + +func resourceGithubCustomPropertiesDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*Owner).v3client + ownerName := meta.(*Owner).name + + _, err := client.Organizations.RemoveCustomProperty(context.Background(), ownerName, d.Get("property_name").(string)) + if err != nil { + return err + } + + return nil +} + +func resourceGithubCustomPropertiesImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + // WIP + return []*schema.ResourceData{d}, nil +}