diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b82474f..1f6364f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased + +- SUP-2506: Organization rule resource and data source implementation [[PR #562](https://github.com/buildkite/terraform-provider-buildkite/pull/562)] @james2791 + ## [v1.11.0](https://github.com/buildkite/terraform-provider-buildkite/compare/v1.10.2...v1.11.0) - SUP-2536: Asserting pipeline template datasource attributes on its tests [[PR #559](https://github.com/buildkite/terraform-provider-buildkite/pull/559)] @james2791 diff --git a/buildkite/data_source_organization_rule.go b/buildkite/data_source_organization_rule.go new file mode 100644 index 00000000..004026df --- /dev/null +++ b/buildkite/data_source_organization_rule.go @@ -0,0 +1,271 @@ +package buildkite + +import ( + "context" + "fmt" + "log" + + "github.com/MakeNowJust/heredoc" + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" +) + +type organizationRuleDatasourceModel struct { + ID types.String `tfsdk:"id"` + UUID types.String `tfsdk:"uuid"` + Description types.String `tfsdk:"description"` + Type types.String `tfsdk:"type"` + Value types.String `tfsdk:"value"` + SourceType types.String `tfsdk:"source_type"` + SourceUUID types.String `tfsdk:"source_uuid"` + TargetType types.String `tfsdk:"target_type"` + TargetUUID types.String `tfsdk:"target_uuid"` + Effect types.String `tfsdk:"effect"` + Action types.String `tfsdk:"action"` +} + +type organizationRuleDatasource struct { + client *Client +} + +func newOrganizationRuleDatasource() datasource.DataSource { + return &organizationRuleDatasource{} +} + +func (organizationRuleDatasource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_organization_rule" +} + +func (or *organizationRuleDatasource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + or.client = req.ProviderData.(*Client) +} + +func (organizationRuleDatasource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + MarkdownDescription: heredoc.Doc(` + Use this data source to retrieve an organization rule by its ID. + + More information on organization rules can be found in the [documentation](https://buildkite.com/docs/pipelines/rules). + `), + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Optional: true, + MarkdownDescription: "The GraphQL ID of the organization rule. ", + }, + "uuid": schema.StringAttribute{ + Optional: true, + MarkdownDescription: "The UUID of the organization rule. ", + }, + "description": schema.StringAttribute{ + Computed: true, + MarkdownDescription: "The description of the organization rule. ", + }, + "type": schema.StringAttribute{ + Computed: true, + MarkdownDescription: "The type of organization rule. ", + }, + "value": schema.StringAttribute{ + Computed: true, + MarkdownDescription: "The JSON document that this organization rule implements. ", + }, + "source_type": schema.StringAttribute{ + Computed: true, + MarkdownDescription: "The source resource type that this organization rule allows or denies to invoke its defined action. ", + }, + "source_uuid": schema.StringAttribute{ + Computed: true, + MarkdownDescription: "The UUID of the resource that this organization rule allows or denies invocating its defined action. ", + }, + "target_type": schema.StringAttribute{ + Computed: true, + MarkdownDescription: "The target resource type that this organization rule allows or denies the source to respective action. ", + }, + "target_uuid": schema.StringAttribute{ + Computed: true, + MarkdownDescription: "The UUID of the target resourcee that this organization rule allows or denies invocation its respective action. ", + }, + "effect": schema.StringAttribute{ + Computed: true, + MarkdownDescription: "Whether this organization rule allows or denys the action to take place between source and target resources. ", + }, + "action": schema.StringAttribute{ + Computed: true, + MarkdownDescription: "The action defined between source and target resources. ", + }, + }, + } +} + +func (or *organizationRuleDatasource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var state organizationRuleDatasourceModel + + resp.Diagnostics.Append(req.Config.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + timeouts, diags := or.client.timeouts.Read(ctx, DefaultTimeout) + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // If a UUID is entered through an organization rule data source + if !state.UUID.IsNull() { + matchFound := false + err := retry.RetryContext(ctx, timeouts, func() *retry.RetryError { + var cursor *string + for { + r, err := getOrganizationRules( + ctx, + or.client.genqlient, + or.client.organization, + cursor) + if err != nil { + if isRetryableError(err) { + return retry.RetryableError(err) + } + resp.Diagnostics.AddError( + "Unable to read organizatiion rules", + fmt.Sprintf("Unable to read organizatiion rules: %s", err.Error()), + ) + return retry.NonRetryableError(err) + } + + for _, rule := range r.Organization.Rules.Edges { + if rule.Node.Uuid == state.UUID.ValueString() { + matchFound = true + // Update data source state from the found rule + value, err := obtainValueJSON(rule.Node.Document) + if err != nil { + resp.Diagnostics.AddError( + "Unable to read organization rule", + fmt.Sprintf("Unable to read organmization rule: %s", err.Error()), + ) + } + updateOrganizatonRuleDatasourceFromNode(&state, rule.Node, *value) + break + } + } + + // If there is a match, or there is no next page, break + if matchFound || !r.Organization.Rules.PageInfo.HasNextPage { + break + } + + // Move to the next cursor + cursor = &r.Organization.Rules.PageInfo.EndCursor + } + return nil + }) + + if err != nil { + resp.Diagnostics.AddError("Unable to find organization rule", err.Error()) + return + } + + if !matchFound { + resp.Diagnostics.AddError("Unable to find organization rule", + fmt.Sprintf("Could not find an organization rule with UUID \"%s\"", state.UUID.ValueString())) + return + } + // Otherwise if a ID is specified + } else if !state.ID.IsNull() { + var apiResponse *getNodeResponse + err := retry.RetryContext(ctx, timeouts, func() *retry.RetryError { + var err error + + log.Printf("Reading organization rule with ID %s ...", state.ID.ValueString()) + apiResponse, err = getNode(ctx, + or.client.genqlient, + state.ID.ValueString(), + ) + + return retryContextError(err) + }) + + if err != nil { + resp.Diagnostics.AddError( + "Unable to read organization rule", + fmt.Sprintf("Unable to read organmization rule: %s", err.Error()), + ) + return + } + + // Convert fron Node to getNodeNodeRule type + if organizationRule, ok := apiResponse.GetNode().(*getNodeNodeRule); ok { + if organizationRule == nil { + resp.Diagnostics.AddError( + "Unable to get organization rule", + "Error getting organization rule: nil response", + ) + return + } + // Update data source state from the found rule + value, err := obtainValueJSON(organizationRule.Document) + if err != nil { + resp.Diagnostics.AddError( + "Unable to read organization rule", + fmt.Sprintf("Unable to read organmization rule: %s", err.Error()), + ) + } + updateOrganizatonRuleDatasourceState(&state, *organizationRule, *value) + } + } + resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) +} + +func obtainDatasourceReadUUIDs(orn getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule) (string, string) { + var sourceUUID, targetUUID string + + switch orn.SourceType { + case "PIPELINE": + sourceUUID = orn.Source.(*OrganizationRuleFieldsSourcePipeline).Uuid + } + + switch orn.TargetType { + case "PIPELINE": + targetUUID = orn.Target.(*OrganizationRuleFieldsTargetPipeline).Uuid + } + + return sourceUUID, targetUUID +} + +func updateOrganizatonRuleDatasourceState(or *organizationRuleDatasourceModel, orn getNodeNodeRule, value string) { + sourceUUID, targetUUID := obtainReadUUIDs(orn) + + or.ID = types.StringValue(orn.Id) + or.UUID = types.StringValue(orn.Uuid) + or.Description = types.StringPointerValue(orn.Description) + or.Type = types.StringValue(orn.Type) + or.Value = types.StringValue(value) + or.SourceType = types.StringValue(string(orn.SourceType)) + or.SourceUUID = types.StringValue(sourceUUID) + or.TargetType = types.StringValue(string(orn.TargetType)) + or.TargetUUID = types.StringValue(targetUUID) + or.Effect = types.StringValue(string(orn.Effect)) + or.Action = types.StringValue(string(orn.Action)) +} + +func updateOrganizatonRuleDatasourceFromNode(or *organizationRuleDatasourceModel, orn getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule, value string) { + sourceUUID, targetUUID := obtainDatasourceReadUUIDs(orn) + + or.ID = types.StringValue(orn.Id) + or.UUID = types.StringValue(orn.Uuid) + or.Description = types.StringPointerValue(orn.Description) + or.Type = types.StringValue(orn.Type) + or.Value = types.StringValue(value) + or.SourceType = types.StringValue(string(orn.SourceType)) + or.SourceUUID = types.StringValue(sourceUUID) + or.TargetType = types.StringValue(string(orn.TargetType)) + or.TargetUUID = types.StringValue(targetUUID) + or.Effect = types.StringValue(string(orn.Effect)) + or.Action = types.StringValue(string(orn.Action)) +} diff --git a/buildkite/data_source_organization_rule_test.go b/buildkite/data_source_organization_rule_test.go new file mode 100644 index 00000000..f1d3e76c --- /dev/null +++ b/buildkite/data_source_organization_rule_test.go @@ -0,0 +1,344 @@ +package buildkite + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func TestAccBuildkiteOrganizationRuleDatasource(t *testing.T) { + ruleActions := []string{"trigger_build", "artifacts_read"} + + configRequiredByID := func(fields ...string) string { + return fmt.Sprintf(` + provider "buildkite" { + timeouts = { + create = "10s" + read = "10s" + update = "10s" + delete = "10s" + } + } + + resource "buildkite_cluster" "cluster_one" { + name = "Cluster %s" + description = "A test cluster containing a source pipeline." + } + + resource "buildkite_cluster" "cluster_two" { + name = "Cluster %s" + description = "A test cluster containing a target pipeline for triggering builds." + } + + resource "buildkite_pipeline" "pipeline_source" { + name = "Pipeline %s" + repository = "https://github.com/buildkite/terraform-provider-buildkite.git" + cluster_id = buildkite_cluster.cluster_one.id + } + + resource "buildkite_pipeline" "pipeline_target" { + name = "Pipeline %s" + repository = "https://github.com/buildkite/terraform-provider-buildkite.git" + cluster_id = buildkite_cluster.cluster_two.id + } + + resource "buildkite_organization_rule" "%s_rule" { + type = "pipeline.%s.pipeline" + value = jsonencode({ + source_pipeline = buildkite_pipeline.pipeline_source.uuid + target_pipeline = buildkite_pipeline.pipeline_target.uuid + }) + } + + data "buildkite_organization_rule" "%s_rule" { + depends_on = [buildkite_organization_rule.%s_rule] + id = buildkite_organization_rule.%s_rule.id + } + + `, fields[0], fields[1], fields[0], fields[1], fields[2], fields[2], fields[2], fields[2], fields[2]) + } + + configRequiredByUUID := func(fields ...string) string { + return fmt.Sprintf(` + provider "buildkite" { + timeouts = { + create = "10s" + read = "10s" + update = "10s" + delete = "10s" + } + } + + resource "buildkite_cluster" "cluster_one" { + name = "Cluster %s" + description = "A test cluster containing a source pipeline." + } + + resource "buildkite_cluster" "cluster_two" { + name = "Cluster %s" + description = "A test cluster containing a target pipeline for triggering builds." + } + + resource "buildkite_pipeline" "pipeline_source" { + name = "Pipeline %s" + repository = "https://github.com/buildkite/terraform-provider-buildkite.git" + cluster_id = buildkite_cluster.cluster_one.id + } + + resource "buildkite_pipeline" "pipeline_target" { + name = "Pipeline %s" + repository = "https://github.com/buildkite/terraform-provider-buildkite.git" + cluster_id = buildkite_cluster.cluster_two.id + } + + resource "buildkite_organization_rule" "%s_rule" { + type = "pipeline.%s.pipeline" + value = jsonencode({ + source_pipeline = buildkite_pipeline.pipeline_source.uuid + target_pipeline = buildkite_pipeline.pipeline_target.uuid + }) + } + + data "buildkite_organization_rule" "%s_rule" { + depends_on = [buildkite_organization_rule.%s_rule] + uuid = buildkite_organization_rule.%s_rule.uuid + } + + `, fields[0], fields[1], fields[0], fields[1], fields[2], fields[2], fields[2], fields[2], fields[2]) + } + + configAllByID := func(fields ...string) string { + return fmt.Sprintf(` + provider "buildkite" { + timeouts = { + create = "10s" + read = "10s" + update = "10s" + delete = "10s" + } + } + + resource "buildkite_cluster" "cluster_one" { + name = "Cluster %s" + description = "A test cluster containing a source pipeline." + } + + resource "buildkite_cluster" "cluster_two" { + name = "Cluster %s" + description = "A test cluster containing a target pipeline for triggering builds." + } + + resource "buildkite_pipeline" "pipeline_source" { + name = "Pipeline %s" + repository = "https://github.com/buildkite/terraform-provider-buildkite.git" + cluster_id = buildkite_cluster.cluster_one.id + } + + resource "buildkite_pipeline" "pipeline_target" { + name = "Pipeline %s" + repository = "https://github.com/buildkite/terraform-provider-buildkite.git" + cluster_id = buildkite_cluster.cluster_two.id + } + + resource "buildkite_organization_rule" "%s_rule" { + type = "pipeline.%s.pipeline" + description = "A %s organization rule" + value = jsonencode({ + source_pipeline = buildkite_pipeline.pipeline_source.uuid + target_pipeline = buildkite_pipeline.pipeline_target.uuid + conditions = [ + "source.build.creator.teams includes 'deploy'", + "source.build.branch == 'main'" + ] + }) + } + + data "buildkite_organization_rule" "%s_rule" { + depends_on = [buildkite_organization_rule.%s_rule] + id = buildkite_organization_rule.%s_rule.id + } + + `, fields[0], fields[1], fields[0], fields[1], fields[2], fields[2], fields[2], fields[2], fields[2], fields[2]) + } + + configAllByUUID := func(fields ...string) string { + return fmt.Sprintf(` + provider "buildkite" { + timeouts = { + create = "10s" + read = "10s" + update = "10s" + delete = "10s" + } + } + + resource "buildkite_cluster" "cluster_one" { + name = "Cluster %s" + description = "A test cluster containing a source pipeline." + } + + resource "buildkite_cluster" "cluster_two" { + name = "Cluster %s" + description = "A test cluster containing a target pipeline for triggering builds." + } + + resource "buildkite_pipeline" "pipeline_source" { + name = "Pipeline %s" + repository = "https://github.com/buildkite/terraform-provider-buildkite.git" + cluster_id = buildkite_cluster.cluster_one.id + } + + resource "buildkite_pipeline" "pipeline_target" { + name = "Pipeline %s" + repository = "https://github.com/buildkite/terraform-provider-buildkite.git" + cluster_id = buildkite_cluster.cluster_two.id + } + + resource "buildkite_organization_rule" "%s_rule" { + type = "pipeline.%s.pipeline" + description = "A %s organization rule" + value = jsonencode({ + source_pipeline = buildkite_pipeline.pipeline_source.uuid + target_pipeline = buildkite_pipeline.pipeline_target.uuid + conditions = [ + "source.build.creator.teams includes 'deploy'", + "source.build.branch == 'main'" + ] + }) + } + + data "buildkite_organization_rule" "%s_rule" { + depends_on = [buildkite_organization_rule.%s_rule] + uuid = buildkite_organization_rule.%s_rule.uuid + } + + `, fields[0], fields[1], fields[0], fields[1], fields[2], fields[2], fields[2], fields[2], fields[2], fields[2]) + } + + for _, action := range ruleActions { + t.Run(fmt.Sprintf("loads a pipeline.%s.pipeline organization rule with required attributes by id", action), func(t *testing.T) { + randdNameOne := acctest.RandString(12) + randNameTwo := acctest.RandString(12) + var orr organizationRuleResourceModel + + check := resource.ComposeAggregateTestCheckFunc( + // Confirm the organization rule exists + testAccCheckOrganizationRuleExists(&orr, fmt.Sprintf("buildkite_organization_rule.%s_rule", action)), + // Confirm the organization rule has the correct values in Buildkite's system + testAccCheckOrganizationRuleRemoteValues(&orr, "PIPELINE", "PIPELINE", strings.ToUpper(action), "ALLOW"), + // Check the organization rule data source's attributes are set in state + resource.TestCheckResourceAttrSet(fmt.Sprintf("data.buildkite_organization_rule.%s_rule", action), "id"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("data.buildkite_organization_rule.%s_rule", action), "uuid"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("data.buildkite_organization_rule.%s_rule", action), "type"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("data.buildkite_organization_rule.%s_rule", action), "value"), + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: protoV6ProviderFactories(), + CheckDestroy: testAccCheckOrganizationRuleDestroy, + Steps: []resource.TestStep{ + { + Config: configRequiredByID(randdNameOne, randNameTwo, action), + Check: check, + }, + }, + }) + }) + + t.Run(fmt.Sprintf("loads a pipeline.%s.pipeline organization rule with all attributes by id", action), func(t *testing.T) { + randdNameOne := acctest.RandString(12) + randNameTwo := acctest.RandString(12) + var orr organizationRuleResourceModel + + check := resource.ComposeAggregateTestCheckFunc( + // Confirm the organization rule exists + testAccCheckOrganizationRuleExists(&orr, fmt.Sprintf("buildkite_organization_rule.%s_rule", action)), + // Confirm the organization rule has the correct values in Buildkite's system + testAccCheckOrganizationRuleRemoteValues(&orr, "PIPELINE", "PIPELINE", strings.ToUpper(action), "ALLOW"), + // Check the organization rule data source's attributes are set in state + resource.TestCheckResourceAttrSet(fmt.Sprintf("data.buildkite_organization_rule.%s_rule", action), "id"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("data.buildkite_organization_rule.%s_rule", action), "uuid"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("data.buildkite_organization_rule.%s_rule", action), "type"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("data.buildkite_organization_rule.%s_rule", action), "description"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("data.buildkite_organization_rule.%s_rule", action), "value"), + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: protoV6ProviderFactories(), + CheckDestroy: testAccCheckOrganizationRuleDestroy, + Steps: []resource.TestStep{ + { + Config: configAllByID(randdNameOne, randNameTwo, action), + Check: check, + }, + }, + }) + }) + + t.Run(fmt.Sprintf("loads a pipeline.%s.pipeline organization rule with required attributes by uuid", action), func(t *testing.T) { + randdNameOne := acctest.RandString(12) + randNameTwo := acctest.RandString(12) + var orr organizationRuleResourceModel + + check := resource.ComposeAggregateTestCheckFunc( + // Confirm the organization rule exists + testAccCheckOrganizationRuleExists(&orr, fmt.Sprintf("buildkite_organization_rule.%s_rule", action)), + // Confirm the organization rule has the correct values in Buildkite's system + testAccCheckOrganizationRuleRemoteValues(&orr, "PIPELINE", "PIPELINE", strings.ToUpper(action), "ALLOW"), + // Check the organization rule data source's attributes are set in state + resource.TestCheckResourceAttrSet(fmt.Sprintf("data.buildkite_organization_rule.%s_rule", action), "id"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("data.buildkite_organization_rule.%s_rule", action), "uuid"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("data.buildkite_organization_rule.%s_rule", action), "type"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("data.buildkite_organization_rule.%s_rule", action), "value"), + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: protoV6ProviderFactories(), + CheckDestroy: testAccCheckOrganizationRuleDestroy, + Steps: []resource.TestStep{ + { + Config: configRequiredByUUID(randdNameOne, randNameTwo, action), + Check: check, + }, + }, + }) + }) + + t.Run(fmt.Sprintf("loads a pipeline.%s.pipeline organization rule with all attributes by uuid", action), func(t *testing.T) { + randdNameOne := acctest.RandString(12) + randNameTwo := acctest.RandString(12) + var orr organizationRuleResourceModel + + check := resource.ComposeAggregateTestCheckFunc( + // Confirm the organization rule exists + testAccCheckOrganizationRuleExists(&orr, fmt.Sprintf("buildkite_organization_rule.%s_rule", action)), + // Confirm the organization rule has the correct values in Buildkite's system + testAccCheckOrganizationRuleRemoteValues(&orr, "PIPELINE", "PIPELINE", strings.ToUpper(action), "ALLOW"), + // Check the organization rule data source's attributes are set in state + resource.TestCheckResourceAttrSet(fmt.Sprintf("data.buildkite_organization_rule.%s_rule", action), "id"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("data.buildkite_organization_rule.%s_rule", action), "uuid"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("data.buildkite_organization_rule.%s_rule", action), "type"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("data.buildkite_organization_rule.%s_rule", action), "description"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("data.buildkite_organization_rule.%s_rule", action), "value"), + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: protoV6ProviderFactories(), + CheckDestroy: testAccCheckOrganizationRuleDestroy, + Steps: []resource.TestStep{ + { + Config: configAllByUUID(randdNameOne, randNameTwo, action), + Check: check, + }, + }, + }) + }) + } +} diff --git a/buildkite/generated.go b/buildkite/generated.go index bece0cf1..5db589c8 100644 --- a/buildkite/generated.go +++ b/buildkite/generated.go @@ -287,6 +287,338 @@ func (v *OrganizationBannerFields) GetUuid() string { return v.Uuid } // GetMessage returns OrganizationBannerFields.Message, and is useful for accessing the field via an interface. func (v *OrganizationBannerFields) GetMessage() string { return v.Message } +// OrganizationRuleFields includes the GraphQL fields of Rule requested by the fragment OrganizationRuleFields. +type OrganizationRuleFields struct { + Id string `json:"id"` + // The public UUID for the rule + Uuid string `json:"uuid"` + // Description of the rule + Description *string `json:"description"` + // A formatted JSON document of the Rule + Document string `json:"document"` + // The type of rule + Type string `json:"type"` + // Source type for the rule + SourceType RuleSourceType `json:"sourceType"` + // Target type for the rule + TargetType RuleTargetType `json:"targetType"` + // Effect for the rule + Effect RuleEffect `json:"effect"` + // Action for the rule + Action RuleAction `json:"action"` + // The source for the rule + Source OrganizationRuleFieldsSourceRuleSource `json:"-"` + // The target for the rule + Target OrganizationRuleFieldsTargetRuleTarget `json:"-"` +} + +// GetId returns OrganizationRuleFields.Id, and is useful for accessing the field via an interface. +func (v *OrganizationRuleFields) GetId() string { return v.Id } + +// GetUuid returns OrganizationRuleFields.Uuid, and is useful for accessing the field via an interface. +func (v *OrganizationRuleFields) GetUuid() string { return v.Uuid } + +// GetDescription returns OrganizationRuleFields.Description, and is useful for accessing the field via an interface. +func (v *OrganizationRuleFields) GetDescription() *string { return v.Description } + +// GetDocument returns OrganizationRuleFields.Document, and is useful for accessing the field via an interface. +func (v *OrganizationRuleFields) GetDocument() string { return v.Document } + +// GetType returns OrganizationRuleFields.Type, and is useful for accessing the field via an interface. +func (v *OrganizationRuleFields) GetType() string { return v.Type } + +// GetSourceType returns OrganizationRuleFields.SourceType, and is useful for accessing the field via an interface. +func (v *OrganizationRuleFields) GetSourceType() RuleSourceType { return v.SourceType } + +// GetTargetType returns OrganizationRuleFields.TargetType, and is useful for accessing the field via an interface. +func (v *OrganizationRuleFields) GetTargetType() RuleTargetType { return v.TargetType } + +// GetEffect returns OrganizationRuleFields.Effect, and is useful for accessing the field via an interface. +func (v *OrganizationRuleFields) GetEffect() RuleEffect { return v.Effect } + +// GetAction returns OrganizationRuleFields.Action, and is useful for accessing the field via an interface. +func (v *OrganizationRuleFields) GetAction() RuleAction { return v.Action } + +// GetSource returns OrganizationRuleFields.Source, and is useful for accessing the field via an interface. +func (v *OrganizationRuleFields) GetSource() OrganizationRuleFieldsSourceRuleSource { return v.Source } + +// GetTarget returns OrganizationRuleFields.Target, and is useful for accessing the field via an interface. +func (v *OrganizationRuleFields) GetTarget() OrganizationRuleFieldsTargetRuleTarget { return v.Target } + +func (v *OrganizationRuleFields) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *OrganizationRuleFields + Source json.RawMessage `json:"source"` + Target json.RawMessage `json:"target"` + graphql.NoUnmarshalJSON + } + firstPass.OrganizationRuleFields = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.Source + src := firstPass.Source + if len(src) != 0 && string(src) != "null" { + err = __unmarshalOrganizationRuleFieldsSourceRuleSource( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal OrganizationRuleFields.Source: %w", err) + } + } + } + + { + dst := &v.Target + src := firstPass.Target + if len(src) != 0 && string(src) != "null" { + err = __unmarshalOrganizationRuleFieldsTargetRuleTarget( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal OrganizationRuleFields.Target: %w", err) + } + } + } + return nil +} + +type __premarshalOrganizationRuleFields struct { + Id string `json:"id"` + + Uuid string `json:"uuid"` + + Description *string `json:"description"` + + Document string `json:"document"` + + Type string `json:"type"` + + SourceType RuleSourceType `json:"sourceType"` + + TargetType RuleTargetType `json:"targetType"` + + Effect RuleEffect `json:"effect"` + + Action RuleAction `json:"action"` + + Source json.RawMessage `json:"source"` + + Target json.RawMessage `json:"target"` +} + +func (v *OrganizationRuleFields) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *OrganizationRuleFields) __premarshalJSON() (*__premarshalOrganizationRuleFields, error) { + var retval __premarshalOrganizationRuleFields + + retval.Id = v.Id + retval.Uuid = v.Uuid + retval.Description = v.Description + retval.Document = v.Document + retval.Type = v.Type + retval.SourceType = v.SourceType + retval.TargetType = v.TargetType + retval.Effect = v.Effect + retval.Action = v.Action + { + + dst := &retval.Source + src := v.Source + var err error + *dst, err = __marshalOrganizationRuleFieldsSourceRuleSource( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal OrganizationRuleFields.Source: %w", err) + } + } + { + + dst := &retval.Target + src := v.Target + var err error + *dst, err = __marshalOrganizationRuleFieldsTargetRuleTarget( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal OrganizationRuleFields.Target: %w", err) + } + } + return &retval, nil +} + +// OrganizationRuleFieldsSourcePipeline includes the requested fields of the GraphQL type Pipeline. +// The GraphQL type's documentation follows. +// +// A pipeline +type OrganizationRuleFieldsSourcePipeline struct { + Typename string `json:"__typename"` + // The UUID of the pipeline + Uuid string `json:"uuid"` +} + +// GetTypename returns OrganizationRuleFieldsSourcePipeline.Typename, and is useful for accessing the field via an interface. +func (v *OrganizationRuleFieldsSourcePipeline) GetTypename() string { return v.Typename } + +// GetUuid returns OrganizationRuleFieldsSourcePipeline.Uuid, and is useful for accessing the field via an interface. +func (v *OrganizationRuleFieldsSourcePipeline) GetUuid() string { return v.Uuid } + +// OrganizationRuleFieldsSourceRuleSource includes the requested fields of the GraphQL interface RuleSource. +// +// OrganizationRuleFieldsSourceRuleSource is implemented by the following types: +// OrganizationRuleFieldsSourcePipeline +// The GraphQL type's documentation follows. +// +// Kinds of sources for a rule +type OrganizationRuleFieldsSourceRuleSource interface { + implementsGraphQLInterfaceOrganizationRuleFieldsSourceRuleSource() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string +} + +func (v *OrganizationRuleFieldsSourcePipeline) implementsGraphQLInterfaceOrganizationRuleFieldsSourceRuleSource() { +} + +func __unmarshalOrganizationRuleFieldsSourceRuleSource(b []byte, v *OrganizationRuleFieldsSourceRuleSource) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "Pipeline": + *v = new(OrganizationRuleFieldsSourcePipeline) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing RuleSource.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for OrganizationRuleFieldsSourceRuleSource: "%v"`, tn.TypeName) + } +} + +func __marshalOrganizationRuleFieldsSourceRuleSource(v *OrganizationRuleFieldsSourceRuleSource) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *OrganizationRuleFieldsSourcePipeline: + typename = "Pipeline" + + result := struct { + TypeName string `json:"__typename"` + *OrganizationRuleFieldsSourcePipeline + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for OrganizationRuleFieldsSourceRuleSource: "%T"`, v) + } +} + +// OrganizationRuleFieldsTargetPipeline includes the requested fields of the GraphQL type Pipeline. +// The GraphQL type's documentation follows. +// +// A pipeline +type OrganizationRuleFieldsTargetPipeline struct { + Typename string `json:"__typename"` + // The UUID of the pipeline + Uuid string `json:"uuid"` +} + +// GetTypename returns OrganizationRuleFieldsTargetPipeline.Typename, and is useful for accessing the field via an interface. +func (v *OrganizationRuleFieldsTargetPipeline) GetTypename() string { return v.Typename } + +// GetUuid returns OrganizationRuleFieldsTargetPipeline.Uuid, and is useful for accessing the field via an interface. +func (v *OrganizationRuleFieldsTargetPipeline) GetUuid() string { return v.Uuid } + +// OrganizationRuleFieldsTargetRuleTarget includes the requested fields of the GraphQL interface RuleTarget. +// +// OrganizationRuleFieldsTargetRuleTarget is implemented by the following types: +// OrganizationRuleFieldsTargetPipeline +// The GraphQL type's documentation follows. +// +// Kinds of targets for a rule +type OrganizationRuleFieldsTargetRuleTarget interface { + implementsGraphQLInterfaceOrganizationRuleFieldsTargetRuleTarget() + // GetTypename returns the receiver's concrete GraphQL type-name (see interface doc for possible values). + GetTypename() string +} + +func (v *OrganizationRuleFieldsTargetPipeline) implementsGraphQLInterfaceOrganizationRuleFieldsTargetRuleTarget() { +} + +func __unmarshalOrganizationRuleFieldsTargetRuleTarget(b []byte, v *OrganizationRuleFieldsTargetRuleTarget) error { + if string(b) == "null" { + return nil + } + + var tn struct { + TypeName string `json:"__typename"` + } + err := json.Unmarshal(b, &tn) + if err != nil { + return err + } + + switch tn.TypeName { + case "Pipeline": + *v = new(OrganizationRuleFieldsTargetPipeline) + return json.Unmarshal(b, *v) + case "": + return fmt.Errorf( + "response was missing RuleTarget.__typename") + default: + return fmt.Errorf( + `unexpected concrete type for OrganizationRuleFieldsTargetRuleTarget: "%v"`, tn.TypeName) + } +} + +func __marshalOrganizationRuleFieldsTargetRuleTarget(v *OrganizationRuleFieldsTargetRuleTarget) ([]byte, error) { + + var typename string + switch v := (*v).(type) { + case *OrganizationRuleFieldsTargetPipeline: + typename = "Pipeline" + + result := struct { + TypeName string `json:"__typename"` + *OrganizationRuleFieldsTargetPipeline + }{typename, v} + return json.Marshal(result) + case nil: + return []byte("null"), nil + default: + return nil, fmt.Errorf( + `unexpected concrete type for OrganizationRuleFieldsTargetRuleTarget: "%T"`, v) + } +} + // The access levels that can be assigned to a pipeline type PipelineAccessLevels string @@ -1078,6 +1410,40 @@ const ( PipelineVisibilityPrivate PipelineVisibility = "PRIVATE" ) +// The action a rule enforces +type RuleAction string + +const ( + // Artifacts read + RuleActionArtifactsRead RuleAction = "ARTIFACTS_READ" + // Trigger build + RuleActionTriggerBuild RuleAction = "TRIGGER_BUILD" +) + +// The effect a rule has +type RuleEffect string + +const ( + // Allow + RuleEffectAllow RuleEffect = "ALLOW" +) + +// The source type for a rule +type RuleSourceType string + +const ( + // Pipeline + RuleSourceTypePipeline RuleSourceType = "PIPELINE" +) + +// The target type for a rule +type RuleTargetType string + +const ( + // Pipeline + RuleTargetTypePipeline RuleTargetType = "PIPELINE" +) + // The access levels that can be assigned to a suite type SuiteAccessLevels string @@ -1392,6 +1758,26 @@ func (v *__createClusterQueueInput) GetKey() string { return v.Key } // GetDescription returns __createClusterQueueInput.Description, and is useful for accessing the field via an interface. func (v *__createClusterQueueInput) GetDescription() *string { return v.Description } +// __createOrganizationRuleInput is used internally by genqlient +type __createOrganizationRuleInput struct { + OrganizationId string `json:"organizationId"` + Description *string `json:"description"` + RuleType string `json:"ruleType"` + Value string `json:"value"` +} + +// GetOrganizationId returns __createOrganizationRuleInput.OrganizationId, and is useful for accessing the field via an interface. +func (v *__createOrganizationRuleInput) GetOrganizationId() string { return v.OrganizationId } + +// GetDescription returns __createOrganizationRuleInput.Description, and is useful for accessing the field via an interface. +func (v *__createOrganizationRuleInput) GetDescription() *string { return v.Description } + +// GetRuleType returns __createOrganizationRuleInput.RuleType, and is useful for accessing the field via an interface. +func (v *__createOrganizationRuleInput) GetRuleType() string { return v.RuleType } + +// GetValue returns __createOrganizationRuleInput.Value, and is useful for accessing the field via an interface. +func (v *__createOrganizationRuleInput) GetValue() string { return v.Value } + // __createPipelineInput is used internally by genqlient type __createPipelineInput struct { Input PipelineCreateInput `json:"input"` @@ -1540,6 +1926,18 @@ func (v *__deleteClusterQueueInput) GetOrganizationId() string { return v.Organi // GetId returns __deleteClusterQueueInput.Id, and is useful for accessing the field via an interface. func (v *__deleteClusterQueueInput) GetId() string { return v.Id } +// __deleteOrganizationRuleInput is used internally by genqlient +type __deleteOrganizationRuleInput struct { + OrganizationId string `json:"organizationId"` + Id string `json:"id"` +} + +// GetOrganizationId returns __deleteOrganizationRuleInput.OrganizationId, and is useful for accessing the field via an interface. +func (v *__deleteOrganizationRuleInput) GetOrganizationId() string { return v.OrganizationId } + +// GetId returns __deleteOrganizationRuleInput.Id, and is useful for accessing the field via an interface. +func (v *__deleteOrganizationRuleInput) GetId() string { return v.Id } + // __deletePipelineInput is used internally by genqlient type __deletePipelineInput struct { Id string `json:"id"` @@ -1652,6 +2050,18 @@ type __getOrganizationInput struct { // GetSlug returns __getOrganizationInput.Slug, and is useful for accessing the field via an interface. func (v *__getOrganizationInput) GetSlug() string { return v.Slug } +// __getOrganizationRulesInput is used internally by genqlient +type __getOrganizationRulesInput struct { + OrgSlug string `json:"orgSlug"` + Cursor *string `json:"cursor"` +} + +// GetOrgSlug returns __getOrganizationRulesInput.OrgSlug, and is useful for accessing the field via an interface. +func (v *__getOrganizationRulesInput) GetOrgSlug() string { return v.OrgSlug } + +// GetCursor returns __getOrganizationRulesInput.Cursor, and is useful for accessing the field via an interface. +func (v *__getOrganizationRulesInput) GetCursor() *string { return v.Cursor } + // __getOrganiztionBannerInput is used internally by genqlient type __getOrganiztionBannerInput struct { OrgSlug string `json:"orgSlug"` @@ -2480,26 +2890,206 @@ func (v *createClusterResponse) GetClusterCreate() createClusterClusterCreateClu return v.ClusterCreate } -// createPipelinePipelineCreatePipelineCreatePayload includes the requested fields of the GraphQL type PipelineCreatePayload. -// The GraphQL type's documentation follows. -// -// Autogenerated return type of PipelineCreate. -type createPipelinePipelineCreatePipelineCreatePayload struct { - Pipeline createPipelinePipelineCreatePipelineCreatePayloadPipeline `json:"pipeline"` +// createOrganizationRuleResponse is returned by createOrganizationRule on success. +type createOrganizationRuleResponse struct { + // Create a rule. + RuleCreate createOrganizationRuleRuleCreateRuleCreatePayload `json:"ruleCreate"` } -// GetPipeline returns createPipelinePipelineCreatePipelineCreatePayload.Pipeline, and is useful for accessing the field via an interface. -func (v *createPipelinePipelineCreatePipelineCreatePayload) GetPipeline() createPipelinePipelineCreatePipelineCreatePayloadPipeline { - return v.Pipeline +// GetRuleCreate returns createOrganizationRuleResponse.RuleCreate, and is useful for accessing the field via an interface. +func (v *createOrganizationRuleResponse) GetRuleCreate() createOrganizationRuleRuleCreateRuleCreatePayload { + return v.RuleCreate } -// createPipelinePipelineCreatePipelineCreatePayloadPipeline includes the requested fields of the GraphQL type Pipeline. +// createOrganizationRuleRuleCreateRuleCreatePayload includes the requested fields of the GraphQL type RuleCreatePayload. // The GraphQL type's documentation follows. // -// A pipeline -type createPipelinePipelineCreatePipelineCreatePayloadPipeline struct { - PipelineFields `json:"-"` - // The URL to use in your repository settings for commit webhooks +// Autogenerated return type of RuleCreate. +type createOrganizationRuleRuleCreateRuleCreatePayload struct { + Rule createOrganizationRuleRuleCreateRuleCreatePayloadRule `json:"rule"` +} + +// GetRule returns createOrganizationRuleRuleCreateRuleCreatePayload.Rule, and is useful for accessing the field via an interface. +func (v *createOrganizationRuleRuleCreateRuleCreatePayload) GetRule() createOrganizationRuleRuleCreateRuleCreatePayloadRule { + return v.Rule +} + +// createOrganizationRuleRuleCreateRuleCreatePayloadRule includes the requested fields of the GraphQL type Rule. +type createOrganizationRuleRuleCreateRuleCreatePayloadRule struct { + OrganizationRuleFields `json:"-"` +} + +// GetId returns createOrganizationRuleRuleCreateRuleCreatePayloadRule.Id, and is useful for accessing the field via an interface. +func (v *createOrganizationRuleRuleCreateRuleCreatePayloadRule) GetId() string { + return v.OrganizationRuleFields.Id +} + +// GetUuid returns createOrganizationRuleRuleCreateRuleCreatePayloadRule.Uuid, and is useful for accessing the field via an interface. +func (v *createOrganizationRuleRuleCreateRuleCreatePayloadRule) GetUuid() string { + return v.OrganizationRuleFields.Uuid +} + +// GetDescription returns createOrganizationRuleRuleCreateRuleCreatePayloadRule.Description, and is useful for accessing the field via an interface. +func (v *createOrganizationRuleRuleCreateRuleCreatePayloadRule) GetDescription() *string { + return v.OrganizationRuleFields.Description +} + +// GetDocument returns createOrganizationRuleRuleCreateRuleCreatePayloadRule.Document, and is useful for accessing the field via an interface. +func (v *createOrganizationRuleRuleCreateRuleCreatePayloadRule) GetDocument() string { + return v.OrganizationRuleFields.Document +} + +// GetType returns createOrganizationRuleRuleCreateRuleCreatePayloadRule.Type, and is useful for accessing the field via an interface. +func (v *createOrganizationRuleRuleCreateRuleCreatePayloadRule) GetType() string { + return v.OrganizationRuleFields.Type +} + +// GetSourceType returns createOrganizationRuleRuleCreateRuleCreatePayloadRule.SourceType, and is useful for accessing the field via an interface. +func (v *createOrganizationRuleRuleCreateRuleCreatePayloadRule) GetSourceType() RuleSourceType { + return v.OrganizationRuleFields.SourceType +} + +// GetTargetType returns createOrganizationRuleRuleCreateRuleCreatePayloadRule.TargetType, and is useful for accessing the field via an interface. +func (v *createOrganizationRuleRuleCreateRuleCreatePayloadRule) GetTargetType() RuleTargetType { + return v.OrganizationRuleFields.TargetType +} + +// GetEffect returns createOrganizationRuleRuleCreateRuleCreatePayloadRule.Effect, and is useful for accessing the field via an interface. +func (v *createOrganizationRuleRuleCreateRuleCreatePayloadRule) GetEffect() RuleEffect { + return v.OrganizationRuleFields.Effect +} + +// GetAction returns createOrganizationRuleRuleCreateRuleCreatePayloadRule.Action, and is useful for accessing the field via an interface. +func (v *createOrganizationRuleRuleCreateRuleCreatePayloadRule) GetAction() RuleAction { + return v.OrganizationRuleFields.Action +} + +// GetSource returns createOrganizationRuleRuleCreateRuleCreatePayloadRule.Source, and is useful for accessing the field via an interface. +func (v *createOrganizationRuleRuleCreateRuleCreatePayloadRule) GetSource() OrganizationRuleFieldsSourceRuleSource { + return v.OrganizationRuleFields.Source +} + +// GetTarget returns createOrganizationRuleRuleCreateRuleCreatePayloadRule.Target, and is useful for accessing the field via an interface. +func (v *createOrganizationRuleRuleCreateRuleCreatePayloadRule) GetTarget() OrganizationRuleFieldsTargetRuleTarget { + return v.OrganizationRuleFields.Target +} + +func (v *createOrganizationRuleRuleCreateRuleCreatePayloadRule) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *createOrganizationRuleRuleCreateRuleCreatePayloadRule + graphql.NoUnmarshalJSON + } + firstPass.createOrganizationRuleRuleCreateRuleCreatePayloadRule = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.OrganizationRuleFields) + if err != nil { + return err + } + return nil +} + +type __premarshalcreateOrganizationRuleRuleCreateRuleCreatePayloadRule struct { + Id string `json:"id"` + + Uuid string `json:"uuid"` + + Description *string `json:"description"` + + Document string `json:"document"` + + Type string `json:"type"` + + SourceType RuleSourceType `json:"sourceType"` + + TargetType RuleTargetType `json:"targetType"` + + Effect RuleEffect `json:"effect"` + + Action RuleAction `json:"action"` + + Source json.RawMessage `json:"source"` + + Target json.RawMessage `json:"target"` +} + +func (v *createOrganizationRuleRuleCreateRuleCreatePayloadRule) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *createOrganizationRuleRuleCreateRuleCreatePayloadRule) __premarshalJSON() (*__premarshalcreateOrganizationRuleRuleCreateRuleCreatePayloadRule, error) { + var retval __premarshalcreateOrganizationRuleRuleCreateRuleCreatePayloadRule + + retval.Id = v.OrganizationRuleFields.Id + retval.Uuid = v.OrganizationRuleFields.Uuid + retval.Description = v.OrganizationRuleFields.Description + retval.Document = v.OrganizationRuleFields.Document + retval.Type = v.OrganizationRuleFields.Type + retval.SourceType = v.OrganizationRuleFields.SourceType + retval.TargetType = v.OrganizationRuleFields.TargetType + retval.Effect = v.OrganizationRuleFields.Effect + retval.Action = v.OrganizationRuleFields.Action + { + + dst := &retval.Source + src := v.OrganizationRuleFields.Source + var err error + *dst, err = __marshalOrganizationRuleFieldsSourceRuleSource( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal createOrganizationRuleRuleCreateRuleCreatePayloadRule.OrganizationRuleFields.Source: %w", err) + } + } + { + + dst := &retval.Target + src := v.OrganizationRuleFields.Target + var err error + *dst, err = __marshalOrganizationRuleFieldsTargetRuleTarget( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal createOrganizationRuleRuleCreateRuleCreatePayloadRule.OrganizationRuleFields.Target: %w", err) + } + } + return &retval, nil +} + +// createPipelinePipelineCreatePipelineCreatePayload includes the requested fields of the GraphQL type PipelineCreatePayload. +// The GraphQL type's documentation follows. +// +// Autogenerated return type of PipelineCreate. +type createPipelinePipelineCreatePipelineCreatePayload struct { + Pipeline createPipelinePipelineCreatePipelineCreatePayloadPipeline `json:"pipeline"` +} + +// GetPipeline returns createPipelinePipelineCreatePipelineCreatePayload.Pipeline, and is useful for accessing the field via an interface. +func (v *createPipelinePipelineCreatePipelineCreatePayload) GetPipeline() createPipelinePipelineCreatePipelineCreatePayloadPipeline { + return v.Pipeline +} + +// createPipelinePipelineCreatePipelineCreatePayloadPipeline includes the requested fields of the GraphQL type Pipeline. +// The GraphQL type's documentation follows. +// +// A pipeline +type createPipelinePipelineCreatePipelineCreatePayloadPipeline struct { + PipelineFields `json:"-"` + // The URL to use in your repository settings for commit webhooks WebhookURL string `json:"webhookURL"` } @@ -3559,6 +4149,31 @@ func (v *deleteClusterResponse) GetClusterDelete() deleteClusterClusterDeleteClu return v.ClusterDelete } +// deleteOrganizationRuleResponse is returned by deleteOrganizationRule on success. +type deleteOrganizationRuleResponse struct { + // Delete a rule. + RuleDelete deleteOrganizationRuleRuleDeleteRuleDeletePayload `json:"ruleDelete"` +} + +// GetRuleDelete returns deleteOrganizationRuleResponse.RuleDelete, and is useful for accessing the field via an interface. +func (v *deleteOrganizationRuleResponse) GetRuleDelete() deleteOrganizationRuleRuleDeleteRuleDeletePayload { + return v.RuleDelete +} + +// deleteOrganizationRuleRuleDeleteRuleDeletePayload includes the requested fields of the GraphQL type RuleDeletePayload. +// The GraphQL type's documentation follows. +// +// Autogenerated return type of RuleDelete. +type deleteOrganizationRuleRuleDeleteRuleDeletePayload struct { + // A unique identifier for the client performing the mutation. + ClientMutationId string `json:"clientMutationId"` +} + +// GetClientMutationId returns deleteOrganizationRuleRuleDeleteRuleDeletePayload.ClientMutationId, and is useful for accessing the field via an interface. +func (v *deleteOrganizationRuleRuleDeleteRuleDeletePayload) GetClientMutationId() string { + return v.ClientMutationId +} + // deletePipelinePipelineDeletePipelineDeletePayload includes the requested fields of the GraphQL type PipelineDeletePayload. // The GraphQL type's documentation follows. // @@ -4266,6 +4881,8 @@ func (v *getClusterQueuesResponse) GetOrganization() getClusterQueuesOrganizatio // getNodeNodePipelineSchedule // getNodeNodePipelineTemplate // getNodeNodeRegistry +// getNodeNodeRegistryToken +// getNodeNodeRule // getNodeNodeSSOProviderGitHubApp // getNodeNodeSSOProviderGoogleGSuite // getNodeNodeSSOProviderSAML @@ -4330,6 +4947,8 @@ func (v *getNodeNodePipelineMetric) implementsGraphQLInterfacegetNodeNode() func (v *getNodeNodePipelineSchedule) implementsGraphQLInterfacegetNodeNode() {} func (v *getNodeNodePipelineTemplate) implementsGraphQLInterfacegetNodeNode() {} func (v *getNodeNodeRegistry) implementsGraphQLInterfacegetNodeNode() {} +func (v *getNodeNodeRegistryToken) implementsGraphQLInterfacegetNodeNode() {} +func (v *getNodeNodeRule) implementsGraphQLInterfacegetNodeNode() {} func (v *getNodeNodeSSOProviderGitHubApp) implementsGraphQLInterfacegetNodeNode() {} func (v *getNodeNodeSSOProviderGoogleGSuite) implementsGraphQLInterfacegetNodeNode() {} func (v *getNodeNodeSSOProviderSAML) implementsGraphQLInterfacegetNodeNode() {} @@ -4486,6 +5105,12 @@ func __unmarshalgetNodeNode(b []byte, v *getNodeNode) error { case "Registry": *v = new(getNodeNodeRegistry) return json.Unmarshal(b, *v) + case "RegistryToken": + *v = new(getNodeNodeRegistryToken) + return json.Unmarshal(b, *v) + case "Rule": + *v = new(getNodeNodeRule) + return json.Unmarshal(b, *v) case "SSOProviderGitHubApp": *v = new(getNodeNodeSSOProviderGitHubApp) return json.Unmarshal(b, *v) @@ -4891,6 +5516,26 @@ func __marshalgetNodeNode(v *getNodeNode) ([]byte, error) { *getNodeNodeRegistry }{typename, v} return json.Marshal(result) + case *getNodeNodeRegistryToken: + typename = "RegistryToken" + + result := struct { + TypeName string `json:"__typename"` + *getNodeNodeRegistryToken + }{typename, v} + return json.Marshal(result) + case *getNodeNodeRule: + typename = "Rule" + + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + result := struct { + TypeName string `json:"__typename"` + *__premarshalgetNodeNodeRule + }{typename, premarshaled} + return json.Marshal(result) case *getNodeNodeSSOProviderGitHubApp: typename = "SSOProviderGitHubApp" @@ -5851,6 +6496,162 @@ type getNodeNodeRegistry struct { // GetTypename returns getNodeNodeRegistry.Typename, and is useful for accessing the field via an interface. func (v *getNodeNodeRegistry) GetTypename() string { return v.Typename } +// getNodeNodeRegistryToken includes the requested fields of the GraphQL type RegistryToken. +// The GraphQL type's documentation follows. +// +// A registry token +type getNodeNodeRegistryToken struct { + Typename string `json:"__typename"` +} + +// GetTypename returns getNodeNodeRegistryToken.Typename, and is useful for accessing the field via an interface. +func (v *getNodeNodeRegistryToken) GetTypename() string { return v.Typename } + +// getNodeNodeRule includes the requested fields of the GraphQL type Rule. +type getNodeNodeRule struct { + Typename string `json:"__typename"` + OrganizationRuleFields `json:"-"` +} + +// GetTypename returns getNodeNodeRule.Typename, and is useful for accessing the field via an interface. +func (v *getNodeNodeRule) GetTypename() string { return v.Typename } + +// GetId returns getNodeNodeRule.Id, and is useful for accessing the field via an interface. +func (v *getNodeNodeRule) GetId() string { return v.OrganizationRuleFields.Id } + +// GetUuid returns getNodeNodeRule.Uuid, and is useful for accessing the field via an interface. +func (v *getNodeNodeRule) GetUuid() string { return v.OrganizationRuleFields.Uuid } + +// GetDescription returns getNodeNodeRule.Description, and is useful for accessing the field via an interface. +func (v *getNodeNodeRule) GetDescription() *string { return v.OrganizationRuleFields.Description } + +// GetDocument returns getNodeNodeRule.Document, and is useful for accessing the field via an interface. +func (v *getNodeNodeRule) GetDocument() string { return v.OrganizationRuleFields.Document } + +// GetType returns getNodeNodeRule.Type, and is useful for accessing the field via an interface. +func (v *getNodeNodeRule) GetType() string { return v.OrganizationRuleFields.Type } + +// GetSourceType returns getNodeNodeRule.SourceType, and is useful for accessing the field via an interface. +func (v *getNodeNodeRule) GetSourceType() RuleSourceType { return v.OrganizationRuleFields.SourceType } + +// GetTargetType returns getNodeNodeRule.TargetType, and is useful for accessing the field via an interface. +func (v *getNodeNodeRule) GetTargetType() RuleTargetType { return v.OrganizationRuleFields.TargetType } + +// GetEffect returns getNodeNodeRule.Effect, and is useful for accessing the field via an interface. +func (v *getNodeNodeRule) GetEffect() RuleEffect { return v.OrganizationRuleFields.Effect } + +// GetAction returns getNodeNodeRule.Action, and is useful for accessing the field via an interface. +func (v *getNodeNodeRule) GetAction() RuleAction { return v.OrganizationRuleFields.Action } + +// GetSource returns getNodeNodeRule.Source, and is useful for accessing the field via an interface. +func (v *getNodeNodeRule) GetSource() OrganizationRuleFieldsSourceRuleSource { + return v.OrganizationRuleFields.Source +} + +// GetTarget returns getNodeNodeRule.Target, and is useful for accessing the field via an interface. +func (v *getNodeNodeRule) GetTarget() OrganizationRuleFieldsTargetRuleTarget { + return v.OrganizationRuleFields.Target +} + +func (v *getNodeNodeRule) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *getNodeNodeRule + graphql.NoUnmarshalJSON + } + firstPass.getNodeNodeRule = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + err = json.Unmarshal( + b, &v.OrganizationRuleFields) + if err != nil { + return err + } + return nil +} + +type __premarshalgetNodeNodeRule struct { + Typename string `json:"__typename"` + + Id string `json:"id"` + + Uuid string `json:"uuid"` + + Description *string `json:"description"` + + Document string `json:"document"` + + Type string `json:"type"` + + SourceType RuleSourceType `json:"sourceType"` + + TargetType RuleTargetType `json:"targetType"` + + Effect RuleEffect `json:"effect"` + + Action RuleAction `json:"action"` + + Source json.RawMessage `json:"source"` + + Target json.RawMessage `json:"target"` +} + +func (v *getNodeNodeRule) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *getNodeNodeRule) __premarshalJSON() (*__premarshalgetNodeNodeRule, error) { + var retval __premarshalgetNodeNodeRule + + retval.Typename = v.Typename + retval.Id = v.OrganizationRuleFields.Id + retval.Uuid = v.OrganizationRuleFields.Uuid + retval.Description = v.OrganizationRuleFields.Description + retval.Document = v.OrganizationRuleFields.Document + retval.Type = v.OrganizationRuleFields.Type + retval.SourceType = v.OrganizationRuleFields.SourceType + retval.TargetType = v.OrganizationRuleFields.TargetType + retval.Effect = v.OrganizationRuleFields.Effect + retval.Action = v.OrganizationRuleFields.Action + { + + dst := &retval.Source + src := v.OrganizationRuleFields.Source + var err error + *dst, err = __marshalOrganizationRuleFieldsSourceRuleSource( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal getNodeNodeRule.OrganizationRuleFields.Source: %w", err) + } + } + { + + dst := &retval.Target + src := v.OrganizationRuleFields.Target + var err error + *dst, err = __marshalOrganizationRuleFieldsTargetRuleTarget( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal getNodeNodeRule.OrganizationRuleFields.Target: %w", err) + } + } + return &retval, nil +} + // getNodeNodeSSOProviderGitHubApp includes the requested fields of the GraphQL type SSOProviderGitHubApp. // The GraphQL type's documentation follows. // @@ -6293,75 +7094,291 @@ func (v *getNodeNodeTeamSuite) __premarshalJSON() (*__premarshalgetNodeNodeTeamS return &retval, nil } -// getNodeNodeUser includes the requested fields of the GraphQL type User. -// The GraphQL type's documentation follows. -// -// A user -type getNodeNodeUser struct { - Typename string `json:"__typename"` +// getNodeNodeUser includes the requested fields of the GraphQL type User. +// The GraphQL type's documentation follows. +// +// A user +type getNodeNodeUser struct { + Typename string `json:"__typename"` +} + +// GetTypename returns getNodeNodeUser.Typename, and is useful for accessing the field via an interface. +func (v *getNodeNodeUser) GetTypename() string { return v.Typename } + +// getNodeNodeViewer includes the requested fields of the GraphQL type Viewer. +// The GraphQL type's documentation follows. +// +// Represents the current user session +type getNodeNodeViewer struct { + Typename string `json:"__typename"` +} + +// GetTypename returns getNodeNodeViewer.Typename, and is useful for accessing the field via an interface. +func (v *getNodeNodeViewer) GetTypename() string { return v.Typename } + +// getNodeResponse is returned by getNode on success. +type getNodeResponse struct { + // Fetches an object given its ID. + Node getNodeNode `json:"-"` +} + +// GetNode returns getNodeResponse.Node, and is useful for accessing the field via an interface. +func (v *getNodeResponse) GetNode() getNodeNode { return v.Node } + +func (v *getNodeResponse) UnmarshalJSON(b []byte) error { + + if string(b) == "null" { + return nil + } + + var firstPass struct { + *getNodeResponse + Node json.RawMessage `json:"node"` + graphql.NoUnmarshalJSON + } + firstPass.getNodeResponse = v + + err := json.Unmarshal(b, &firstPass) + if err != nil { + return err + } + + { + dst := &v.Node + src := firstPass.Node + if len(src) != 0 && string(src) != "null" { + err = __unmarshalgetNodeNode( + src, dst) + if err != nil { + return fmt.Errorf( + "unable to unmarshal getNodeResponse.Node: %w", err) + } + } + } + return nil +} + +type __premarshalgetNodeResponse struct { + Node json.RawMessage `json:"node"` +} + +func (v *getNodeResponse) MarshalJSON() ([]byte, error) { + premarshaled, err := v.__premarshalJSON() + if err != nil { + return nil, err + } + return json.Marshal(premarshaled) +} + +func (v *getNodeResponse) __premarshalJSON() (*__premarshalgetNodeResponse, error) { + var retval __premarshalgetNodeResponse + + { + + dst := &retval.Node + src := v.Node + var err error + *dst, err = __marshalgetNodeNode( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal getNodeResponse.Node: %w", err) + } + } + return &retval, nil +} + +// getOrganizationOrganization includes the requested fields of the GraphQL type Organization. +// The GraphQL type's documentation follows. +// +// An organization +type getOrganizationOrganization struct { + // A space-separated allowlist of IP addresses that can access the organization via the GraphQL or REST API + AllowedApiIpAddresses string `json:"allowedApiIpAddresses"` + Id string `json:"id"` + // The public UUID for this organization + Uuid string `json:"uuid"` + // Whether this organization requires 2FA to access (Please note that this is a beta feature and is not yet available to all organizations.) + MembersRequireTwoFactorAuthentication bool `json:"membersRequireTwoFactorAuthentication"` +} + +// GetAllowedApiIpAddresses returns getOrganizationOrganization.AllowedApiIpAddresses, and is useful for accessing the field via an interface. +func (v *getOrganizationOrganization) GetAllowedApiIpAddresses() string { + return v.AllowedApiIpAddresses +} + +// GetId returns getOrganizationOrganization.Id, and is useful for accessing the field via an interface. +func (v *getOrganizationOrganization) GetId() string { return v.Id } + +// GetUuid returns getOrganizationOrganization.Uuid, and is useful for accessing the field via an interface. +func (v *getOrganizationOrganization) GetUuid() string { return v.Uuid } + +// GetMembersRequireTwoFactorAuthentication returns getOrganizationOrganization.MembersRequireTwoFactorAuthentication, and is useful for accessing the field via an interface. +func (v *getOrganizationOrganization) GetMembersRequireTwoFactorAuthentication() bool { + return v.MembersRequireTwoFactorAuthentication +} + +// getOrganizationResponse is returned by getOrganization on success. +type getOrganizationResponse struct { + // Find an organization + Organization getOrganizationOrganization `json:"organization"` +} + +// GetOrganization returns getOrganizationResponse.Organization, and is useful for accessing the field via an interface. +func (v *getOrganizationResponse) GetOrganization() getOrganizationOrganization { + return v.Organization +} + +// getOrganizationRulesOrganization includes the requested fields of the GraphQL type Organization. +// The GraphQL type's documentation follows. +// +// An organization +type getOrganizationRulesOrganization struct { + // Returns rules for an Organization + Rules getOrganizationRulesOrganizationRulesRuleConnection `json:"rules"` +} + +// GetRules returns getOrganizationRulesOrganization.Rules, and is useful for accessing the field via an interface. +func (v *getOrganizationRulesOrganization) GetRules() getOrganizationRulesOrganizationRulesRuleConnection { + return v.Rules +} + +// getOrganizationRulesOrganizationRulesRuleConnection includes the requested fields of the GraphQL type RuleConnection. +type getOrganizationRulesOrganizationRulesRuleConnection struct { + PageInfo getOrganizationRulesOrganizationRulesRuleConnectionPageInfo `json:"pageInfo"` + Edges []getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdge `json:"edges"` +} + +// GetPageInfo returns getOrganizationRulesOrganizationRulesRuleConnection.PageInfo, and is useful for accessing the field via an interface. +func (v *getOrganizationRulesOrganizationRulesRuleConnection) GetPageInfo() getOrganizationRulesOrganizationRulesRuleConnectionPageInfo { + return v.PageInfo +} + +// GetEdges returns getOrganizationRulesOrganizationRulesRuleConnection.Edges, and is useful for accessing the field via an interface. +func (v *getOrganizationRulesOrganizationRulesRuleConnection) GetEdges() []getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdge { + return v.Edges +} + +// getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdge includes the requested fields of the GraphQL type RuleEdge. +type getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdge struct { + Node getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule `json:"node"` +} + +// GetNode returns getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdge.Node, and is useful for accessing the field via an interface. +func (v *getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdge) GetNode() getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule { + return v.Node +} + +// getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule includes the requested fields of the GraphQL type Rule. +type getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule struct { + OrganizationRuleFields `json:"-"` +} + +// GetId returns getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule.Id, and is useful for accessing the field via an interface. +func (v *getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule) GetId() string { + return v.OrganizationRuleFields.Id +} + +// GetUuid returns getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule.Uuid, and is useful for accessing the field via an interface. +func (v *getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule) GetUuid() string { + return v.OrganizationRuleFields.Uuid +} + +// GetDescription returns getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule.Description, and is useful for accessing the field via an interface. +func (v *getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule) GetDescription() *string { + return v.OrganizationRuleFields.Description +} + +// GetDocument returns getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule.Document, and is useful for accessing the field via an interface. +func (v *getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule) GetDocument() string { + return v.OrganizationRuleFields.Document +} + +// GetType returns getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule.Type, and is useful for accessing the field via an interface. +func (v *getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule) GetType() string { + return v.OrganizationRuleFields.Type +} + +// GetSourceType returns getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule.SourceType, and is useful for accessing the field via an interface. +func (v *getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule) GetSourceType() RuleSourceType { + return v.OrganizationRuleFields.SourceType } -// GetTypename returns getNodeNodeUser.Typename, and is useful for accessing the field via an interface. -func (v *getNodeNodeUser) GetTypename() string { return v.Typename } +// GetTargetType returns getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule.TargetType, and is useful for accessing the field via an interface. +func (v *getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule) GetTargetType() RuleTargetType { + return v.OrganizationRuleFields.TargetType +} -// getNodeNodeViewer includes the requested fields of the GraphQL type Viewer. -// The GraphQL type's documentation follows. -// -// Represents the current user session -type getNodeNodeViewer struct { - Typename string `json:"__typename"` +// GetEffect returns getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule.Effect, and is useful for accessing the field via an interface. +func (v *getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule) GetEffect() RuleEffect { + return v.OrganizationRuleFields.Effect } -// GetTypename returns getNodeNodeViewer.Typename, and is useful for accessing the field via an interface. -func (v *getNodeNodeViewer) GetTypename() string { return v.Typename } +// GetAction returns getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule.Action, and is useful for accessing the field via an interface. +func (v *getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule) GetAction() RuleAction { + return v.OrganizationRuleFields.Action +} -// getNodeResponse is returned by getNode on success. -type getNodeResponse struct { - // Fetches an object given its ID. - Node getNodeNode `json:"-"` +// GetSource returns getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule.Source, and is useful for accessing the field via an interface. +func (v *getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule) GetSource() OrganizationRuleFieldsSourceRuleSource { + return v.OrganizationRuleFields.Source } -// GetNode returns getNodeResponse.Node, and is useful for accessing the field via an interface. -func (v *getNodeResponse) GetNode() getNodeNode { return v.Node } +// GetTarget returns getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule.Target, and is useful for accessing the field via an interface. +func (v *getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule) GetTarget() OrganizationRuleFieldsTargetRuleTarget { + return v.OrganizationRuleFields.Target +} -func (v *getNodeResponse) UnmarshalJSON(b []byte) error { +func (v *getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule) UnmarshalJSON(b []byte) error { if string(b) == "null" { return nil } var firstPass struct { - *getNodeResponse - Node json.RawMessage `json:"node"` + *getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule graphql.NoUnmarshalJSON } - firstPass.getNodeResponse = v + firstPass.getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule = v err := json.Unmarshal(b, &firstPass) if err != nil { return err } - { - dst := &v.Node - src := firstPass.Node - if len(src) != 0 && string(src) != "null" { - err = __unmarshalgetNodeNode( - src, dst) - if err != nil { - return fmt.Errorf( - "unable to unmarshal getNodeResponse.Node: %w", err) - } - } + err = json.Unmarshal( + b, &v.OrganizationRuleFields) + if err != nil { + return err } return nil } -type __premarshalgetNodeResponse struct { - Node json.RawMessage `json:"node"` +type __premarshalgetOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule struct { + Id string `json:"id"` + + Uuid string `json:"uuid"` + + Description *string `json:"description"` + + Document string `json:"document"` + + Type string `json:"type"` + + SourceType RuleSourceType `json:"sourceType"` + + TargetType RuleTargetType `json:"targetType"` + + Effect RuleEffect `json:"effect"` + + Action RuleAction `json:"action"` + + Source json.RawMessage `json:"source"` + + Target json.RawMessage `json:"target"` } -func (v *getNodeResponse) MarshalJSON() ([]byte, error) { +func (v *getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule) MarshalJSON() ([]byte, error) { premarshaled, err := v.__premarshalJSON() if err != nil { return nil, err @@ -6369,62 +7386,74 @@ func (v *getNodeResponse) MarshalJSON() ([]byte, error) { return json.Marshal(premarshaled) } -func (v *getNodeResponse) __premarshalJSON() (*__premarshalgetNodeResponse, error) { - var retval __premarshalgetNodeResponse +func (v *getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule) __premarshalJSON() (*__premarshalgetOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule, error) { + var retval __premarshalgetOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule + retval.Id = v.OrganizationRuleFields.Id + retval.Uuid = v.OrganizationRuleFields.Uuid + retval.Description = v.OrganizationRuleFields.Description + retval.Document = v.OrganizationRuleFields.Document + retval.Type = v.OrganizationRuleFields.Type + retval.SourceType = v.OrganizationRuleFields.SourceType + retval.TargetType = v.OrganizationRuleFields.TargetType + retval.Effect = v.OrganizationRuleFields.Effect + retval.Action = v.OrganizationRuleFields.Action { - dst := &retval.Node - src := v.Node + dst := &retval.Source + src := v.OrganizationRuleFields.Source var err error - *dst, err = __marshalgetNodeNode( + *dst, err = __marshalOrganizationRuleFieldsSourceRuleSource( &src) if err != nil { return nil, fmt.Errorf( - "unable to marshal getNodeResponse.Node: %w", err) + "unable to marshal getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule.OrganizationRuleFields.Source: %w", err) + } + } + { + + dst := &retval.Target + src := v.OrganizationRuleFields.Target + var err error + *dst, err = __marshalOrganizationRuleFieldsTargetRuleTarget( + &src) + if err != nil { + return nil, fmt.Errorf( + "unable to marshal getOrganizationRulesOrganizationRulesRuleConnectionEdgesRuleEdgeNodeRule.OrganizationRuleFields.Target: %w", err) } } return &retval, nil } -// getOrganizationOrganization includes the requested fields of the GraphQL type Organization. +// getOrganizationRulesOrganizationRulesRuleConnectionPageInfo includes the requested fields of the GraphQL type PageInfo. // The GraphQL type's documentation follows. // -// An organization -type getOrganizationOrganization struct { - // A space-separated allowlist of IP addresses that can access the organization via the GraphQL or REST API - AllowedApiIpAddresses string `json:"allowedApiIpAddresses"` - Id string `json:"id"` - // The public UUID for this organization - Uuid string `json:"uuid"` - // Whether this organization requires 2FA to access (Please note that this is a beta feature and is not yet available to all organizations.) - MembersRequireTwoFactorAuthentication bool `json:"membersRequireTwoFactorAuthentication"` +// Information about pagination in a connection. +type getOrganizationRulesOrganizationRulesRuleConnectionPageInfo struct { + // When paginating forwards, the cursor to continue. + EndCursor string `json:"endCursor"` + // When paginating forwards, are there more items? + HasNextPage bool `json:"hasNextPage"` } -// GetAllowedApiIpAddresses returns getOrganizationOrganization.AllowedApiIpAddresses, and is useful for accessing the field via an interface. -func (v *getOrganizationOrganization) GetAllowedApiIpAddresses() string { - return v.AllowedApiIpAddresses +// GetEndCursor returns getOrganizationRulesOrganizationRulesRuleConnectionPageInfo.EndCursor, and is useful for accessing the field via an interface. +func (v *getOrganizationRulesOrganizationRulesRuleConnectionPageInfo) GetEndCursor() string { + return v.EndCursor } -// GetId returns getOrganizationOrganization.Id, and is useful for accessing the field via an interface. -func (v *getOrganizationOrganization) GetId() string { return v.Id } - -// GetUuid returns getOrganizationOrganization.Uuid, and is useful for accessing the field via an interface. -func (v *getOrganizationOrganization) GetUuid() string { return v.Uuid } - -// GetMembersRequireTwoFactorAuthentication returns getOrganizationOrganization.MembersRequireTwoFactorAuthentication, and is useful for accessing the field via an interface. -func (v *getOrganizationOrganization) GetMembersRequireTwoFactorAuthentication() bool { - return v.MembersRequireTwoFactorAuthentication +// GetHasNextPage returns getOrganizationRulesOrganizationRulesRuleConnectionPageInfo.HasNextPage, and is useful for accessing the field via an interface. +func (v *getOrganizationRulesOrganizationRulesRuleConnectionPageInfo) GetHasNextPage() bool { + return v.HasNextPage } -// getOrganizationResponse is returned by getOrganization on success. -type getOrganizationResponse struct { +// getOrganizationRulesResponse is returned by getOrganizationRules on success. +type getOrganizationRulesResponse struct { // Find an organization - Organization getOrganizationOrganization `json:"organization"` + Organization getOrganizationRulesOrganization `json:"organization"` } -// GetOrganization returns getOrganizationResponse.Organization, and is useful for accessing the field via an interface. -func (v *getOrganizationResponse) GetOrganization() getOrganizationOrganization { +// GetOrganization returns getOrganizationRulesResponse.Organization, and is useful for accessing the field via an interface. +func (v *getOrganizationRulesResponse) GetOrganization() getOrganizationRulesOrganization { return v.Organization } @@ -6960,6 +7989,8 @@ func (v *getPipelineScheduleBySlugResponse) GetPipelineSchedule() getPipelineSch // getPipelineScheduleNodePipelineSchedule // getPipelineScheduleNodePipelineTemplate // getPipelineScheduleNodeRegistry +// getPipelineScheduleNodeRegistryToken +// getPipelineScheduleNodeRule // getPipelineScheduleNodeSSOProviderGitHubApp // getPipelineScheduleNodeSSOProviderGoogleGSuite // getPipelineScheduleNodeSSOProviderSAML @@ -7045,7 +8076,9 @@ func (v *getPipelineScheduleNodePipelineSchedule) implementsGraphQLInterfacegetP } func (v *getPipelineScheduleNodePipelineTemplate) implementsGraphQLInterfacegetPipelineScheduleNode() { } -func (v *getPipelineScheduleNodeRegistry) implementsGraphQLInterfacegetPipelineScheduleNode() {} +func (v *getPipelineScheduleNodeRegistry) implementsGraphQLInterfacegetPipelineScheduleNode() {} +func (v *getPipelineScheduleNodeRegistryToken) implementsGraphQLInterfacegetPipelineScheduleNode() {} +func (v *getPipelineScheduleNodeRule) implementsGraphQLInterfacegetPipelineScheduleNode() {} func (v *getPipelineScheduleNodeSSOProviderGitHubApp) implementsGraphQLInterfacegetPipelineScheduleNode() { } func (v *getPipelineScheduleNodeSSOProviderGoogleGSuite) implementsGraphQLInterfacegetPipelineScheduleNode() { @@ -7205,6 +8238,12 @@ func __unmarshalgetPipelineScheduleNode(b []byte, v *getPipelineScheduleNode) er case "Registry": *v = new(getPipelineScheduleNodeRegistry) return json.Unmarshal(b, *v) + case "RegistryToken": + *v = new(getPipelineScheduleNodeRegistryToken) + return json.Unmarshal(b, *v) + case "Rule": + *v = new(getPipelineScheduleNodeRule) + return json.Unmarshal(b, *v) case "SSOProviderGitHubApp": *v = new(getPipelineScheduleNodeSSOProviderGitHubApp) return json.Unmarshal(b, *v) @@ -7602,6 +8641,22 @@ func __marshalgetPipelineScheduleNode(v *getPipelineScheduleNode) ([]byte, error *getPipelineScheduleNodeRegistry }{typename, v} return json.Marshal(result) + case *getPipelineScheduleNodeRegistryToken: + typename = "RegistryToken" + + result := struct { + TypeName string `json:"__typename"` + *getPipelineScheduleNodeRegistryToken + }{typename, v} + return json.Marshal(result) + case *getPipelineScheduleNodeRule: + typename = "Rule" + + result := struct { + TypeName string `json:"__typename"` + *getPipelineScheduleNodeRule + }{typename, v} + return json.Marshal(result) case *getPipelineScheduleNodeSSOProviderGitHubApp: typename = "SSOProviderGitHubApp" @@ -8300,6 +9355,25 @@ type getPipelineScheduleNodeRegistry struct { // GetTypename returns getPipelineScheduleNodeRegistry.Typename, and is useful for accessing the field via an interface. func (v *getPipelineScheduleNodeRegistry) GetTypename() string { return v.Typename } +// getPipelineScheduleNodeRegistryToken includes the requested fields of the GraphQL type RegistryToken. +// The GraphQL type's documentation follows. +// +// A registry token +type getPipelineScheduleNodeRegistryToken struct { + Typename string `json:"__typename"` +} + +// GetTypename returns getPipelineScheduleNodeRegistryToken.Typename, and is useful for accessing the field via an interface. +func (v *getPipelineScheduleNodeRegistryToken) GetTypename() string { return v.Typename } + +// getPipelineScheduleNodeRule includes the requested fields of the GraphQL type Rule. +type getPipelineScheduleNodeRule struct { + Typename string `json:"__typename"` +} + +// GetTypename returns getPipelineScheduleNodeRule.Typename, and is useful for accessing the field via an interface. +func (v *getPipelineScheduleNodeRule) GetTypename() string { return v.Typename } + // getPipelineScheduleNodeSSOProviderGitHubApp includes the requested fields of the GraphQL type SSOProviderGitHubApp. // The GraphQL type's documentation follows. // @@ -9283,6 +10357,8 @@ func (v *getTestSuiteSuiteJobTypeWait) GetTypename() string { return v.Typename // getTestSuiteSuitePipelineSchedule // getTestSuiteSuitePipelineTemplate // getTestSuiteSuiteRegistry +// getTestSuiteSuiteRegistryToken +// getTestSuiteSuiteRule // getTestSuiteSuiteSSOProviderGitHubApp // getTestSuiteSuiteSSOProviderGoogleGSuite // getTestSuiteSuiteSSOProviderSAML @@ -9350,6 +10426,8 @@ func (v *getTestSuiteSuitePipelineMetric) implementsGraphQLInterfacegetTestSuite func (v *getTestSuiteSuitePipelineSchedule) implementsGraphQLInterfacegetTestSuiteSuiteNode() {} func (v *getTestSuiteSuitePipelineTemplate) implementsGraphQLInterfacegetTestSuiteSuiteNode() {} func (v *getTestSuiteSuiteRegistry) implementsGraphQLInterfacegetTestSuiteSuiteNode() {} +func (v *getTestSuiteSuiteRegistryToken) implementsGraphQLInterfacegetTestSuiteSuiteNode() {} +func (v *getTestSuiteSuiteRule) implementsGraphQLInterfacegetTestSuiteSuiteNode() {} func (v *getTestSuiteSuiteSSOProviderGitHubApp) implementsGraphQLInterfacegetTestSuiteSuiteNode() {} func (v *getTestSuiteSuiteSSOProviderGoogleGSuite) implementsGraphQLInterfacegetTestSuiteSuiteNode() { } @@ -9507,6 +10585,12 @@ func __unmarshalgetTestSuiteSuiteNode(b []byte, v *getTestSuiteSuiteNode) error case "Registry": *v = new(getTestSuiteSuiteRegistry) return json.Unmarshal(b, *v) + case "RegistryToken": + *v = new(getTestSuiteSuiteRegistryToken) + return json.Unmarshal(b, *v) + case "Rule": + *v = new(getTestSuiteSuiteRule) + return json.Unmarshal(b, *v) case "SSOProviderGitHubApp": *v = new(getTestSuiteSuiteSSOProviderGitHubApp) return json.Unmarshal(b, *v) @@ -9900,6 +10984,22 @@ func __marshalgetTestSuiteSuiteNode(v *getTestSuiteSuiteNode) ([]byte, error) { *getTestSuiteSuiteRegistry }{typename, v} return json.Marshal(result) + case *getTestSuiteSuiteRegistryToken: + typename = "RegistryToken" + + result := struct { + TypeName string `json:"__typename"` + *getTestSuiteSuiteRegistryToken + }{typename, v} + return json.Marshal(result) + case *getTestSuiteSuiteRule: + typename = "Rule" + + result := struct { + TypeName string `json:"__typename"` + *getTestSuiteSuiteRule + }{typename, v} + return json.Marshal(result) case *getTestSuiteSuiteSSOProviderGitHubApp: typename = "SSOProviderGitHubApp" @@ -10114,6 +11214,25 @@ type getTestSuiteSuiteRegistry struct { // GetTypename returns getTestSuiteSuiteRegistry.Typename, and is useful for accessing the field via an interface. func (v *getTestSuiteSuiteRegistry) GetTypename() string { return v.Typename } +// getTestSuiteSuiteRegistryToken includes the requested fields of the GraphQL type RegistryToken. +// The GraphQL type's documentation follows. +// +// A registry token +type getTestSuiteSuiteRegistryToken struct { + Typename string `json:"__typename"` +} + +// GetTypename returns getTestSuiteSuiteRegistryToken.Typename, and is useful for accessing the field via an interface. +func (v *getTestSuiteSuiteRegistryToken) GetTypename() string { return v.Typename } + +// getTestSuiteSuiteRule includes the requested fields of the GraphQL type Rule. +type getTestSuiteSuiteRule struct { + Typename string `json:"__typename"` +} + +// GetTypename returns getTestSuiteSuiteRule.Typename, and is useful for accessing the field via an interface. +func (v *getTestSuiteSuiteRule) GetTypename() string { return v.Typename } + // getTestSuiteSuiteSSOProviderGitHubApp includes the requested fields of the GraphQL type SSOProviderGitHubApp. // The GraphQL type's documentation follows. // @@ -12364,29 +13483,29 @@ fragment TeamFields on Team { ` func GetTeamFromSlug( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, slug string, ) (*GetTeamFromSlugResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "GetTeamFromSlug", Query: GetTeamFromSlug_Operation, Variables: &__GetTeamFromSlugInput{ Slug: slug, }, } - var err error + var err_ error - var data GetTeamFromSlugResponse - resp := &graphql.Response{Data: &data} + var data_ GetTeamFromSlugResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by archivePipeline. @@ -12399,29 +13518,29 @@ mutation archivePipeline ($id: ID!) { ` func archivePipeline( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, id string, ) (*archivePipelineResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "archivePipeline", Query: archivePipeline_Operation, Variables: &__archivePipelineInput{ Id: id, }, } - var err error + var err_ error - var data archivePipelineResponse - resp := &graphql.Response{Data: &data} + var data_ archivePipelineResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by createAgentToken. @@ -12441,12 +13560,12 @@ mutation createAgentToken ($organizationId: ID!, $description: String) { ` func createAgentToken( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, organizationId string, description *string, ) (*createAgentTokenResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "createAgentToken", Query: createAgentToken_Operation, Variables: &__createAgentTokenInput{ @@ -12454,18 +13573,18 @@ func createAgentToken( Description: description, }, } - var err error + var err_ error - var data createAgentTokenResponse - resp := &graphql.Response{Data: &data} + var data_ createAgentTokenResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by createCluster. @@ -12495,15 +13614,15 @@ fragment ClusterFields on Cluster { ` func createCluster( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, organizationId string, name string, description *string, emoji *string, color *string, ) (*createClusterResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "createCluster", Query: createCluster_Operation, Variables: &__createClusterInput{ @@ -12514,18 +13633,18 @@ func createCluster( Color: color, }, } - var err error + var err_ error - var data createClusterResponse - resp := &graphql.Response{Data: &data} + var data_ createClusterResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by createClusterAgentToken. @@ -12551,14 +13670,14 @@ fragment ClusterAgentTokenValues on ClusterToken { ` func createClusterAgentToken( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, organizationId string, clusterId string, description string, allowedIpAddresses string, ) (*createClusterAgentTokenResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "createClusterAgentToken", Query: createClusterAgentToken_Operation, Variables: &__createClusterAgentTokenInput{ @@ -12568,18 +13687,18 @@ func createClusterAgentToken( AllowedIpAddresses: allowedIpAddresses, }, } - var err error + var err_ error - var data createClusterAgentTokenResponse - resp := &graphql.Response{Data: &data} + var data_ createClusterAgentTokenResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by createClusterQueue. @@ -12604,14 +13723,14 @@ fragment ClusterQueueValues on ClusterQueue { ` func createClusterQueue( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, organizationId string, clusterId string, key string, description *string, ) (*createClusterQueueResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "createClusterQueue", Query: createClusterQueue_Operation, Variables: &__createClusterQueueInput{ @@ -12621,18 +13740,84 @@ func createClusterQueue( Description: description, }, } - var err error + var err_ error + + var data_ createClusterQueueResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by createOrganizationRule. +const createOrganizationRule_Operation = ` +mutation createOrganizationRule ($organizationId: ID!, $description: String, $ruleType: String!, $value: JSON!) { + ruleCreate(input: {organizationId:$organizationId,description:$description,type:$ruleType,value:$value}) { + rule { + ... OrganizationRuleFields + } + } +} +fragment OrganizationRuleFields on Rule { + id + uuid + description + document + type + sourceType + targetType + effect + action + source { + __typename + ... on Pipeline { + uuid + } + } + target { + __typename + ... on Pipeline { + uuid + } + } +} +` + +func createOrganizationRule( + ctx_ context.Context, + client_ graphql.Client, + organizationId string, + description *string, + ruleType string, + value string, +) (*createOrganizationRuleResponse, error) { + req_ := &graphql.Request{ + OpName: "createOrganizationRule", + Query: createOrganizationRule_Operation, + Variables: &__createOrganizationRuleInput{ + OrganizationId: organizationId, + Description: description, + RuleType: ruleType, + Value: value, + }, + } + var err_ error - var data createClusterQueueResponse - resp := &graphql.Response{Data: &data} + var data_ createOrganizationRuleResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by createPipeline. @@ -12701,29 +13886,29 @@ fragment PipelineTeam on TeamPipelineConnection { ` func createPipeline( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, input PipelineCreateInput, ) (*createPipelineResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "createPipeline", Query: createPipeline_Operation, Variables: &__createPipelineInput{ Input: input, }, } - var err error + var err_ error - var data createPipelineResponse - resp := &graphql.Response{Data: &data} + var data_ createPipelineResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by createPipelineSchedule. @@ -12757,8 +13942,8 @@ fragment PipelineScheduleValues on PipelineSchedule { ` func createPipelineSchedule( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, pipelineId string, label *string, cronline *string, @@ -12768,7 +13953,7 @@ func createPipelineSchedule( env *string, enabled bool, ) (*createPipelineScheduleResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "createPipelineSchedule", Query: createPipelineSchedule_Operation, Variables: &__createPipelineScheduleInput{ @@ -12782,18 +13967,18 @@ func createPipelineSchedule( Enabled: enabled, }, } - var err error + var err_ error - var data createPipelineScheduleResponse - resp := &graphql.Response{Data: &data} + var data_ createPipelineScheduleResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by createPipelineTemplate. @@ -12816,15 +14001,15 @@ fragment PipelineTemplateFields on PipelineTemplate { ` func createPipelineTemplate( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, organizationId string, name string, configuration string, description *string, available bool, ) (*createPipelineTemplateResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "createPipelineTemplate", Query: createPipelineTemplate_Operation, Variables: &__createPipelineTemplateInput{ @@ -12835,18 +14020,18 @@ func createPipelineTemplate( Available: available, }, } - var err error + var err_ error - var data createPipelineTemplateResponse - resp := &graphql.Response{Data: &data} + var data_ createPipelineTemplateResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by createTeamMember. @@ -12874,13 +14059,13 @@ fragment TeamMemberFields on TeamMember { ` func createTeamMember( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, teamID string, userID string, role string, ) (*createTeamMemberResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "createTeamMember", Query: createTeamMember_Operation, Variables: &__createTeamMemberInput{ @@ -12889,18 +14074,18 @@ func createTeamMember( Role: role, }, } - var err error + var err_ error - var data createTeamMemberResponse - resp := &graphql.Response{Data: &data} + var data_ createTeamMemberResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by createTeamPipeline. @@ -12928,13 +14113,13 @@ fragment TeamPipelineFields on TeamPipeline { ` func createTeamPipeline( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, teamID string, pipelineID string, accessLevel PipelineAccessLevels, ) (*createTeamPipelineResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "createTeamPipeline", Query: createTeamPipeline_Operation, Variables: &__createTeamPipelineInput{ @@ -12943,18 +14128,18 @@ func createTeamPipeline( AccessLevel: accessLevel, }, } - var err error + var err_ error - var data createTeamPipelineResponse - resp := &graphql.Response{Data: &data} + var data_ createTeamPipelineResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by createTestSuiteTeam. @@ -12993,13 +14178,13 @@ fragment TeamSuiteFields on TeamSuite { ` func createTestSuiteTeam( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, teamId string, suiteId string, accessLevel SuiteAccessLevels, ) (*createTestSuiteTeamResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "createTestSuiteTeam", Query: createTestSuiteTeam_Operation, Variables: &__createTestSuiteTeamInput{ @@ -13008,18 +14193,18 @@ func createTestSuiteTeam( AccessLevel: accessLevel, }, } - var err error + var err_ error - var data createTestSuiteTeamResponse - resp := &graphql.Response{Data: &data} + var data_ createTestSuiteTeamResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by deleteBanner. @@ -13032,29 +14217,29 @@ mutation deleteBanner ($organizationId: ID!) { ` func deleteBanner( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, organizationId string, ) (*deleteBannerResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "deleteBanner", Query: deleteBanner_Operation, Variables: &__deleteBannerInput{ OrganizationId: organizationId, }, } - var err error + var err_ error - var data deleteBannerResponse - resp := &graphql.Response{Data: &data} + var data_ deleteBannerResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by deleteCluster. @@ -13067,12 +14252,12 @@ mutation deleteCluster ($organizationId: ID!, $id: ID!) { ` func deleteCluster( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, organizationId string, id string, ) (*deleteClusterResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "deleteCluster", Query: deleteCluster_Operation, Variables: &__deleteClusterInput{ @@ -13080,18 +14265,18 @@ func deleteCluster( Id: id, }, } - var err error + var err_ error - var data deleteClusterResponse - resp := &graphql.Response{Data: &data} + var data_ deleteClusterResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by deleteClusterQueue. @@ -13104,12 +14289,12 @@ mutation deleteClusterQueue ($organizationId: ID!, $id: ID!) { ` func deleteClusterQueue( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, organizationId string, id string, ) (*deleteClusterQueueResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "deleteClusterQueue", Query: deleteClusterQueue_Operation, Variables: &__deleteClusterQueueInput{ @@ -13117,18 +14302,55 @@ func deleteClusterQueue( Id: id, }, } - var err error + var err_ error + + var data_ deleteClusterQueueResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by deleteOrganizationRule. +const deleteOrganizationRule_Operation = ` +mutation deleteOrganizationRule ($organizationId: ID!, $id: ID!) { + ruleDelete(input: {organizationId:$organizationId,id:$id}) { + clientMutationId + } +} +` + +func deleteOrganizationRule( + ctx_ context.Context, + client_ graphql.Client, + organizationId string, + id string, +) (*deleteOrganizationRuleResponse, error) { + req_ := &graphql.Request{ + OpName: "deleteOrganizationRule", + Query: deleteOrganizationRule_Operation, + Variables: &__deleteOrganizationRuleInput{ + OrganizationId: organizationId, + Id: id, + }, + } + var err_ error - var data deleteClusterQueueResponse - resp := &graphql.Response{Data: &data} + var data_ deleteOrganizationRuleResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by deletePipeline. @@ -13141,29 +14363,29 @@ mutation deletePipeline ($id: ID!) { ` func deletePipeline( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, id string, ) (*deletePipelineResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "deletePipeline", Query: deletePipeline_Operation, Variables: &__deletePipelineInput{ Id: id, }, } - var err error + var err_ error - var data deletePipelineResponse - resp := &graphql.Response{Data: &data} + var data_ deletePipelineResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by deletePipelineSchedule. @@ -13176,29 +14398,29 @@ mutation deletePipelineSchedule ($id: ID!) { ` func deletePipelineSchedule( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, id string, ) (*deletePipelineScheduleResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "deletePipelineSchedule", Query: deletePipelineSchedule_Operation, Variables: &__deletePipelineScheduleInput{ Id: id, }, } - var err error + var err_ error - var data deletePipelineScheduleResponse - resp := &graphql.Response{Data: &data} + var data_ deletePipelineScheduleResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by deletePipelineTemplate. @@ -13211,12 +14433,12 @@ mutation deletePipelineTemplate ($organizationId: ID!, $id: ID!) { ` func deletePipelineTemplate( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, organizationId string, id string, ) (*deletePipelineTemplateResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "deletePipelineTemplate", Query: deletePipelineTemplate_Operation, Variables: &__deletePipelineTemplateInput{ @@ -13224,18 +14446,18 @@ func deletePipelineTemplate( Id: id, }, } - var err error + var err_ error - var data deletePipelineTemplateResponse - resp := &graphql.Response{Data: &data} + var data_ deletePipelineTemplateResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by deleteTeamMember. @@ -13248,29 +14470,29 @@ mutation deleteTeamMember ($id: ID!) { ` func deleteTeamMember( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, id string, ) (*deleteTeamMemberResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "deleteTeamMember", Query: deleteTeamMember_Operation, Variables: &__deleteTeamMemberInput{ Id: id, }, } - var err error + var err_ error - var data deleteTeamMemberResponse - resp := &graphql.Response{Data: &data} + var data_ deleteTeamMemberResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by deleteTeamPipeline. @@ -13284,29 +14506,29 @@ mutation deleteTeamPipeline ($id: ID!) { ` func deleteTeamPipeline( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, id string, ) (*deleteTeamPipelineResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "deleteTeamPipeline", Query: deleteTeamPipeline_Operation, Variables: &__deleteTeamPipelineInput{ Id: id, }, } - var err error + var err_ error - var data deleteTeamPipelineResponse - resp := &graphql.Response{Data: &data} + var data_ deleteTeamPipelineResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by deleteTestSuiteTeam. @@ -13322,29 +14544,29 @@ mutation deleteTestSuiteTeam ($id: ID!) { ` func deleteTestSuiteTeam( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, id string, ) (*deleteTestSuiteTeamResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "deleteTestSuiteTeam", Query: deleteTestSuiteTeam_Operation, Variables: &__deleteTestSuiteTeamInput{ Id: id, }, } - var err error + var err_ error - var data deleteTestSuiteTeamResponse - resp := &graphql.Response{Data: &data} + var data_ deleteTestSuiteTeamResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by getAgentToken. @@ -13359,29 +14581,29 @@ query getAgentToken ($slug: ID!) { ` func getAgentToken( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, slug string, ) (*getAgentTokenResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "getAgentToken", Query: getAgentToken_Operation, Variables: &__getAgentTokenInput{ Slug: slug, }, } - var err error + var err_ error - var data getAgentTokenResponse - resp := &graphql.Response{Data: &data} + var data_ getAgentTokenResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by getClusterAgentTokens. @@ -13412,12 +14634,12 @@ fragment ClusterAgentTokenValues on ClusterToken { ` func getClusterAgentTokens( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, orgSlug string, id string, ) (*getClusterAgentTokensResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "getClusterAgentTokens", Query: getClusterAgentTokens_Operation, Variables: &__getClusterAgentTokensInput{ @@ -13425,18 +14647,18 @@ func getClusterAgentTokens( Id: id, }, } - var err error + var err_ error - var data getClusterAgentTokensResponse - resp := &graphql.Response{Data: &data} + var data_ getClusterAgentTokensResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by getClusterByName. @@ -13473,12 +14695,12 @@ fragment ClusterFields on Cluster { ` func getClusterByName( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, orgSlug string, cursor *string, ) (*getClusterByNameResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "getClusterByName", Query: getClusterByName_Operation, Variables: &__getClusterByNameInput{ @@ -13486,18 +14708,18 @@ func getClusterByName( Cursor: cursor, }, } - var err error + var err_ error - var data getClusterByNameResponse - resp := &graphql.Response{Data: &data} + var data_ getClusterByNameResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by getClusterQueues. @@ -13528,12 +14750,12 @@ fragment ClusterQueueValues on ClusterQueue { ` func getClusterQueues( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, orgSlug string, id string, ) (*getClusterQueuesResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "getClusterQueues", Query: getClusterQueues_Operation, Variables: &__getClusterQueuesInput{ @@ -13541,18 +14763,18 @@ func getClusterQueues( Id: id, }, } - var err error + var err_ error - var data getClusterQueuesResponse - resp := &graphql.Response{Data: &data} + var data_ getClusterQueuesResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by getNode. @@ -13566,6 +14788,9 @@ query getNode ($id: ID!) { ... on PipelineTemplate { ... PipelineTemplateFields } + ... on Rule { + ... OrganizationRuleFields + } ... on TeamMember { ... TeamMemberFields } @@ -13627,6 +14852,29 @@ fragment PipelineTemplateFields on PipelineTemplate { description name } +fragment OrganizationRuleFields on Rule { + id + uuid + description + document + type + sourceType + targetType + effect + action + source { + __typename + ... on Pipeline { + uuid + } + } + target { + __typename + ... on Pipeline { + uuid + } + } +} fragment TeamMemberFields on TeamMember { id uuid @@ -13705,29 +14953,29 @@ fragment PipelineTeam on TeamPipelineConnection { ` func getNode( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, id string, ) (*getNodeResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "getNode", Query: getNode_Operation, Variables: &__getNodeInput{ Id: id, }, } - var err error + var err_ error - var data getNodeResponse - resp := &graphql.Response{Data: &data} + var data_ getNodeResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by getOrganization. @@ -13743,29 +14991,99 @@ query getOrganization ($slug: ID!) { ` func getOrganization( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, slug string, ) (*getOrganizationResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "getOrganization", Query: getOrganization_Operation, Variables: &__getOrganizationInput{ Slug: slug, }, } - var err error + var err_ error + + var data_ getOrganizationResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by getOrganizationRules. +const getOrganizationRules_Operation = ` +query getOrganizationRules ($orgSlug: ID!, $cursor: String) { + organization(slug: $orgSlug) { + rules(first: 50, after: $cursor) { + pageInfo { + endCursor + hasNextPage + } + edges { + node { + ... OrganizationRuleFields + } + } + } + } +} +fragment OrganizationRuleFields on Rule { + id + uuid + description + document + type + sourceType + targetType + effect + action + source { + __typename + ... on Pipeline { + uuid + } + } + target { + __typename + ... on Pipeline { + uuid + } + } +} +` + +func getOrganizationRules( + ctx_ context.Context, + client_ graphql.Client, + orgSlug string, + cursor *string, +) (*getOrganizationRulesResponse, error) { + req_ := &graphql.Request{ + OpName: "getOrganizationRules", + Query: getOrganizationRules_Operation, + Variables: &__getOrganizationRulesInput{ + OrgSlug: orgSlug, + Cursor: cursor, + }, + } + var err_ error - var data getOrganizationResponse - resp := &graphql.Response{Data: &data} + var data_ getOrganizationRulesResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by getOrganiztionBanner. @@ -13789,29 +15107,29 @@ fragment OrganizationBannerFields on OrganizationBanner { ` func getOrganiztionBanner( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, orgSlug string, ) (*getOrganiztionBannerResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "getOrganiztionBanner", Query: getOrganiztionBanner_Operation, Variables: &__getOrganiztionBannerInput{ OrgSlug: orgSlug, }, } - var err error + var err_ error - var data getOrganiztionBannerResponse - resp := &graphql.Response{Data: &data} + var data_ getOrganiztionBannerResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by getPipeline. @@ -13878,29 +15196,29 @@ fragment PipelineTeam on TeamPipelineConnection { ` func getPipeline( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, slug string, ) (*getPipelineResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "getPipeline", Query: getPipeline_Operation, Variables: &__getPipelineInput{ Slug: slug, }, } - var err error + var err_ error - var data getPipelineResponse - resp := &graphql.Response{Data: &data} + var data_ getPipelineResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by getPipelineSchedule. @@ -13930,29 +15248,29 @@ fragment PipelineScheduleValues on PipelineSchedule { ` func getPipelineSchedule( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, id string, ) (*getPipelineScheduleResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "getPipelineSchedule", Query: getPipelineSchedule_Operation, Variables: &__getPipelineScheduleInput{ Id: id, }, } - var err error + var err_ error - var data getPipelineScheduleResponse - resp := &graphql.Response{Data: &data} + var data_ getPipelineScheduleResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by getPipelineScheduleBySlug. @@ -13979,29 +15297,29 @@ fragment PipelineScheduleValues on PipelineSchedule { ` func getPipelineScheduleBySlug( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, slug string, ) (*getPipelineScheduleBySlugResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "getPipelineScheduleBySlug", Query: getPipelineScheduleBySlug_Operation, Variables: &__getPipelineScheduleBySlugInput{ Slug: slug, }, } - var err error + var err_ error - var data getPipelineScheduleBySlugResponse - resp := &graphql.Response{Data: &data} + var data_ getPipelineScheduleBySlugResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by getPipelineTeams. @@ -14033,12 +15351,12 @@ fragment PipelineTeam on TeamPipelineConnection { ` func getPipelineTeams( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, slug string, cursor string, ) (*getPipelineTeamsResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "getPipelineTeams", Query: getPipelineTeams_Operation, Variables: &__getPipelineTeamsInput{ @@ -14046,18 +15364,18 @@ func getPipelineTeams( Cursor: cursor, }, } - var err error + var err_ error - var data getPipelineTeamsResponse - resp := &graphql.Response{Data: &data} + var data_ getPipelineTeamsResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by getPipelineTemplates. @@ -14088,12 +15406,12 @@ fragment PipelineTemplateFields on PipelineTemplate { ` func getPipelineTemplates( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, orgSlug string, cursor *string, ) (*getPipelineTemplatesResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "getPipelineTemplates", Query: getPipelineTemplates_Operation, Variables: &__getPipelineTemplatesInput{ @@ -14101,18 +15419,18 @@ func getPipelineTemplates( Cursor: cursor, }, } - var err error + var err_ error - var data getPipelineTemplatesResponse - resp := &graphql.Response{Data: &data} + var data_ getPipelineTemplatesResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by getTestSuite. @@ -14143,12 +15461,12 @@ query getTestSuite ($id: ID!, $teamCount: Int) { ` func getTestSuite( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, id string, teamCount int, ) (*getTestSuiteResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "getTestSuite", Query: getTestSuite_Operation, Variables: &__getTestSuiteInput{ @@ -14156,18 +15474,18 @@ func getTestSuite( TeamCount: teamCount, }, } - var err error + var err_ error - var data getTestSuiteResponse - resp := &graphql.Response{Data: &data} + var data_ getTestSuiteResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by removeClusterDefaultQueue. @@ -14201,12 +15519,12 @@ fragment ClusterFields on Cluster { ` func removeClusterDefaultQueue( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, organizationId string, clusterId string, ) (*removeClusterDefaultQueueResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "removeClusterDefaultQueue", Query: removeClusterDefaultQueue_Operation, Variables: &__removeClusterDefaultQueueInput{ @@ -14214,18 +15532,18 @@ func removeClusterDefaultQueue( ClusterId: clusterId, }, } - var err error + var err_ error - var data removeClusterDefaultQueueResponse - resp := &graphql.Response{Data: &data} + var data_ removeClusterDefaultQueueResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by revokeAgentToken. @@ -14242,12 +15560,12 @@ mutation revokeAgentToken ($id: ID!, $reason: String!) { ` func revokeAgentToken( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, id string, reason string, ) (*revokeAgentTokenResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "revokeAgentToken", Query: revokeAgentToken_Operation, Variables: &__revokeAgentTokenInput{ @@ -14255,18 +15573,18 @@ func revokeAgentToken( Reason: reason, }, } - var err error + var err_ error - var data revokeAgentTokenResponse - resp := &graphql.Response{Data: &data} + var data_ revokeAgentTokenResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by revokeClusterAgentToken. @@ -14279,12 +15597,12 @@ mutation revokeClusterAgentToken ($organizationId: ID!, $id: ID!) { ` func revokeClusterAgentToken( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, organizationId string, id string, ) (*revokeClusterAgentTokenResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "revokeClusterAgentToken", Query: revokeClusterAgentToken_Operation, Variables: &__revokeClusterAgentTokenInput{ @@ -14292,18 +15610,18 @@ func revokeClusterAgentToken( Id: id, }, } - var err error + var err_ error - var data revokeClusterAgentTokenResponse - resp := &graphql.Response{Data: &data} + var data_ revokeClusterAgentTokenResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by setApiIpAddresses. @@ -14321,12 +15639,12 @@ mutation setApiIpAddresses ($organizationID: ID!, $ipAddresses: String!) { ` func setApiIpAddresses( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, organizationID string, ipAddresses string, ) (*setApiIpAddressesResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "setApiIpAddresses", Query: setApiIpAddresses_Operation, Variables: &__setApiIpAddressesInput{ @@ -14334,18 +15652,18 @@ func setApiIpAddresses( IpAddresses: ipAddresses, }, } - var err error + var err_ error - var data setApiIpAddressesResponse - resp := &graphql.Response{Data: &data} + var data_ setApiIpAddressesResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by setClusterDefaultQueue. @@ -14379,13 +15697,13 @@ fragment ClusterFields on Cluster { ` func setClusterDefaultQueue( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, organizationId string, clusterId string, queueId string, ) (*setClusterDefaultQueueResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "setClusterDefaultQueue", Query: setClusterDefaultQueue_Operation, Variables: &__setClusterDefaultQueueInput{ @@ -14394,18 +15712,18 @@ func setClusterDefaultQueue( QueueId: queueId, }, } - var err error + var err_ error - var data setClusterDefaultQueueResponse - resp := &graphql.Response{Data: &data} + var data_ setClusterDefaultQueueResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by setOrganization2FA. @@ -14420,12 +15738,12 @@ mutation setOrganization2FA ($organizationID: ID!, $value: Boolean!) { ` func setOrganization2FA( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, organizationID string, value bool, ) (*setOrganization2FAResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "setOrganization2FA", Query: setOrganization2FA_Operation, Variables: &__setOrganization2FAInput{ @@ -14433,18 +15751,18 @@ func setOrganization2FA( Value: value, }, } - var err error + var err_ error - var data setOrganization2FAResponse - resp := &graphql.Response{Data: &data} + var data_ setOrganization2FAResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by teamCreate. @@ -14472,8 +15790,8 @@ fragment TeamFields on Team { ` func teamCreate( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, organizationID string, name string, description string, @@ -14482,7 +15800,7 @@ func teamCreate( defaultMemberRole string, membersCanCreatePipelines bool, ) (*teamCreateResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "teamCreate", Query: teamCreate_Operation, Variables: &__teamCreateInput{ @@ -14495,18 +15813,18 @@ func teamCreate( MembersCanCreatePipelines: membersCanCreatePipelines, }, } - var err error + var err_ error - var data teamCreateResponse - resp := &graphql.Response{Data: &data} + var data_ teamCreateResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by teamDelete. @@ -14519,29 +15837,29 @@ mutation teamDelete ($id: ID!) { ` func teamDelete( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, id string, ) (*teamDeleteResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "teamDelete", Query: teamDelete_Operation, Variables: &__teamDeleteInput{ Id: id, }, } - var err error + var err_ error - var data teamDeleteResponse - resp := &graphql.Response{Data: &data} + var data_ teamDeleteResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by teamUpdate. @@ -14567,8 +15885,8 @@ fragment TeamFields on Team { ` func teamUpdate( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, id string, name string, description string, @@ -14577,7 +15895,7 @@ func teamUpdate( defaultMemberRole string, membersCanCreatePipelines bool, ) (*teamUpdateResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "teamUpdate", Query: teamUpdate_Operation, Variables: &__teamUpdateInput{ @@ -14590,18 +15908,18 @@ func teamUpdate( MembersCanCreatePipelines: membersCanCreatePipelines, }, } - var err error + var err_ error - var data teamUpdateResponse - resp := &graphql.Response{Data: &data} + var data_ teamUpdateResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by updateCluster. @@ -14631,8 +15949,8 @@ fragment ClusterFields on Cluster { ` func updateCluster( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, organizationId string, id string, name string, @@ -14640,7 +15958,7 @@ func updateCluster( emoji *string, color *string, ) (*updateClusterResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "updateCluster", Query: updateCluster_Operation, Variables: &__updateClusterInput{ @@ -14652,18 +15970,18 @@ func updateCluster( Color: color, }, } - var err error + var err_ error - var data updateClusterResponse - resp := &graphql.Response{Data: &data} + var data_ updateClusterResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by updateClusterAgentToken. @@ -14688,14 +16006,14 @@ fragment ClusterAgentTokenValues on ClusterToken { ` func updateClusterAgentToken( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, organizationId string, id string, description string, allowedIpAddresses string, ) (*updateClusterAgentTokenResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "updateClusterAgentToken", Query: updateClusterAgentToken_Operation, Variables: &__updateClusterAgentTokenInput{ @@ -14705,18 +16023,18 @@ func updateClusterAgentToken( AllowedIpAddresses: allowedIpAddresses, }, } - var err error + var err_ error - var data updateClusterAgentTokenResponse - resp := &graphql.Response{Data: &data} + var data_ updateClusterAgentTokenResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by updateClusterQueue. @@ -14741,13 +16059,13 @@ fragment ClusterQueueValues on ClusterQueue { ` func updateClusterQueue( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, organizationId string, id string, description *string, ) (*updateClusterQueueResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "updateClusterQueue", Query: updateClusterQueue_Operation, Variables: &__updateClusterQueueInput{ @@ -14756,18 +16074,18 @@ func updateClusterQueue( Description: description, }, } - var err error + var err_ error - var data updateClusterQueueResponse - resp := &graphql.Response{Data: &data} + var data_ updateClusterQueueResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by updatePipeline. @@ -14835,29 +16153,29 @@ fragment PipelineTeam on TeamPipelineConnection { ` func updatePipeline( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, input PipelineUpdateInput, ) (*updatePipelineResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "updatePipeline", Query: updatePipeline_Operation, Variables: &__updatePipelineInput{ Input: input, }, } - var err error + var err_ error - var data updatePipelineResponse - resp := &graphql.Response{Data: &data} + var data_ updatePipelineResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by updatePipelineSchedule. @@ -14886,29 +16204,29 @@ fragment PipelineScheduleValues on PipelineSchedule { ` func updatePipelineSchedule( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, input PipelineScheduleUpdateInput, ) (*updatePipelineScheduleResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "updatePipelineSchedule", Query: updatePipelineSchedule_Operation, Variables: &__updatePipelineScheduleInput{ Input: input, }, } - var err error + var err_ error - var data updatePipelineScheduleResponse - resp := &graphql.Response{Data: &data} + var data_ updatePipelineScheduleResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by updatePipelineTemplate. @@ -14931,8 +16249,8 @@ fragment PipelineTemplateFields on PipelineTemplate { ` func updatePipelineTemplate( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, organizationId string, id string, name string, @@ -14940,7 +16258,7 @@ func updatePipelineTemplate( description string, available bool, ) (*updatePipelineTemplateResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "updatePipelineTemplate", Query: updatePipelineTemplate_Operation, Variables: &__updatePipelineTemplateInput{ @@ -14952,18 +16270,18 @@ func updatePipelineTemplate( Available: available, }, } - var err error + var err_ error - var data updatePipelineTemplateResponse - resp := &graphql.Response{Data: &data} + var data_ updatePipelineTemplateResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by updateTeamMember. @@ -14989,12 +16307,12 @@ fragment TeamMemberFields on TeamMember { ` func updateTeamMember( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, id string, role string, ) (*updateTeamMemberResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "updateTeamMember", Query: updateTeamMember_Operation, Variables: &__updateTeamMemberInput{ @@ -15002,18 +16320,18 @@ func updateTeamMember( Role: role, }, } - var err error + var err_ error - var data updateTeamMemberResponse - resp := &graphql.Response{Data: &data} + var data_ updateTeamMemberResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by updateTeamPipeline. @@ -15039,12 +16357,12 @@ fragment TeamPipelineFields on TeamPipeline { ` func updateTeamPipeline( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, id string, accessLevel PipelineAccessLevels, ) (*updateTeamPipelineResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "updateTeamPipeline", Query: updateTeamPipeline_Operation, Variables: &__updateTeamPipelineInput{ @@ -15052,18 +16370,18 @@ func updateTeamPipeline( AccessLevel: accessLevel, }, } - var err error + var err_ error - var data updateTeamPipelineResponse - resp := &graphql.Response{Data: &data} + var data_ updateTeamPipelineResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by updateTestSuiteTeam. @@ -15080,12 +16398,12 @@ mutation updateTestSuiteTeam ($id: ID!, $accessLevel: SuiteAccessLevels!) { ` func updateTestSuiteTeam( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, id string, accessLevel SuiteAccessLevels, ) (*updateTestSuiteTeamResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "updateTestSuiteTeam", Query: updateTestSuiteTeam_Operation, Variables: &__updateTestSuiteTeamInput{ @@ -15093,18 +16411,18 @@ func updateTestSuiteTeam( AccessLevel: accessLevel, }, } - var err error + var err_ error - var data updateTestSuiteTeamResponse - resp := &graphql.Response{Data: &data} + var data_ updateTestSuiteTeamResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } // The query or mutation executed by upsertBanner. @@ -15125,12 +16443,12 @@ fragment OrganizationBannerFields on OrganizationBanner { ` func upsertBanner( - ctx context.Context, - client graphql.Client, + ctx_ context.Context, + client_ graphql.Client, organizationId string, message string, ) (*upsertBannerResponse, error) { - req := &graphql.Request{ + req_ := &graphql.Request{ OpName: "upsertBanner", Query: upsertBanner_Operation, Variables: &__upsertBannerInput{ @@ -15138,16 +16456,16 @@ func upsertBanner( Message: message, }, } - var err error + var err_ error - var data upsertBannerResponse - resp := &graphql.Response{Data: &data} + var data_ upsertBannerResponse + resp_ := &graphql.Response{Data: &data_} - err = client.MakeRequest( - ctx, - req, - resp, + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, ) - return &data, err + return &data_, err_ } diff --git a/buildkite/graphql/node.graphql b/buildkite/graphql/node.graphql index 3003f602..8d019b51 100644 --- a/buildkite/graphql/node.graphql +++ b/buildkite/graphql/node.graphql @@ -8,6 +8,9 @@ query getNode( ... on PipelineTemplate { ...PipelineTemplateFields } + ... on Rule { + ...OrganizationRuleFields + } ... on TeamMember { ...TeamMemberFields } diff --git a/buildkite/graphql/organization_rule.graphql b/buildkite/graphql/organization_rule.graphql new file mode 100644 index 00000000..bf17a6ef --- /dev/null +++ b/buildkite/graphql/organization_rule.graphql @@ -0,0 +1,77 @@ +fragment OrganizationRuleFields on Rule { + id + uuid + # @genqlient(pointer: true) + description + document + type + sourceType + targetType + effect + action + source { + ... on Pipeline { + uuid + } + } + target { + ... on Pipeline { + uuid + } + } +} + +query getOrganizationRules( + $orgSlug: ID!, + # @genqlient(pointer: true) + $cursor: String +) { + organization(slug: $orgSlug) { + rules(first: 50, after: $cursor) { + pageInfo { + endCursor + hasNextPage + } + edges { + node { + ...OrganizationRuleFields + } + } + } + } +} + +mutation createOrganizationRule( + $organizationId: ID!, + # @genqlient(pointer: true) + $description: String, + $ruleType: String!, + $value: JSON!, +) { + ruleCreate( + input: { + organizationId: $organizationId + description: $description + type: $ruleType, + value: $value + } + ) { + rule { + ...OrganizationRuleFields + } + } +} + +mutation deleteOrganizationRule( + $organizationId: ID!, + $id: ID!, +) { + ruleDelete( + input: { + organizationId: $organizationId + id: $id, + } + ) { + clientMutationId + } +} diff --git a/buildkite/provider.go b/buildkite/provider.go index 021f68ac..5dcc64cc 100644 --- a/buildkite/provider.go +++ b/buildkite/provider.go @@ -111,6 +111,7 @@ func (*terraformProvider) DataSources(context.Context) []func() datasource.DataS newClusterDatasource, newMetaDatasource, newOrganizationDatasource, + newOrganizationRuleDatasource, newPipelineDatasource, newPipelineTemplateDatasource, newSignedPipelineStepsDataSource, @@ -132,6 +133,7 @@ func (tf *terraformProvider) Resources(context.Context) []func() resource.Resour newClusterResource, newDefaultQueueClusterResource, newOrganizationBannerResource, + newOrganizationRuleResource, newOrganizationResource, newPipelineScheduleResource, newPipelineTeamResource, diff --git a/buildkite/resource_organization_rule.go b/buildkite/resource_organization_rule.go new file mode 100644 index 00000000..4e2c3ebf --- /dev/null +++ b/buildkite/resource_organization_rule.go @@ -0,0 +1,469 @@ +package buildkite + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "log" + + "github.com/MakeNowJust/heredoc" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + resource_schema "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" +) + +type organizationRuleResourceModel struct { + ID types.String `tfsdk:"id"` + UUID types.String `tfsdk:"uuid"` + Description types.String `tfsdk:"description"` + Type types.String `tfsdk:"type"` + Value types.String `tfsdk:"value"` + SourceType types.String `tfsdk:"source_type"` + SourceUUID types.String `tfsdk:"source_uuid"` + TargetType types.String `tfsdk:"target_type"` + TargetUUID types.String `tfsdk:"target_uuid"` + Effect types.String `tfsdk:"effect"` + Action types.String `tfsdk:"action"` +} + +type ruleDocument struct { + Rule string `json:"rule"` + Value json.RawMessage `json:"value"` +} + +type ruleValue struct { + Source string `json:"source_pipeline"` + Target string `json:"target_pipeline"` + Conditions []string `json:"conditions"` +} + +type organizationRuleResource struct { + client *Client +} + +func newOrganizationRuleResource() resource.Resource { + return &organizationRuleResource{} +} + +func (organizationRuleResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_organization_rule" +} + +func (or *organizationRuleResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + or.client = req.ProviderData.(*Client) +} + +func (organizationRuleResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = resource_schema.Schema{ + MarkdownDescription: heredoc.Doc(` + An Organization Rule allows specifying explicit rules between two Buildkite resources and the desired effect/action. + + More information on organization rules can be found in the [documentation](https://buildkite.com/docs/pipelines/rules). + `), + Attributes: map[string]resource_schema.Attribute{ + "id": resource_schema.StringAttribute{ + Computed: true, + MarkdownDescription: "The GraphQL ID of the organization rule.", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "uuid": resource_schema.StringAttribute{ + Computed: true, + MarkdownDescription: "The UUID of the organization rule.", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "description": resource_schema.StringAttribute{ + Optional: true, + MarkdownDescription: "The description of the organization rule. ", + }, + "type": resource_schema.StringAttribute{ + Required: true, + MarkdownDescription: "The type of organization rule. ", + }, + "value": resource_schema.StringAttribute{ + Required: true, + MarkdownDescription: "The JSON document that this organization rule implements. ", + }, + "source_type": resource_schema.StringAttribute{ + Computed: true, + MarkdownDescription: "The source resource type that this organization rule allows or denies to invoke its defined action. ", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "source_uuid": resource_schema.StringAttribute{ + Computed: true, + MarkdownDescription: "The UUID of the resource that this organization rule allows or denies invocating its defined action. ", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "target_type": resource_schema.StringAttribute{ + Computed: true, + MarkdownDescription: "The target resource type that this organization rule allows or denies the source to respective action. ", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "target_uuid": resource_schema.StringAttribute{ + Computed: true, + MarkdownDescription: "The UUID of the target resource that this organization rule allows or denies invocation its respective action. ", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "effect": resource_schema.StringAttribute{ + Computed: true, + MarkdownDescription: "Whether this organization rule allows or denies the action to take place between source and target resources. ", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "action": resource_schema.StringAttribute{ + Computed: true, + MarkdownDescription: "The action defined between source and target resources. ", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + }, + } +} + +func (or *organizationRuleResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + var plan, state organizationRuleResourceModel + var plannedValue ruleValue + + diags := req.Plan.Get(ctx, &plan) + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + timeout, diags := or.client.timeouts.Create(ctx, DefaultTimeout) + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + // Unmarshall the plan's value into a ruleValue struct instance + err := json.Unmarshal([]byte(plan.Value.ValueString()), &plannedValue) + + if err != nil { + resp.Diagnostics.AddError( + "Unable to create organization rule", + fmt.Sprintf("Unable to create organization rule: %s ", err.Error()), + ) + return + } + + // Confirm that both the source|target pipelines specified in the value attribute of a buildkite_organization_rule are valid UUID strings. + // If either is not a valid UUID and not empty, the provider will return an error stating this and abort creation of the rule. + if !isUUID(plannedValue.Source) && len(plannedValue.Source) > 0 { + resp.Diagnostics.AddError( + "Unable to create organization rule", + fmt.Sprintf("%s: source_pipeline is an invalid UUID.", plan.Type.ValueString()), + ) + return + } else if !isUUID(plannedValue.Target) && len(plannedValue.Target) > 0 { + resp.Diagnostics.AddError( + "Unable to create organization rule", + fmt.Sprintf("%s: target_pipeline is an invalid UUID.", plan.Type.ValueString()), + ) + return + } + + var r *createOrganizationRuleResponse + err = retry.RetryContext(ctx, timeout, func() *retry.RetryError { + org, err := or.client.GetOrganizationID() + if err == nil { + log.Printf("Creating organization rule ...") + r, err = createOrganizationRule( + ctx, + or.client.genqlient, + *org, + plan.Description.ValueStringPointer(), + plan.Type.ValueString(), + plan.Value.ValueString(), + ) + } + + return retryContextError(err) + }) + + if err != nil { + resp.Diagnostics.AddError( + "Unable to create organization rule", + fmt.Sprintf("Unable to create organization rule: %s ", err.Error()), + ) + return + } + + // Obtain the source and target UUIDs of the created organization rule based on the API response. + sourceUUID, targetUUID, err := obtainCreationUUIDs(r) + + if err != nil { + resp.Diagnostics.AddError( + "Unable to create organization rule", + fmt.Sprintf("Unable to obtain source/target UUIDs: %s ", err.Error()), + ) + return + } + + // Obtain the sorted value JSON from the API response (document field in RuleCreatePayload's rule) + value, err := obtainValueJSON(r.RuleCreate.Rule.Document) + + if err != nil { + resp.Diagnostics.AddError( + "Unable to create organization rule", + fmt.Sprintf("Unable to create organmization rule: %s", err.Error()), + ) + return + } + + // Update organization rule model and set in state + updateOrganizatonRuleCreateState(&state, *r, *sourceUUID, *targetUUID, *value) + resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) +} + +func (or *organizationRuleResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + var state organizationRuleResourceModel + + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + + if resp.Diagnostics.HasError() { + return + } + + timeouts, diags := or.client.timeouts.Read(ctx, DefaultTimeout) + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + var apiResponse *getNodeResponse + err := retry.RetryContext(ctx, timeouts, func() *retry.RetryError { + var err error + + log.Printf("Reading organization rule with ID %s ...", state.ID.ValueString()) + apiResponse, err = getNode(ctx, or.client.genqlient, state.ID.ValueString()) + + return retryContextError(err) + }) + + if err != nil { + resp.Diagnostics.AddError( + "Unable to read organization rule", + fmt.Sprintf("Unable to read organmization rule: %s", err.Error()), + ) + return + } + + // Convert fron Node to getNodeNodeRule type + if organizationRule, ok := apiResponse.GetNode().(*getNodeNodeRule); ok { + if organizationRule == nil { + resp.Diagnostics.AddError( + "Unable to get organization rule", + "Error getting organization rule: nil response", + ) + return + } + + // Get the returned rule's sorted value JSON object from its Document field + value, err := obtainValueJSON(organizationRule.Document) + + if err != nil { + resp.Diagnostics.AddError( + "Unable to read organization rule", + fmt.Sprintf("Unable to read organmization rule: %s", err.Error()), + ) + return + } + + // Update organization rule model and set in state + updateOrganizatonRuleReadState(&state, *organizationRule, *value) + resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) + } else { + // Remove from state if not found{{}} + resp.Diagnostics.AddWarning("Organization rule not found", "Removing from state") + resp.State.RemoveResource(ctx) + return + } +} + +func (or *organizationRuleResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) +} + +func (or *organizationRuleResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + resp.Diagnostics.AddError("Cannot update an organization rule", "An existing rule must be deleted/re-created") + panic("cannot update an organization rule") +} + +func (or *organizationRuleResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + var state organizationRuleResourceModel + diags := req.State.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + timeout, diags := or.client.timeouts.Delete(ctx, DefaultTimeout) + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + err := retry.RetryContext(ctx, timeout, func() *retry.RetryError { + org, err := or.client.GetOrganizationID() + if err == nil { + log.Printf("Deleting organization rule with ID %s ...", state.ID.ValueString()) + _, err = deleteOrganizationRule( + ctx, + or.client.genqlient, + *org, + state.ID.ValueString(), + ) + } + + return retryContextError(err) + }) + + if err != nil { + resp.Diagnostics.AddError( + "Unable to delete organization rule", + fmt.Sprintf("Unable to delete organization rule: %s", err.Error()), + ) + return + } +} + +func obtainCreationUUIDs(r *createOrganizationRuleResponse) (*string, *string, error) { + var sourceUUID, targetUUID string + + // The provider will try and determine the source UUID based on type that is returned in the *createOrganizationRuleResponse + // It will switch based on the SourceType returned in the response and extract the UUID of the respective source based on this. + // Otherwise, it will create and throw an error stating that it cannot obtain the source type from the returned API response. + // In all cases exhausted, it'll throw an error stating that the rule's source type can't be determined after creation. + + switch r.RuleCreate.Rule.SourceType { + case "PIPELINE": + if ruleCreateSourcePipeline, ok := r.RuleCreate.Rule.Source.(*OrganizationRuleFieldsSourcePipeline); ok { + sourceUUID = ruleCreateSourcePipeline.Uuid + } else { + return nil, nil, errors.New("Error obtaining source type upon creating the organization rule.") + } + default: + // We can't determine the source type - return an error + return nil, nil, errors.New("Error determining source type upon creating the organization rule.") + } + + // Now, like above - the provider will try and determine the target UUID based on the *createOrganizationRuleResponse. It will + // switch based on the TargetType returned in the response and extract the UUID of the respective source based on this. Otherwise, + // it will create and throw an error stating that it cannot obtain the source type from the returned API response. + // In all cases exhausted, it'll throw an error stating that the rule's target type can't be determined after creation. + + switch r.RuleCreate.Rule.TargetType { + case "PIPELINE": + if ruleCreateTargetPipeline, ok := r.RuleCreate.Rule.Target.(*OrganizationRuleFieldsTargetPipeline); ok { + targetUUID = ruleCreateTargetPipeline.Uuid + } else { + return nil, nil, errors.New("Error obtaining target type upon creating the organization rule.") + } + default: + // We can't determine the target type - return an error + return nil, nil, errors.New("Error determining target type upon creating the organization rule.") + } + + return &sourceUUID, &targetUUID, nil +} + +func obtainReadUUIDs(nr getNodeNodeRule) (string, string) { + var sourceUUID, targetUUID string + + switch nr.SourceType { + case "PIPELINE": + sourceUUID = nr.Source.(*OrganizationRuleFieldsSourcePipeline).Uuid + } + + switch nr.TargetType { + case "PIPELINE": + targetUUID = nr.Target.(*OrganizationRuleFieldsTargetPipeline).Uuid + } + + return sourceUUID, targetUUID +} + +func obtainValueJSON(document string) (*string, error) { + var rd ruleDocument + valueMap := make(map[string]interface{}) + + // Unmarshall the API obtained document into a ruleDocument struct instance + err := json.Unmarshal([]byte(document), &rd) + if err != nil { + return nil, errors.New("Error unmarshalling the organization rule's JSON document.") + } + + // Unmarshall the ruleDocument's value into a [string]interface{} map + err = json.Unmarshal([]byte(string(rd.Value)), &valueMap) + if err != nil { + return nil, errors.New("Error unmarshalling the organization rule's value.") + } + + // Marshall the value map back into a byte slice (sorted) + valueMarshalled, err := json.Marshal(valueMap) + if err != nil { + return nil, errors.New("Error marshalling the organization rule's sorted value JSON.") + } + + // Convert and return sorted and serialized value string + value := string(valueMarshalled) + return &value, nil +} + +func updateOrganizatonRuleCreateState(or *organizationRuleResourceModel, ruleCreate createOrganizationRuleResponse, sourceUUID, targetUUID, value string) { + or.ID = types.StringValue(ruleCreate.RuleCreate.Rule.Id) + or.UUID = types.StringValue(ruleCreate.RuleCreate.Rule.Uuid) + or.Description = types.StringPointerValue(ruleCreate.RuleCreate.Rule.Description) + or.Type = types.StringValue(ruleCreate.RuleCreate.Rule.Type) + or.Value = types.StringValue(value) + or.SourceType = types.StringValue(string(ruleCreate.RuleCreate.Rule.SourceType)) + or.SourceUUID = types.StringValue(sourceUUID) + or.TargetType = types.StringValue(string(ruleCreate.RuleCreate.Rule.TargetType)) + or.TargetUUID = types.StringValue(targetUUID) + or.Effect = types.StringValue(string(ruleCreate.RuleCreate.Rule.Effect)) + or.Action = types.StringValue(string(ruleCreate.RuleCreate.Rule.Action)) +} + +func updateOrganizatonRuleReadState(or *organizationRuleResourceModel, orn getNodeNodeRule, value string) { + sourceUUID, targetUUID := obtainReadUUIDs(orn) + + or.ID = types.StringValue(orn.Id) + or.UUID = types.StringValue(orn.Uuid) + or.Description = types.StringPointerValue(orn.Description) + or.Type = types.StringValue(orn.Type) + or.Value = types.StringValue(value) + or.SourceType = types.StringValue(string(orn.SourceType)) + or.SourceUUID = types.StringValue(sourceUUID) + or.TargetType = types.StringValue(string(orn.TargetType)) + or.TargetUUID = types.StringValue(targetUUID) + or.Effect = types.StringValue(string(orn.Effect)) + or.Action = types.StringValue(string(orn.Action)) +} diff --git a/buildkite/resource_organization_rule_test.go b/buildkite/resource_organization_rule_test.go new file mode 100644 index 00000000..59c8303e --- /dev/null +++ b/buildkite/resource_organization_rule_test.go @@ -0,0 +1,609 @@ +package buildkite + +import ( + "context" + "fmt" + "regexp" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" +) + +func TestAccBuildkiteOrganizationRuleResource(t *testing.T) { + ruleActions := []string{"trigger_build", "artifacts_read"} + + configRequired := func(fields ...string) string { + return fmt.Sprintf(` + provider "buildkite" { + timeouts = { + create = "10s" + read = "10s" + update = "10s" + delete = "10s" + } + } + + resource "buildkite_cluster" "cluster_source" { + name = "Cluster %s" + description = "A test cluster containing a source pipeline." + } + + resource "buildkite_cluster" "cluster_target" { + name = "Cluster %s" + description = "A test cluster containing a target pipeline for triggering builds." + } + + resource "buildkite_pipeline" "pipeline_source" { + depends_on = [buildkite_cluster.cluster_source] + name = "Pipeline %s" + repository = "https://github.com/buildkite/terraform-provider-buildkite.git" + cluster_id = buildkite_cluster.cluster_source.id + } + + resource "buildkite_pipeline" "pipeline_target" { + depends_on = [buildkite_cluster.cluster_target] + name = "Pipeline %s" + repository = "https://github.com/buildkite/terraform-provider-buildkite.git" + cluster_id = buildkite_cluster.cluster_target.id + } + + resource "buildkite_organization_rule" "%s_rule" { + depends_on = [ + buildkite_pipeline.pipeline_source, + buildkite_pipeline.pipeline_target + ] + type = "pipeline.%s.pipeline" + value = jsonencode({ + source_pipeline = buildkite_pipeline.pipeline_source.uuid + target_pipeline = buildkite_pipeline.pipeline_target.uuid + }) + } + + `, fields[0], fields[1], fields[0], fields[1], fields[2], fields[2]) + } + + configAll := func(fields ...string) string { + return fmt.Sprintf(` + provider "buildkite" { + timeouts = { + create = "10s" + read = "10s" + update = "10s" + delete = "10s" + } + } + + resource "buildkite_cluster" "cluster_source" { + name = "Cluster %s" + description = "A test cluster containing a source pipeline." + } + + resource "buildkite_cluster" "cluster_target" { + name = "Cluster %s" + description = "A test cluster containing a target pipeline for triggering builds." + } + + resource "buildkite_pipeline" "pipeline_source" { + depends_on = [buildkite_cluster.cluster_source] + name = "Pipeline %s" + repository = "https://github.com/buildkite/terraform-provider-buildkite.git" + cluster_id = buildkite_cluster.cluster_source.id + } + + resource "buildkite_pipeline" "pipeline_target" { + depends_on = [buildkite_cluster.cluster_target] + name = "Pipeline %s" + repository = "https://github.com/buildkite/terraform-provider-buildkite.git" + cluster_id = buildkite_cluster.cluster_target.id + } + + resource "buildkite_organization_rule" "%s_rule" { + depends_on = [ + buildkite_pipeline.pipeline_source, + buildkite_pipeline.pipeline_target + ] + type = "pipeline.%s.pipeline" + description = "A pipeline.%s.pipeline rule" + value = jsonencode({ + source_pipeline = buildkite_pipeline.pipeline_source.uuid + target_pipeline = buildkite_pipeline.pipeline_target.uuid + conditions = [ + "source.build.creator.teams includes 'deploy'", + "source.build.branch == 'main'" + ] + }) + } + + `, fields[0], fields[1], fields[0], fields[1], fields[2], fields[2], fields[2]) + } + + configNonExistentAction := func(fields ...string) string { + return fmt.Sprintf(` + provider "buildkite" { + timeouts = { + create = "10s" + read = "10s" + update = "10s" + delete = "10s" + } + } + + resource "buildkite_pipeline" "pipeline_source" { + name = "Pipeline %s" + repository = "https://github.com/buildkite/terraform-provider-buildkite.git" + } + + resource "buildkite_pipeline" "pipeline_target" { + name = "Pipeline %s" + repository = "https://github.com/buildkite/terraform-provider-buildkite.git" + } + + resource "buildkite_organization_rule" "non_existent_action_rule" { + depends_on = [ + buildkite_pipeline.pipeline_source, + buildkite_pipeline.pipeline_target + ] + type = "pipeline.non_existent_action.pipeline" + value = jsonencode({ + source_pipeline = buildkite_pipeline.pipeline_target.uuid + target_pipeline = buildkite_pipeline.pipeline_source.uuid + }) + } + + `, fields[0], fields[1]) + } + + configInvalidConditional := func(fields ...string) string { + return fmt.Sprintf(` + provider "buildkite" { + timeouts = { + create = "10s" + read = "10s" + update = "10s" + delete = "10s" + } + } + + resource "buildkite_pipeline" "pipeline_source" { + name = "Pipeline %s" + repository = "https://github.com/buildkite/terraform-provider-buildkite.git" + } + + resource "buildkite_pipeline" "pipeline_target" { + name = "Pipeline %s" + repository = "https://github.com/buildkite/terraform-provider-buildkite.git" + } + + resource "buildkite_organization_rule" "non_existent_condition" { + depends_on = [ + buildkite_pipeline.pipeline_source, + buildkite_pipeline.pipeline_target + ] + type = "pipeline.trigger_build.pipeline" + value = jsonencode({ + source_pipeline = buildkite_pipeline.pipeline_target.uuid + target_pipeline = buildkite_pipeline.pipeline_source.uuid + conditions = [ + "source.nonexistent_condition includes 'idontexist'" + ] + }) + } + + `, fields[0], fields[1]) + } + + configNoSourcePipelineUUID := func(targetName string) string { + return fmt.Sprintf(` + provider "buildkite" { + timeouts = { + create = "10s" + read = "10s" + update = "10s" + delete = "10s" + } + } + + resource "buildkite_pipeline" "pipeline_target" { + name = "Pipeline %s" + repository = "https://github.com/buildkite/terraform-provider-buildkite.git" + } + + resource "buildkite_organization_rule" "no_source_pipeline_rule" { + depends_on = [buildkite_pipeline.pipeline_target] + type = "pipeline.trigger_build.pipeline" + value = jsonencode({ + target_pipeline = buildkite_pipeline.pipeline_target.uuid + }) + } + + `, targetName) + } + + configNoTargetPipelineUUID := func(sourceName string) string { + return fmt.Sprintf(` + provider "buildkite" { + timeouts = { + create = "10s" + read = "10s" + update = "10s" + delete = "10s" + } + } + + resource "buildkite_pipeline" "pipeline_source" { + name = "Pipeline %s" + repository = "https://github.com/buildkite/terraform-provider-buildkite.git" + } + + resource "buildkite_organization_rule" "no_target_pipeline_rule" { + depends_on = [buildkite_pipeline.pipeline_source] + type = "pipeline.trigger_build.pipeline" + value = jsonencode({ + source_pipeline = buildkite_pipeline.pipeline_source.uuid + }) + } + + `, sourceName) + } + + configSourceUUIDInvalid := func(targetName string) string { + return fmt.Sprintf(` + provider "buildkite" { + timeouts = { + create = "10s" + read = "10s" + update = "10s" + delete = "10s" + } + } + + resource "buildkite_pipeline" "pipeline_target" { + name = "Pipeline %s" + repository = "https://github.com/buildkite/terraform-provider-buildkite.git" + } + + resource "buildkite_organization_rule" "rule_without_a_source" { + depends_on = [buildkite_pipeline.pipeline_target] + type = "pipeline.trigger_build.pipeline" + value = jsonencode({ + source_pipeline = "non_existent" + target_pipeline = buildkite_pipeline.pipeline_target.uuid + }) + } + + `, targetName) + } + + configTargetUUIDInvalid := func(sourceName string) string { + return fmt.Sprintf(` + provider "buildkite" { + timeouts = { + create = "10s" + read = "10s" + update = "10s" + delete = "10s" + } + } + + resource "buildkite_pipeline" "pipeline_source" { + name = "Pipeline %s" + repository = "https://github.com/buildkite/terraform-provider-buildkite.git" + } + + resource "buildkite_organization_rule" "rule_without_a_target" { + depends_on = [buildkite_pipeline.pipeline_source] + type = "pipeline.trigger_build.pipeline" + value = jsonencode({ + source_pipeline = buildkite_pipeline.pipeline_source.uuid + target_pipeline = "non-existent" + }) + } + + `, sourceName) + } + + for _, action := range ruleActions { + t.Run(fmt.Sprintf("creates a pipeline.%s.pipeline organization rule with required attributes", action), func(t *testing.T) { + randNameOne := acctest.RandString(12) + randNameTwo := acctest.RandString(12) + var orr organizationRuleResourceModel + + check := resource.ComposeAggregateTestCheckFunc( + // Confirm the organization rule exists + testAccCheckOrganizationRuleExists(&orr, fmt.Sprintf("buildkite_organization_rule.%s_rule", action)), + // Confirm the organization rule has the correct values in Buildkite's system + testAccCheckOrganizationRuleRemoteValues(&orr, "PIPELINE", "PIPELINE", strings.ToUpper(action), "ALLOW"), + // Check the organization rule resource's attributes are set in state + resource.TestCheckResourceAttrSet(fmt.Sprintf("buildkite_organization_rule.%s_rule", action), "id"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("buildkite_organization_rule.%s_rule", action), "uuid"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("buildkite_organization_rule.%s_rule", action), "type"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("buildkite_organization_rule.%s_rule", action), "value"), + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: protoV6ProviderFactories(), + CheckDestroy: testAccCheckOrganizationRuleDestroy, + Steps: []resource.TestStep{ + { + Config: configRequired(randNameOne, randNameTwo, action), + Check: check, + }, + }, + }) + }) + + t.Run(fmt.Sprintf("creates a pipeline.%s.pipeline organization rule with all attributes", action), func(t *testing.T) { + randNameOne := acctest.RandString(12) + randNameTwo := acctest.RandString(12) + var orr organizationRuleResourceModel + + check := resource.ComposeAggregateTestCheckFunc( + // Confirm the organization rule exists + testAccCheckOrganizationRuleExists(&orr, fmt.Sprintf("buildkite_organization_rule.%s_rule", action)), + // Confirm the organization rule has the correct values in Buildkite's system + testAccCheckOrganizationRuleRemoteValues(&orr, "PIPELINE", "PIPELINE", strings.ToUpper(action), "ALLOW"), + // Check the organization rule resource's attributes are set in state + resource.TestCheckResourceAttrSet(fmt.Sprintf("buildkite_organization_rule.%s_rule", action), "id"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("buildkite_organization_rule.%s_rule", action), "uuid"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("buildkite_organization_rule.%s_rule", action), "type"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("buildkite_organization_rule.%s_rule", action), "description"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("buildkite_organization_rule.%s_rule", action), "value"), + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: protoV6ProviderFactories(), + CheckDestroy: testAccCheckOrganizationRuleDestroy, + Steps: []resource.TestStep{ + { + Config: configAll(randNameOne, randNameTwo, action), + Check: check, + }, + }, + }) + }) + + t.Run(fmt.Sprintf("imports a pipeline.%s.pipeline organization rule with required attributes", action), func(t *testing.T) { + randNameOne := acctest.RandString(12) + randNameTwo := acctest.RandString(12) + var orr organizationRuleResourceModel + + check := resource.ComposeAggregateTestCheckFunc( + // Confirm the organization rule exists + testAccCheckOrganizationRuleExists(&orr, fmt.Sprintf("buildkite_organization_rule.%s_rule", action)), + // Confirm the organization rule has the correct values in Buildkite's system + testAccCheckOrganizationRuleRemoteValues(&orr, "PIPELINE", "PIPELINE", strings.ToUpper(action), "ALLOW"), + // Check the organization rule resource's attributes are set in state + resource.TestCheckResourceAttrSet(fmt.Sprintf("buildkite_organization_rule.%s_rule", action), "id"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("buildkite_organization_rule.%s_rule", action), "uuid"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("buildkite_organization_rule.%s_rule", action), "type"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("buildkite_organization_rule.%s_rule", action), "value"), + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: protoV6ProviderFactories(), + CheckDestroy: testAccCheckOrganizationRuleDestroy, + Steps: []resource.TestStep{ + { + Config: configRequired(randNameOne, randNameTwo, action), + Check: check, + }, + { + ResourceName: fmt.Sprintf("buildkite_organization_rule.%s_rule", action), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) + }) + + t.Run(fmt.Sprintf("imports a pipeline.%s.pipeline organization rule with all attributes", action), func(t *testing.T) { + randNameOne := acctest.RandString(12) + randNameTwo := acctest.RandString(12) + var orr organizationRuleResourceModel + + check := resource.ComposeAggregateTestCheckFunc( + // Confirm the organization rule exists + testAccCheckOrganizationRuleExists(&orr, fmt.Sprintf("buildkite_organization_rule.%s_rule", action)), + // Confirm the organization rule has the correct values in Buildkite's system + testAccCheckOrganizationRuleRemoteValues(&orr, "PIPELINE", "PIPELINE", strings.ToUpper(action), "ALLOW"), + // Check the organization rule resource's attributes are set in state + resource.TestCheckResourceAttrSet(fmt.Sprintf("buildkite_organization_rule.%s_rule", action), "id"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("buildkite_organization_rule.%s_rule", action), "uuid"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("buildkite_organization_rule.%s_rule", action), "type"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("buildkite_organization_rule.%s_rule", action), "description"), + resource.TestCheckResourceAttrSet(fmt.Sprintf("buildkite_organization_rule.%s_rule", action), "value"), + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: protoV6ProviderFactories(), + CheckDestroy: testAccCheckOrganizationRuleDestroy, + Steps: []resource.TestStep{ + { + Config: configAll(randNameOne, randNameTwo, action), + Check: check, + }, + { + ResourceName: fmt.Sprintf("buildkite_organization_rule.%s_rule", action), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) + }) + } + + t.Run("errors when an organization rule is specified with an unknown action", func(t *testing.T) { + randNameOne := acctest.RandString(12) + randNameTwo := acctest.RandString(12) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: protoV6ProviderFactories(), + CheckDestroy: testAccCheckOrganizationRuleDestroy, + Steps: []resource.TestStep{ + { + Config: configNonExistentAction(randNameOne, randNameTwo), + ExpectError: regexp.MustCompile("input: Rule type is unknown"), + }, + }, + }) + }) + + t.Run("errors when an organization rule is specified with an invalid conditional", func(t *testing.T) { + randNameOne := acctest.RandString(12) + randNameTwo := acctest.RandString(12) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: protoV6ProviderFactories(), + CheckDestroy: testAccCheckOrganizationRuleDestroy, + Steps: []resource.TestStep{ + { + Config: configInvalidConditional(randNameOne, randNameTwo), + ExpectError: regexp.MustCompile("conditional is invalid:\n`source.nonexistent_condition` is not a variable"), + }, + }, + }) + }) + + t.Run("errors when no source_pipeline key exists within an organization rule's value", func(t *testing.T) { + randName := acctest.RandString(12) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: protoV6ProviderFactories(), + CheckDestroy: testAccCheckOrganizationRuleDestroy, + Steps: []resource.TestStep{ + { + Config: configNoSourcePipelineUUID(randName), + ExpectError: regexp.MustCompile("pipeline.trigger_build.pipeline: missing source_pipeline"), + }, + }, + }) + }) + + t.Run("errors when no target_pipeline key exists within an organization rule's value", func(t *testing.T) { + randName := acctest.RandString(12) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: protoV6ProviderFactories(), + CheckDestroy: testAccCheckOrganizationRuleDestroy, + Steps: []resource.TestStep{ + { + Config: configNoTargetPipelineUUID(randName), + ExpectError: regexp.MustCompile("pipeline.trigger_build.pipeline: missing target_pipeline"), + }, + }, + }) + }) + + t.Run("errors when the pipeline defined in source_pipeline is an invalid uuid", func(t *testing.T) { + randName := acctest.RandString(12) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: protoV6ProviderFactories(), + CheckDestroy: testAccCheckOrganizationRuleDestroy, + Steps: []resource.TestStep{ + { + Config: configSourceUUIDInvalid(randName), + ExpectError: regexp.MustCompile("pipeline.trigger_build.pipeline: source_pipeline is an invalid UUID."), + }, + }, + }) + }) + + t.Run("errors when the pipeline defined in target_pipeline is an invalid uuid", func(t *testing.T) { + randName := acctest.RandString(12) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: protoV6ProviderFactories(), + CheckDestroy: testAccCheckOrganizationRuleDestroy, + Steps: []resource.TestStep{ + { + Config: configTargetUUIDInvalid(randName), + ExpectError: regexp.MustCompile("pipeline.trigger_build.pipeline: target_pipeline is an invalid UUID."), + }, + }, + }) + }) +} + +func testAccCheckOrganizationRuleExists(orr *organizationRuleResourceModel, name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[name] + + if !ok { + return fmt.Errorf("Not found in state: %s", name) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No ID is set in state") + } + + r, err := getNode(context.Background(), genqlientGraphql, rs.Primary.ID) + + if err != nil { + return err + } + + if organizationRule, ok := r.GetNode().(*getNodeNodeRule); ok { + if organizationRule == nil { + return fmt.Errorf("Organization rule not found: nil response") + } + value, err := obtainValueJSON(organizationRule.Document) + if err != nil { + return fmt.Errorf("Error constructing sorted value JSON to store in state") + } + updateOrganizatonRuleReadState(orr, *organizationRule, *value) + } + + return nil + } +} + +func testAccCheckOrganizationRuleRemoteValues(orr *organizationRuleResourceModel, sourceType, targetType, action, effect string) resource.TestCheckFunc { + return func(s *terraform.State) error { + if orr.SourceType.ValueString() != sourceType { + return fmt.Errorf("Remote organization rule source type (%s) doesn't match expected value (%s)", orr.SourceType, sourceType) + } + + if orr.TargetType.ValueString() != targetType { + return fmt.Errorf("Remote organization rule target type (%s) doesn't match expected value (%s)", orr.TargetType, targetType) + } + + if orr.Action.ValueString() != action { + return fmt.Errorf("Remote organization rule action (%s) doesn't match expected value (%s)", orr.Action, action) + } + + if orr.Effect.ValueString() != effect { + return fmt.Errorf("Remote organization rule effect (%s) doesn't match expected value (%s)", orr.Effect, effect) + } + + return nil + } +} + +func testAccCheckOrganizationRuleDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "buildkite_organization_rule" { + continue + } + + r, err := getNode(context.Background(), genqlientGraphql, rs.Primary.ID) + + if err != nil { + return err + } + + if organizationRule, ok := r.GetNode().(*getNodeNodeRule); ok { + if organizationRule != nil { + return fmt.Errorf("Organization rule still exists") + } + } + } + return nil +} diff --git a/buildkite/util.go b/buildkite/util.go index 646c4634..9478a5ec 100644 --- a/buildkite/util.go +++ b/buildkite/util.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "os" + "regexp" "strings" "github.com/hashicorp/terraform-plugin-framework/types" @@ -57,6 +58,11 @@ func GetTeamID(slug string, client *Client) (string, error) { return id, nil } +func isUUID(uuid string) bool { + r := regexp.MustCompile("^[a-f0-9]{8}(-[a-f0-9]{4}){3}-[a-f0-9]{12}$") + return r.MatchString(uuid) +} + func getenv(key string) string { val, ok := os.LookupEnv(key) if !ok { diff --git a/docs/data-sources/organization_rule.md b/docs/data-sources/organization_rule.md new file mode 100644 index 00000000..81c50924 --- /dev/null +++ b/docs/data-sources/organization_rule.md @@ -0,0 +1,49 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "buildkite_organization_rule Data Source - terraform-provider-buildkite" +subcategory: "" +description: |- + Use this data source to retrieve an organization rule by its ID. + More information on organization rules can be found in the documentation https://buildkite.com/docs/pipelines/rules. +--- + +# buildkite_organization_rule (Data Source) + +~> Rules is a feature that is currently in development and enabled on an opt-in basis for early access. To have this enabled for your organization for utilizing this data source, please reach out to Buildkite's [Support Team](https://buildkite.com/support). + +Use this data source to retrieve an organization rule by its ID. + +More information on organization rules can be found in the [documentation](https://buildkite.com/docs/pipelines/rules). + +## Example Usage + +```terraform +# Read an organization rule by its id +data "buildkite_organization_rule" "data_artifacts_read_dev_test" { + id = buildkite_organization_rule.artifacts_read_dev_test.id +} + +# Read an organization rule by its uuid +data "buildkite_organization_rule" "data_artifacts_read_test_dev" { + uuid = buildkite_organization_rule.artifacts_read_test_dev.uuid +} +``` + +## Schema + +### Optional + +- `id` (String) The GraphQL ID of the organization rule. +- `uuid` (String) The UUID of the organization rule. + +### Read-Only + +- `action` (String) The action defined between source and target resources. +- `description` (String) The description of the organization rule. +- `effect` (String) Whether this organization rule allows or denys the action to take place between source and target resources. +- `source_type` (String) The source resource type that this organization rule allows or denies to invoke its defined action. +- `source_uuid` (String) The UUID of the resource that this organization rule allows or denies invocating its defined action. +- `target_type` (String) The target resource type that this organization rule allows or denies the source to respective action. +- `target_uuid` (String) The UUID of the target resourcee that this organization rule allows or denies invocation its respective action. +- `type` (String) The type of organization rule. +- `value` (String) The JSON document that this organization rule implements. diff --git a/docs/resources/cluster_default_queue.md b/docs/resources/cluster_default_queue.md index 9bac6e46..2d9c427f 100644 --- a/docs/resources/cluster_default_queue.md +++ b/docs/resources/cluster_default_queue.md @@ -45,8 +45,8 @@ resource "buildkite_cluster_default_queue" "primary" { ### Read-Only - `id` (String) The GraphQL ID of the cluster. +- `key` (String) The Key for the cluster queue; its unique identifier - `uuid` (String) The UUID of the cluster. -- `key` (String) The key of the cluster queue. ## Import diff --git a/docs/resources/organization_rule.md b/docs/resources/organization_rule.md new file mode 100644 index 00000000..77df7a9c --- /dev/null +++ b/docs/resources/organization_rule.md @@ -0,0 +1,129 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "buildkite_organization_rule Resource - terraform-provider-buildkite" +subcategory: "" +description: |- + An Organization Rule allows specifying explicit rules between two Buildkite resources and the desired effect/action. + More information on organization rules can be found in the documentation https://buildkite.com/docs/pipelines/rules. +--- + +# buildkite_organization_rule (Resource) + +~> Rules is a feature that is currently in development and enabled on an opt-in basis for early access. To have this enabled for your organization for utilizing this resource, please reach out to Buildkite's [Support Team](https://buildkite.com/support). + +An Organization Rule allows specifying explicit rules between two Buildkite resources and the desired effect/action. + +More information on organization rules can be found in the [documentation](https://buildkite.com/docs/pipelines/rules). + +## Example Usage + +```terraform +# Creates a TRIGGER_BUILD organization rule with required attributes +resource "buildkite_organization_rule" "trigger_build_test_dev" { + type = "pipeline.trigger_build.pipeline" + value = jsonencode({ + source_pipeline = buildkite_pipeline.app_dev_deploy.uuid + target_pipeline = buildkite_pipeline.app_test_ci.uuid + }) +} + +# Creates a ARTIFACTS_READ organization rule with an optional description +resource "buildkite_organization_rule" "artifacts_read_test_dev" { + type = "pipeline.artifacts_read.pipeline" + description = "A rule to allow artifact reads by app_test_ci to app_dev_deploy" + value = jsonencode({ + source_pipeline = buildkite_pipeline.app_test_ci.uuid + target_pipeline = buildkite_pipeline.app_dev_deploy.uuid + }) +} + +# Creates a TRIGGER_BUILD organization rule with an optional description and conditions +resource "buildkite_organization_rule" "trigger_build_test_dev_cond" { + type = "pipeline.trigger_build.pipeline" + description = "A rule to allow app_dev_deploy to trigger app_test_ci builds with conditions" + value = jsonencode({ + source_pipeline = buildkite_pipeline.app_dev_deploy.uuid + target_pipeline = buildkite_pipeline.app_test_ci.uuid + conditions = [ + "source.build.creator.teams includes 'deploy'", + "source.build.branch == 'main'" + ] + }) +} +``` + +## Schema + +### Required + +- `type` (String) The type of organization rule. +- `value` (String) The JSON document that this organization rule implements. + +### Optional + +- `description` (String) The description of the organization rule. + +### Read-Only + +- `action` (String) The action defined between source and target resources. +- `effect` (String) Whether this organization rule allows or denies the action to take place between source and target resources. +- `id` (String) The GraphQL ID of the organization rule. +- `source_type` (String) The source resource type that this organization rule allows or denies to invoke its defined action. +- `source_uuid` (String) The UUID of the resource that this organization rule allows or denies invocating its defined action. +- `target_type` (String) The target resource type that this organization rule allows or denies the source to respective action. +- `target_uuid` (String) The UUID of the target resource that this organization rule allows or denies invocation its respective action. +- `uuid` (String) The UUID of the organization rule. + +## Import + +Import is supported using the following syntax: + +```shell +# import an organization rule resource using the rules GraphQL ID +# +# You can use this query to find the first 50 organiation rules (adjust for less or more): +# query getOrganizationRules { +# organization(slug: "ORGANIZATION_SLUG") { +# rules(first: 50) { +# edges{ +# node{ +# id +# sourceType +# targetType +# action +# } +# } +# } +# } +# } +# +# Depending on the speciific source/target, you're also able to filter on the source/target information +# query getOrganizationRules { +# organization(slug: "ORGANIZATION_SLUG") { +# rules(first: 50) { +# edges{ +# node{ +# id +# sourceType +# source { +# ... on Pipeline{ +# uuid +# name +# } +# } +# targetType +# target { +# ... on Pipeline{ +# uuid +# name +# } +# } +# action +# } +# } +# } +# } +# } + +terraform import buildkite_organization_rule.artifact_read UnVsZS0tLTAxOTE5NmU2LWNiNjctNzZiZi1iYzAyLTVhYzFiNzhhMWMyOA== +``` diff --git a/docs/resources/pipeline.md b/docs/resources/pipeline.md index 96425cb6..6b06a355 100644 --- a/docs/resources/pipeline.md +++ b/docs/resources/pipeline.md @@ -104,7 +104,7 @@ Optional: - `fork` will create builds when the GitHub repository is forked. - `none` will not create any builds based on GitHub activity. - -> `trigger_mode` is only valid if the pipeline uses a GitHub repository. + -> `trigger_mode` is only valid if the pipeline uses a GitHub repository. -> If not set, the default value is `code` and other provider settings defaults are applied. ## Import diff --git a/examples/data-sources/buildkite_organization_rule/data-source.tf b/examples/data-sources/buildkite_organization_rule/data-source.tf new file mode 100644 index 00000000..5b3aeef7 --- /dev/null +++ b/examples/data-sources/buildkite_organization_rule/data-source.tf @@ -0,0 +1,9 @@ +# Read an organization rule by its id +data "buildkite_organization_rule" "data_artifacts_read_dev_test" { + id = buildkite_organization_rule.artifacts_read_dev_test.id +} + +# Read an organization rule by its uuid +data "buildkite_organization_rule" "data_artifacts_read_test_dev" { + uuid = buildkite_organization_rule.artifacts_read_test_dev.uuid +} \ No newline at end of file diff --git a/examples/resources/buildkite_organization_rule/import.sh b/examples/resources/buildkite_organization_rule/import.sh new file mode 100644 index 00000000..43be3f3b --- /dev/null +++ b/examples/resources/buildkite_organization_rule/import.sh @@ -0,0 +1,47 @@ +# import an organization rule resource using the rules GraphQL ID +# +# You can use this query to find the first 50 organiation rules (adjust for less or more): +# query getOrganizationRules { +# organization(slug: "ORGANIZATION_SLUG") { +# rules(first: 50) { +# edges{ +# node{ +# id +# sourceType +# targetType +# action +# } +# } +# } +# } +# } +# +# Depending on the speciific source/target, you're also able to filter on the source/target information +# query getOrganizationRules { +# organization(slug: "ORGANIZATION_SLUG") { +# rules(first: 50) { +# edges{ +# node{ +# id +# sourceType +# source { +# ... on Pipeline{ +# uuid +# name +# } +# } +# targetType +# target { +# ... on Pipeline{ +# uuid +# name +# } +# } +# action +# } +# } +# } +# } +# } + +terraform import buildkite_organization_rule.artifact_read UnVsZS0tLTAxOTE5NmU2LWNiNjctNzZiZi1iYzAyLTVhYzFiNzhhMWMyOA== \ No newline at end of file diff --git a/examples/resources/buildkite_organization_rule/resource.tf b/examples/resources/buildkite_organization_rule/resource.tf new file mode 100644 index 00000000..f8a20ec8 --- /dev/null +++ b/examples/resources/buildkite_organization_rule/resource.tf @@ -0,0 +1,32 @@ +# Creates a TRIGGER_BUILD organization rule with required attributes +resource "buildkite_organization_rule" "trigger_build_test_dev" { + type = "pipeline.trigger_build.pipeline" + value = jsonencode({ + source_pipeline = buildkite_pipeline.app_dev_deploy.uuid + target_pipeline = buildkite_pipeline.app_test_ci.uuid + }) +} + +# Creates a ARTIFACTS_READ organization rule with an optional description +resource "buildkite_organization_rule" "artifacts_read_test_dev" { + type = "pipeline.artifacts_read.pipeline" + description = "A rule to allow artifact reads by app_test_ci to app_dev_deploy" + value = jsonencode({ + source_pipeline = buildkite_pipeline.app_test_ci.uuid + target_pipeline = buildkite_pipeline.app_dev_deploy.uuid + }) +} + +# Creates a TRIGGER_BUILD organization rule with an optional description and conditions +resource "buildkite_organization_rule" "trigger_build_test_dev_cond" { + type = "pipeline.trigger_build.pipeline" + description = "A rule to allow app_dev_deploy to trigger app_test_ci builds with conditions" + value = jsonencode({ + source_pipeline = buildkite_pipeline.app_dev_deploy.uuid + target_pipeline = buildkite_pipeline.app_test_ci.uuid + conditions = [ + "source.build.creator.teams includes 'deploy'", + "source.build.branch == 'main'" + ] + }) +} \ No newline at end of file diff --git a/genqlient.yaml b/genqlient.yaml index b17ef783..138b6c7f 100644 --- a/genqlient.yaml +++ b/genqlient.yaml @@ -6,6 +6,8 @@ operations: generated: buildkite/generated.go bindings: + JSON: + type: string YAML: type: string TeamPrivacy: diff --git a/schema.graphql b/schema.graphql index 23d14400..aeacdaf8 100644 --- a/schema.graphql +++ b/schema.graphql @@ -74,6 +74,7 @@ enum APIAccessTokenScopes { READ_PIPELINE_TEMPLATES READ_PIPELINES READ_REGISTRIES + READ_RULES READ_SUITES READ_TEAMS READ_TEST_PLAN @@ -88,6 +89,7 @@ enum APIAccessTokenScopes { WRITE_PIPELINE_TEMPLATES WRITE_PIPELINES WRITE_REGISTRIES + WRITE_RULES WRITE_SUITES WRITE_TEAMS WRITE_TEST_PLAN @@ -507,6 +509,8 @@ enum AuditEventType { ORGANIZATION_BUILD_EXPORT_UPDATED ORGANIZATION_CREATED ORGANIZATION_DELETED + ORGANIZATION_IMPERSONATION_REQUEST_APPROVED + ORGANIZATION_IMPERSONATION_REQUEST_REVOKED ORGANIZATION_INVITATION_ACCEPTED ORGANIZATION_INVITATION_CREATED ORGANIZATION_INVITATION_RESENT @@ -530,7 +534,13 @@ enum AuditEventType { PIPELINE_WEBHOOK_URL_ROTATED REGISTRY_CREATED REGISTRY_DELETED + REGISTRY_TOKEN_CREATED + REGISTRY_TOKEN_DELETED + REGISTRY_TOKEN_UPDATED REGISTRY_UPDATED + REGISTRY_VISIBILITY_CHANGED + RULE_CREATED + RULE_DELETED SCM_PIPELINE_SETTINGS_CREATED SCM_PIPELINE_SETTINGS_DELETED SCM_PIPELINE_SETTINGS_UPDATED @@ -552,8 +562,11 @@ enum AuditEventType { SECRET_UPDATED STORAGE_CREATED SUBSCRIPTION_PLAN_ADDED + SUBSCRIPTION_PLAN_CANCELATION_SCHEDULED + SUBSCRIPTION_PLAN_CANCELED SUBSCRIPTION_PLAN_CHANGE_SCHEDULED SUBSCRIPTION_PLAN_CHANGED + SUBSCRIPTION_SCHEDULED_PLAN_CHANGE_CANCELED SUITE_API_TOKEN_REGENERATED SUITE_CREATED SUITE_DELETED @@ -583,6 +596,7 @@ enum AuditEventType { USER_EMAIL_DELETED USER_EMAIL_MARKED_PRIMARY USER_EMAIL_VERIFIED + USER_IMPERSONATED USER_PASSWORD_RESET USER_PASSWORD_RESET_REQUESTED USER_TOTP_ACTIVATED @@ -606,44 +620,47 @@ type AuditSubject { } """Kinds of subjects which can have audit events performed on them""" -union AuditSubjectNode =APIAccessToken | AgentToken | AuthorizationBitbucket | AuthorizationGitHub | AuthorizationGitHubEnterprise | Cluster | ClusterPermission | ClusterQueue | ClusterQueueToken | ClusterToken | Email | JobTypeBlock | JobTypeCommand | JobTypeTrigger | JobTypeWait | NotificationServiceSlack | NotificationServiceWebhook | Organization | OrganizationBanner | OrganizationInvitation | OrganizationMember | Pipeline | PipelineSchedule | PipelineTemplate | Registry | SCMPipelineSettings | SCMRepositoryHost | SCMService | SSOProviderGitHubApp | SSOProviderGoogleGSuite | SSOProviderSAML | Secret | Subscription | Suite | TOTP | Team | TeamMember | TeamPipeline | TeamRegistry | TeamSuite | User +union AuditSubjectNode =APIAccessToken | AgentToken | AuthorizationBitbucket | AuthorizationGitHub | AuthorizationGitHubEnterprise | Cluster | ClusterPermission | ClusterQueue | ClusterQueueToken | ClusterToken | Email | JobTypeBlock | JobTypeCommand | JobTypeTrigger | JobTypeWait | NotificationServiceSlack | NotificationServiceWebhook | Organization | OrganizationBanner | OrganizationImpersonationRequest | OrganizationInvitation | OrganizationMember | Pipeline | PipelineSchedule | PipelineTemplate | Registry | RegistryToken | Rule | SCMPipelineSettings | SCMRepositoryHost | SCMService | SSOProviderGitHubApp | SSOProviderGoogleGSuite | SSOProviderSAML | Secret | Subscription | Suite | TOTP | Team | TeamMember | TeamPipeline | TeamRegistry | TeamSuite | User """All the possible types of subjects in an Audit Event""" enum AuditSubjectType { - SUITE - ORGANIZATION CLUSTER_PERMISSION - TEAM - USER - SECRET - PIPELINE - REGISTRY - ORGANIZATION_MEMBER - JOB + RULE + SUITE + AGENT_TOKEN + API_ACCESS_TOKEN CLUSTER_QUEUE - CLUSTER_TOKEN - CLUSTER_QUEUE_TOKEN NOTIFICATION_SERVICE ORGANIZATION_BANNER ORGANIZATION_INVITATION - PIPELINE_SCHEDULE + CLUSTER + ORGANIZATION_MEMBER + ORGANIZATION_IMPERSONATION_REQUEST PIPELINE_TEMPLATE - AUTHORIZATION - TEAM_MEMBER + ORGANIZATION + TEAM_PIPELINE + TEAM TEAM_REGISTRY + PIPELINE_SCHEDULE + REGISTRY_TOKEN + TEAM_MEMBER + CLUSTER_TOKEN + CLUSTER_QUEUE_TOKEN TEAM_SUITE - TEAM_PIPELINE - CLUSTER - API_ACCESS_TOKEN - SCM_SERVICE SCM_PIPELINE_SETTINGS + JOB + PIPELINE + USER_EMAIL SCM_REPOSITORY_HOST - SUITE_MONITOR - AGENT_TOKEN + SSO_PROVIDER + SCM_SERVICE USER_TOTP + SUITE_MONITOR SUBSCRIPTION - USER_EMAIL - SSO_PROVIDER + SECRET + REGISTRY + USER + AUTHORIZATION } """Context for an audit event created during a web request""" @@ -2474,6 +2491,16 @@ Note that the old webhook URL will stop working immediately and so must be updat """Parameters for PipelineUpdate""" input: PipelineUpdateInput! ): PipelineUpdatePayload +"""Create a rule.""" + ruleCreate( +"""Parameters for RuleCreate""" + input: RuleCreateInput! + ): RuleCreatePayload +"""Delete a rule.""" + ruleDelete( +"""Parameters for RuleDelete""" + input: RuleDeleteInput! + ): RuleDeletePayload """Create a SSO provider.""" ssoProviderCreate( """Parameters for SSOProviderCreate""" @@ -2906,6 +2933,25 @@ type Organization implements Node{ ): RegistryConnection """API tokens with access to this organization will be automatically revoked after this many seconds of inactivity. A `null` value indicates never revoke inactive tokens.""" revokeInactiveTokensAfter: RevokeInactiveTokenPeriod +"""Returns rules for an Organization""" + rules( +"""Returns the first _n_ elements from the list.""" + first: Int +"""Returns the elements in the list that come after the specified cursor.""" + after: String +"""Returns the last _n_ elements from the list.""" + last: Int +"""Returns the elements in the list that come before the specified cursor.""" + before: String +"""Order the rules""" + order: RuleOrder +"""Filter the rules by source type""" + sourceType: [RuleSourceType!] +"""Filter the rules by target type""" + targetType: [RuleTargetType!] +"""Filter the rules by action""" + action: [RuleAction!] + ): RuleConnection """The slug used to represent the organization in URLs""" slug: String! """The single sign-on configuration of this organization""" @@ -3152,6 +3198,15 @@ type OrganizationEnforceTwoFactorAuthenticationForMembersUpdateMutationPayload { organization: Organization! } +"""A request made by Buildkite to impersonate a user in an organization""" +type OrganizationImpersonationRequest { + approvedAt: DateTime + createdAt: DateTime + duration: String + reason: String + uuid: String! +} + """A pending invitation to a user to join this organization""" type OrganizationInvitation implements Node{ """The time when the invitation was accepted""" @@ -3680,7 +3735,7 @@ type Pipeline implements Node{ ): PipelineMetricConnection """The name of the pipeline""" name: String! -"""The next build number in the sequence""" +"""The next build number""" nextBuildNumber: Int! organization: Organization! permissions: PipelinePermissions! @@ -4391,6 +4446,13 @@ type Query { """The UUID of the pipeline template""" uuid: ID! ): PipelineTemplate +"""Find a registry""" + registry( +"""The slug of the registry, prefixed with its organization. i.e. `acme-inc/my-registry`""" + slug: ID +"""The UUID of the registry""" + uuid: ID + ): Registry """Find a secret via its uuid. This does not contain the value of the secret or encrypted material.""" secret( """The UUID for the secret i.e. `0bd5ea7c-89b3-4f40-8ca3-ffac805771eb`""" @@ -4500,6 +4562,24 @@ enum RegistryOrders { RELEVANCE } +"""A registry token""" +type RegistryToken implements Node{ +"""The time when this token was created""" + createdAt: DateTime +"""The user who created this token""" + createdBy: User +"""The description of the purpose for this registry token""" + description: String + id: ID! + organization: Organization! + registry: Registry! +"""The time when this token was last updated""" + updatedAt: DateTime +"""The user who last updated this token""" + updatedBy: User + uuid: String! +} + """A repository associated with a pipeline""" type Repository { """The repository’s provider""" @@ -4813,6 +4893,120 @@ enum RevokeInactiveTokenPeriod { NEVER } +type Rule implements Node{ +"""Action for the rule""" + action: RuleAction +"""User who created the rule""" + createdBy: User +"""Description of the rule""" + description: String +"""A formatted JSON document of the Rule""" + document: String +"""Effect for the rule""" + effect: RuleEffect + id: ID! + organization: Organization +"""The source for the rule""" + source: RuleSource +"""Source type for the rule""" + sourceType: RuleSourceType +"""The target for the rule""" + target: RuleTarget +"""Target type for the rule""" + targetType: RuleTargetType +"""The type of rule""" + type: String! +"""The public UUID for the rule""" + uuid: ID! +} + +"""The action a rule enforces""" +enum RuleAction { +"""Artifacts read""" + ARTIFACTS_READ +"""Trigger build""" + TRIGGER_BUILD +} + +type RuleConnection implements Connection{ + count: Int! + edges: [RuleEdge] + pageInfo: PageInfo +} + +"""Autogenerated input type of RuleCreate""" +input RuleCreateInput { +"""Autogenerated input type of RuleCreate""" + clientMutationId: String +"""Autogenerated input type of RuleCreate""" + organizationId: ID! +"""Autogenerated input type of RuleCreate""" + description: String +"""Autogenerated input type of RuleCreate""" + type: String! +"""Autogenerated input type of RuleCreate""" + value: JSON! +} + +"""Autogenerated return type of RuleCreate.""" +type RuleCreatePayload { +"""A unique identifier for the client performing the mutation.""" + clientMutationId: String + rule: Rule! +} + +"""Autogenerated input type of RuleDelete""" +input RuleDeleteInput { +"""Autogenerated input type of RuleDelete""" + clientMutationId: String +"""Autogenerated input type of RuleDelete""" + organizationId: ID! +"""Autogenerated input type of RuleDelete""" + id: ID! +} + +"""Autogenerated return type of RuleDelete.""" +type RuleDeletePayload { +"""A unique identifier for the client performing the mutation.""" + clientMutationId: String + deletedRuleId: ID! +} + +type RuleEdge { + cursor: String! + node: Rule +} + +"""The effect a rule has""" +enum RuleEffect { +"""Allow""" + ALLOW +} + +"""The different orders you can sort rules by""" +enum RuleOrder { +"""Order by the most recently created rules first""" + RECENTLY_CREATED +} + +"""Kinds of sources for a rule""" +union RuleSource =Pipeline + +"""The source type for a rule""" +enum RuleSourceType { +"""Pipeline""" + PIPELINE +} + +"""Kinds of targets for a rule""" +union RuleTarget =Pipeline + +"""The target type for a rule""" +enum RuleTargetType { +"""Pipeline""" + PIPELINE +} + type SCMPipelineSettings { id: ID! } diff --git a/templates/data-sources/organization_rule.md b/templates/data-sources/organization_rule.md new file mode 100644 index 00000000..81c50924 --- /dev/null +++ b/templates/data-sources/organization_rule.md @@ -0,0 +1,49 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "buildkite_organization_rule Data Source - terraform-provider-buildkite" +subcategory: "" +description: |- + Use this data source to retrieve an organization rule by its ID. + More information on organization rules can be found in the documentation https://buildkite.com/docs/pipelines/rules. +--- + +# buildkite_organization_rule (Data Source) + +~> Rules is a feature that is currently in development and enabled on an opt-in basis for early access. To have this enabled for your organization for utilizing this data source, please reach out to Buildkite's [Support Team](https://buildkite.com/support). + +Use this data source to retrieve an organization rule by its ID. + +More information on organization rules can be found in the [documentation](https://buildkite.com/docs/pipelines/rules). + +## Example Usage + +```terraform +# Read an organization rule by its id +data "buildkite_organization_rule" "data_artifacts_read_dev_test" { + id = buildkite_organization_rule.artifacts_read_dev_test.id +} + +# Read an organization rule by its uuid +data "buildkite_organization_rule" "data_artifacts_read_test_dev" { + uuid = buildkite_organization_rule.artifacts_read_test_dev.uuid +} +``` + +## Schema + +### Optional + +- `id` (String) The GraphQL ID of the organization rule. +- `uuid` (String) The UUID of the organization rule. + +### Read-Only + +- `action` (String) The action defined between source and target resources. +- `description` (String) The description of the organization rule. +- `effect` (String) Whether this organization rule allows or denys the action to take place between source and target resources. +- `source_type` (String) The source resource type that this organization rule allows or denies to invoke its defined action. +- `source_uuid` (String) The UUID of the resource that this organization rule allows or denies invocating its defined action. +- `target_type` (String) The target resource type that this organization rule allows or denies the source to respective action. +- `target_uuid` (String) The UUID of the target resourcee that this organization rule allows or denies invocation its respective action. +- `type` (String) The type of organization rule. +- `value` (String) The JSON document that this organization rule implements. diff --git a/templates/resources/organization_rule.md b/templates/resources/organization_rule.md new file mode 100644 index 00000000..77df7a9c --- /dev/null +++ b/templates/resources/organization_rule.md @@ -0,0 +1,129 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "buildkite_organization_rule Resource - terraform-provider-buildkite" +subcategory: "" +description: |- + An Organization Rule allows specifying explicit rules between two Buildkite resources and the desired effect/action. + More information on organization rules can be found in the documentation https://buildkite.com/docs/pipelines/rules. +--- + +# buildkite_organization_rule (Resource) + +~> Rules is a feature that is currently in development and enabled on an opt-in basis for early access. To have this enabled for your organization for utilizing this resource, please reach out to Buildkite's [Support Team](https://buildkite.com/support). + +An Organization Rule allows specifying explicit rules between two Buildkite resources and the desired effect/action. + +More information on organization rules can be found in the [documentation](https://buildkite.com/docs/pipelines/rules). + +## Example Usage + +```terraform +# Creates a TRIGGER_BUILD organization rule with required attributes +resource "buildkite_organization_rule" "trigger_build_test_dev" { + type = "pipeline.trigger_build.pipeline" + value = jsonencode({ + source_pipeline = buildkite_pipeline.app_dev_deploy.uuid + target_pipeline = buildkite_pipeline.app_test_ci.uuid + }) +} + +# Creates a ARTIFACTS_READ organization rule with an optional description +resource "buildkite_organization_rule" "artifacts_read_test_dev" { + type = "pipeline.artifacts_read.pipeline" + description = "A rule to allow artifact reads by app_test_ci to app_dev_deploy" + value = jsonencode({ + source_pipeline = buildkite_pipeline.app_test_ci.uuid + target_pipeline = buildkite_pipeline.app_dev_deploy.uuid + }) +} + +# Creates a TRIGGER_BUILD organization rule with an optional description and conditions +resource "buildkite_organization_rule" "trigger_build_test_dev_cond" { + type = "pipeline.trigger_build.pipeline" + description = "A rule to allow app_dev_deploy to trigger app_test_ci builds with conditions" + value = jsonencode({ + source_pipeline = buildkite_pipeline.app_dev_deploy.uuid + target_pipeline = buildkite_pipeline.app_test_ci.uuid + conditions = [ + "source.build.creator.teams includes 'deploy'", + "source.build.branch == 'main'" + ] + }) +} +``` + +## Schema + +### Required + +- `type` (String) The type of organization rule. +- `value` (String) The JSON document that this organization rule implements. + +### Optional + +- `description` (String) The description of the organization rule. + +### Read-Only + +- `action` (String) The action defined between source and target resources. +- `effect` (String) Whether this organization rule allows or denies the action to take place between source and target resources. +- `id` (String) The GraphQL ID of the organization rule. +- `source_type` (String) The source resource type that this organization rule allows or denies to invoke its defined action. +- `source_uuid` (String) The UUID of the resource that this organization rule allows or denies invocating its defined action. +- `target_type` (String) The target resource type that this organization rule allows or denies the source to respective action. +- `target_uuid` (String) The UUID of the target resource that this organization rule allows or denies invocation its respective action. +- `uuid` (String) The UUID of the organization rule. + +## Import + +Import is supported using the following syntax: + +```shell +# import an organization rule resource using the rules GraphQL ID +# +# You can use this query to find the first 50 organiation rules (adjust for less or more): +# query getOrganizationRules { +# organization(slug: "ORGANIZATION_SLUG") { +# rules(first: 50) { +# edges{ +# node{ +# id +# sourceType +# targetType +# action +# } +# } +# } +# } +# } +# +# Depending on the speciific source/target, you're also able to filter on the source/target information +# query getOrganizationRules { +# organization(slug: "ORGANIZATION_SLUG") { +# rules(first: 50) { +# edges{ +# node{ +# id +# sourceType +# source { +# ... on Pipeline{ +# uuid +# name +# } +# } +# targetType +# target { +# ... on Pipeline{ +# uuid +# name +# } +# } +# action +# } +# } +# } +# } +# } + +terraform import buildkite_organization_rule.artifact_read UnVsZS0tLTAxOTE5NmU2LWNiNjctNzZiZi1iYzAyLTVhYzFiNzhhMWMyOA== +```