diff --git a/buildkite/data_source_organization_member.go b/buildkite/data_source_organization_member.go new file mode 100644 index 00000000..5a484e7c --- /dev/null +++ b/buildkite/data_source_organization_member.go @@ -0,0 +1,104 @@ +package buildkite + +import ( + "context" + "fmt" + + "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" +) + +type organizationMemberDatasourceModel struct { + ID types.String `tfsdk:"id"` + UUID types.String `tfsdk:"uuid"` + Name types.String `tfsdk:"name"` + Email types.String `tfsdk:"email"` +} + +type organizationMemberDatasource struct { + client *Client +} + +func newOrganizationMemberDatasource() datasource.DataSource { + return &organizationMemberDatasource{} +} + +func (o *organizationMemberDatasource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + o.client = req.ProviderData.(*Client) +} + +func (o *organizationMemberDatasource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_organization_member" +} + +func (o *organizationMemberDatasource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + MarkdownDescription: heredoc.Doc(` + Use this data source to retrieve a specific organization member, using their email. You can find out more about organization members in the Buildkite + [documentation](https://buildkite.com/docs/platform/team-management). + `), + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + MarkdownDescription: "The GraphQL ID of the organization member.", + Computed: true, + }, + "uuid": schema.StringAttribute{ + MarkdownDescription: "The UUID of the organization member.", + Computed: true, + }, + "name": schema.StringAttribute{ + MarkdownDescription: "The name of the organization member.", + Computed: true, + }, + "email": schema.StringAttribute{ + MarkdownDescription: "The email address of the organization member.", + Required: true, + }, + }, + } +} + +func (o *organizationMemberDatasource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var state organizationMemberDatasourceModel + + resp.Diagnostics.Append(req.Config.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + res, err := GetOrganizationMemberByEmail(ctx, o.client.genqlient, o.client.organization, state.Email.ValueString()) + if err != nil { + resp.Diagnostics.AddError( + "Unable to get organization member", + fmt.Sprintf("Error getting organization member: %s", err.Error()), + ) + return + } + + if len(res.Organization.Members.Edges) == 0 { + resp.Diagnostics.AddError( + "No organization member found", + fmt.Sprintf("Organization member not found: %s", state.Email.ValueString()), + ) + return + } + + for _, member := range res.Organization.Members.Edges { + updateOrganizationMemberDatasourceState(&state, member) + } + + resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) +} + +func updateOrganizationMemberDatasourceState(state *organizationMemberDatasourceModel, data GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdge) { + state.ID = types.StringValue(data.Node.User.Id) + state.UUID = types.StringValue(data.Node.User.Uuid) + state.Name = types.StringValue(data.Node.User.Name) + state.Email = types.StringValue(data.Node.User.Email) +} diff --git a/buildkite/data_source_organization_member_test.go b/buildkite/data_source_organization_member_test.go new file mode 100644 index 00000000..574a7bf0 --- /dev/null +++ b/buildkite/data_source_organization_member_test.go @@ -0,0 +1,34 @@ +package buildkite + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func testDatasourceOrganizationMemberConfig() string { + return ` + data "buildkite_organization_members" "members" {} + + data "buildkite_organization_member" "member" { + email = data.buildkite_organization_members.members.members[0].email + } + ` +} + +func TestAccBuildkiteOrganizationMemberDatasource(t *testing.T) { + t.Run("loads an organization member data source with required attribute", func(t *testing.T) { + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: protoV6ProviderFactories(), + Steps: []resource.TestStep{ + { + Config: testDatasourceOrganizationMemberConfig(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("data.buildkite_organization_member.member", "id"), + ), + }, + }, + }) + }) +} diff --git a/buildkite/data_source_organization_members.go b/buildkite/data_source_organization_members.go new file mode 100644 index 00000000..73b401ed --- /dev/null +++ b/buildkite/data_source_organization_members.go @@ -0,0 +1,127 @@ +package buildkite + +import ( + "context" + "fmt" + + "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" +) + +type organizationMembersDatasourceModel struct { + Members []organizationMembersModel `tfsdk:"members"` +} + +type organizationMembersModel struct { + ID types.String `tfsdk:"id"` + UUID types.String `tfsdk:"uuid"` + Name types.String `tfsdk:"name"` + Email types.String `tfsdk:"email"` +} + +type organizationMembersDatasource struct { + client *Client +} + +func newOrganizationMembersDatasource() datasource.DataSource { + return &organizationMembersDatasource{} +} + +func (o *organizationMembersDatasource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + o.client = req.ProviderData.(*Client) +} + +func (o *organizationMembersDatasource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_organization_members" +} + +func (o *organizationMembersDatasource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + MarkdownDescription: heredoc.Doc(` + Use this data source to retrieve a members of an organization. You can find out more about organization members in the Buildkite + [documentation](https://buildkite.com/docs/platform/team-management). + `), + Attributes: map[string]schema.Attribute{ + "members": schema.ListNestedAttribute{ + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + MarkdownDescription: "The GraphQL ID of the organization member.", + Computed: true, + }, + "uuid": schema.StringAttribute{ + MarkdownDescription: "The UUID of the organization member.", + Computed: true, + }, + "name": schema.StringAttribute{ + MarkdownDescription: "The name of the organization member.", + Computed: true, + }, + "email": schema.StringAttribute{ + MarkdownDescription: "The email address of the organization member.", + Computed: true, + }, + }, + }, + }, + }, + } +} + +func (o *organizationMembersDatasource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var state organizationMembersDatasourceModel + + resp.Diagnostics.Append(req.Config.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + var cursor *string + for { + res, err := GetOrganizationMembers(ctx, o.client.genqlient, o.client.organization, cursor) + if err != nil { + resp.Diagnostics.AddError( + "Unable to get organization members", + fmt.Sprintf("Error getting organization members: %s", err.Error()), + ) + return + } + + if len(res.Organization.Members.Edges) == 0 { + resp.Diagnostics.AddError( + "No organization members found", + fmt.Sprintf("Error getting members for organization: %s", o.client.organization), + ) + return + } + + for _, member := range res.Organization.Members.Edges { + updateOrganizationMembersDatasourceState(&state, member) + } + + if !res.Organization.Members.PageInfo.HasNextPage { + break + } + + cursor = &res.Organization.Members.PageInfo.EndCursor + } + resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) +} + +func updateOrganizationMembersDatasourceState(state *organizationMembersDatasourceModel, data GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdge) { + memberState := organizationMembersModel{ + ID: types.StringValue(data.Node.User.Id), + UUID: types.StringValue(data.Node.User.Uuid), + Name: types.StringValue(data.Node.User.Name), + Email: types.StringValue(data.Node.User.Email), + } + + state.Members = append(state.Members, memberState) +} diff --git a/buildkite/data_source_organization_members_test.go b/buildkite/data_source_organization_members_test.go new file mode 100644 index 00000000..da3ca01a --- /dev/null +++ b/buildkite/data_source_organization_members_test.go @@ -0,0 +1,24 @@ +package buildkite + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func TestAccBuildkiteOrganizationMembersDatasource(t *testing.T) { + t.Run("organization members data source can be loaded with defaults", func(t *testing.T) { + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: protoV6ProviderFactories(), + Steps: []resource.TestStep{ + { + Config: `data "buildkite_organization_members" "members" {}`, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("data.buildkite_organization_members.members", "members.0.email"), + ), + }, + }, + }) + }) +} diff --git a/buildkite/generated.go b/buildkite/generated.go index 0bbc26af..d581a235 100644 --- a/buildkite/generated.go +++ b/buildkite/generated.go @@ -153,6 +153,217 @@ func (v *ClusterQueueValuesCluster) GetId() string { return v.Id } // GetUuid returns ClusterQueueValuesCluster.Uuid, and is useful for accessing the field via an interface. func (v *ClusterQueueValuesCluster) GetUuid() string { return v.Uuid } +// GetOrganizationMemberByEmailOrganization includes the requested fields of the GraphQL type Organization. +// The GraphQL type's documentation follows. +// +// An organization +type GetOrganizationMemberByEmailOrganization struct { + // Returns users within the organization + Members GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnection `json:"members"` +} + +// GetMembers returns GetOrganizationMemberByEmailOrganization.Members, and is useful for accessing the field via an interface. +func (v *GetOrganizationMemberByEmailOrganization) GetMembers() GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnection { + return v.Members +} + +// GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnection includes the requested fields of the GraphQL type OrganizationMemberConnection. +type GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnection struct { + Edges []GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdge `json:"edges"` +} + +// GetEdges returns GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnection.Edges, and is useful for accessing the field via an interface. +func (v *GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnection) GetEdges() []GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdge { + return v.Edges +} + +// GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdge includes the requested fields of the GraphQL type OrganizationMemberEdge. +type GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdge struct { + Node GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMember `json:"node"` +} + +// GetNode returns GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdge.Node, and is useful for accessing the field via an interface. +func (v *GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdge) GetNode() GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMember { + return v.Node +} + +// GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMember includes the requested fields of the GraphQL type OrganizationMember. +// The GraphQL type's documentation follows. +// +// A member of an organization +type GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMember struct { + User GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMemberUser `json:"user"` +} + +// GetUser returns GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMember.User, and is useful for accessing the field via an interface. +func (v *GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMember) GetUser() GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMemberUser { + return v.User +} + +// GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMemberUser includes the requested fields of the GraphQL type User. +// The GraphQL type's documentation follows. +// +// A user +type GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMemberUser struct { + Id string `json:"id"` + // The public UUID of the user + Uuid string `json:"uuid"` + // The name of the user + Name string `json:"name"` + // The primary email for the user + Email string `json:"email"` +} + +// GetId returns GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMemberUser.Id, and is useful for accessing the field via an interface. +func (v *GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMemberUser) GetId() string { + return v.Id +} + +// GetUuid returns GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMemberUser.Uuid, and is useful for accessing the field via an interface. +func (v *GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMemberUser) GetUuid() string { + return v.Uuid +} + +// GetName returns GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMemberUser.Name, and is useful for accessing the field via an interface. +func (v *GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMemberUser) GetName() string { + return v.Name +} + +// GetEmail returns GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMemberUser.Email, and is useful for accessing the field via an interface. +func (v *GetOrganizationMemberByEmailOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMemberUser) GetEmail() string { + return v.Email +} + +// GetOrganizationMemberByEmailResponse is returned by GetOrganizationMemberByEmail on success. +type GetOrganizationMemberByEmailResponse struct { + // Find an organization + Organization GetOrganizationMemberByEmailOrganization `json:"organization"` +} + +// GetOrganization returns GetOrganizationMemberByEmailResponse.Organization, and is useful for accessing the field via an interface. +func (v *GetOrganizationMemberByEmailResponse) GetOrganization() GetOrganizationMemberByEmailOrganization { + return v.Organization +} + +// GetOrganizationMembersOrganization includes the requested fields of the GraphQL type Organization. +// The GraphQL type's documentation follows. +// +// An organization +type GetOrganizationMembersOrganization struct { + // Returns users within the organization + Members GetOrganizationMembersOrganizationMembersOrganizationMemberConnection `json:"members"` +} + +// GetMembers returns GetOrganizationMembersOrganization.Members, and is useful for accessing the field via an interface. +func (v *GetOrganizationMembersOrganization) GetMembers() GetOrganizationMembersOrganizationMembersOrganizationMemberConnection { + return v.Members +} + +// GetOrganizationMembersOrganizationMembersOrganizationMemberConnection includes the requested fields of the GraphQL type OrganizationMemberConnection. +type GetOrganizationMembersOrganizationMembersOrganizationMemberConnection struct { + PageInfo GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionPageInfo `json:"pageInfo"` + Edges []GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdge `json:"edges"` +} + +// GetPageInfo returns GetOrganizationMembersOrganizationMembersOrganizationMemberConnection.PageInfo, and is useful for accessing the field via an interface. +func (v *GetOrganizationMembersOrganizationMembersOrganizationMemberConnection) GetPageInfo() GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionPageInfo { + return v.PageInfo +} + +// GetEdges returns GetOrganizationMembersOrganizationMembersOrganizationMemberConnection.Edges, and is useful for accessing the field via an interface. +func (v *GetOrganizationMembersOrganizationMembersOrganizationMemberConnection) GetEdges() []GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdge { + return v.Edges +} + +// GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdge includes the requested fields of the GraphQL type OrganizationMemberEdge. +type GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdge struct { + Node GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMember `json:"node"` +} + +// GetNode returns GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdge.Node, and is useful for accessing the field via an interface. +func (v *GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdge) GetNode() GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMember { + return v.Node +} + +// GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMember includes the requested fields of the GraphQL type OrganizationMember. +// The GraphQL type's documentation follows. +// +// A member of an organization +type GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMember struct { + User GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMemberUser `json:"user"` +} + +// GetUser returns GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMember.User, and is useful for accessing the field via an interface. +func (v *GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMember) GetUser() GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMemberUser { + return v.User +} + +// GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMemberUser includes the requested fields of the GraphQL type User. +// The GraphQL type's documentation follows. +// +// A user +type GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMemberUser struct { + Id string `json:"id"` + // The public UUID of the user + Uuid string `json:"uuid"` + // The name of the user + Name string `json:"name"` + // The primary email for the user + Email string `json:"email"` +} + +// GetId returns GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMemberUser.Id, and is useful for accessing the field via an interface. +func (v *GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMemberUser) GetId() string { + return v.Id +} + +// GetUuid returns GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMemberUser.Uuid, and is useful for accessing the field via an interface. +func (v *GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMemberUser) GetUuid() string { + return v.Uuid +} + +// GetName returns GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMemberUser.Name, and is useful for accessing the field via an interface. +func (v *GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMemberUser) GetName() string { + return v.Name +} + +// GetEmail returns GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMemberUser.Email, and is useful for accessing the field via an interface. +func (v *GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionEdgesOrganizationMemberEdgeNodeOrganizationMemberUser) GetEmail() string { + return v.Email +} + +// GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionPageInfo includes the requested fields of the GraphQL type PageInfo. +// The GraphQL type's documentation follows. +// +// Information about pagination in a connection. +type GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionPageInfo struct { + // When paginating forwards, the cursor to continue. + EndCursor string `json:"endCursor"` + // When paginating forwards, are there more items? + HasNextPage bool `json:"hasNextPage"` +} + +// GetEndCursor returns GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionPageInfo.EndCursor, and is useful for accessing the field via an interface. +func (v *GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionPageInfo) GetEndCursor() string { + return v.EndCursor +} + +// GetHasNextPage returns GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionPageInfo.HasNextPage, and is useful for accessing the field via an interface. +func (v *GetOrganizationMembersOrganizationMembersOrganizationMemberConnectionPageInfo) GetHasNextPage() bool { + return v.HasNextPage +} + +// GetOrganizationMembersResponse is returned by GetOrganizationMembers on success. +type GetOrganizationMembersResponse struct { + // Find an organization + Organization GetOrganizationMembersOrganization `json:"organization"` +} + +// GetOrganization returns GetOrganizationMembersResponse.Organization, and is useful for accessing the field via an interface. +func (v *GetOrganizationMembersResponse) GetOrganization() GetOrganizationMembersOrganization { + return v.Organization +} + // GetTeamFromSlugResponse is returned by GetTeamFromSlug on success. type GetTeamFromSlugResponse struct { // Find a team @@ -1415,10 +1626,10 @@ const ( type RuleAction string const ( - // Trigger build - RuleActionTriggerBuild RuleAction = "TRIGGER_BUILD" // Artifacts read RuleActionArtifactsRead RuleAction = "ARTIFACTS_READ" + // Trigger build + RuleActionTriggerBuild RuleAction = "TRIGGER_BUILD" ) // The effect a rule has @@ -1667,6 +1878,30 @@ type TeamSuiteFieldsTeam struct { // GetId returns TeamSuiteFieldsTeam.Id, and is useful for accessing the field via an interface. func (v *TeamSuiteFieldsTeam) GetId() string { return v.Id } +// __GetOrganizationMemberByEmailInput is used internally by genqlient +type __GetOrganizationMemberByEmailInput struct { + Slug string `json:"slug"` + Email string `json:"email"` +} + +// GetSlug returns __GetOrganizationMemberByEmailInput.Slug, and is useful for accessing the field via an interface. +func (v *__GetOrganizationMemberByEmailInput) GetSlug() string { return v.Slug } + +// GetEmail returns __GetOrganizationMemberByEmailInput.Email, and is useful for accessing the field via an interface. +func (v *__GetOrganizationMemberByEmailInput) GetEmail() string { return v.Email } + +// __GetOrganizationMembersInput is used internally by genqlient +type __GetOrganizationMembersInput struct { + Slug string `json:"slug"` + Cursor *string `json:"cursor"` +} + +// GetSlug returns __GetOrganizationMembersInput.Slug, and is useful for accessing the field via an interface. +func (v *__GetOrganizationMembersInput) GetSlug() string { return v.Slug } + +// GetCursor returns __GetOrganizationMembersInput.Cursor, and is useful for accessing the field via an interface. +func (v *__GetOrganizationMembersInput) GetCursor() *string { return v.Cursor } + // __GetTeamFromSlugInput is used internally by genqlient type __GetTeamFromSlugInput struct { Slug string `json:"slug"` @@ -4928,6 +5163,7 @@ func (v *getClusterQueuesResponse) GetOrganization() getClusterQueuesOrganizatio // getNodeNodeClusterQueue // getNodeNodeClusterQueueToken // getNodeNodeClusterToken +// getNodeNodeCompositeRegistryUpstream // getNodeNodeEmail // getNodeNodeJobEventAssigned // getNodeNodeJobEventBuildStepUploadCreated @@ -4996,6 +5232,7 @@ func (v *getNodeNodeCluster) implementsGraphQLInterfacegetNodeNode() func (v *getNodeNodeClusterQueue) implementsGraphQLInterfacegetNodeNode() {} func (v *getNodeNodeClusterQueueToken) implementsGraphQLInterfacegetNodeNode() {} func (v *getNodeNodeClusterToken) implementsGraphQLInterfacegetNodeNode() {} +func (v *getNodeNodeCompositeRegistryUpstream) implementsGraphQLInterfacegetNodeNode() {} func (v *getNodeNodeEmail) implementsGraphQLInterfacegetNodeNode() {} func (v *getNodeNodeJobEventAssigned) implementsGraphQLInterfacegetNodeNode() {} func (v *getNodeNodeJobEventBuildStepUploadCreated) implementsGraphQLInterfacegetNodeNode() {} @@ -5111,6 +5348,9 @@ func __unmarshalgetNodeNode(b []byte, v *getNodeNode) error { case "ClusterToken": *v = new(getNodeNodeClusterToken) return json.Unmarshal(b, *v) + case "CompositeRegistryUpstream": + *v = new(getNodeNodeCompositeRegistryUpstream) + return json.Unmarshal(b, *v) case "Email": *v = new(getNodeNodeEmail) return json.Unmarshal(b, *v) @@ -5405,6 +5645,14 @@ func __marshalgetNodeNode(v *getNodeNode) ([]byte, error) { *getNodeNodeClusterToken }{typename, v} return json.Marshal(result) + case *getNodeNodeCompositeRegistryUpstream: + typename = "CompositeRegistryUpstream" + + result := struct { + TypeName string `json:"__typename"` + *getNodeNodeCompositeRegistryUpstream + }{typename, v} + return json.Marshal(result) case *getNodeNodeEmail: typename = "Email" @@ -6056,6 +6304,17 @@ type getNodeNodeClusterToken struct { // GetTypename returns getNodeNodeClusterToken.Typename, and is useful for accessing the field via an interface. func (v *getNodeNodeClusterToken) GetTypename() string { return v.Typename } +// getNodeNodeCompositeRegistryUpstream includes the requested fields of the GraphQL type CompositeRegistryUpstream. +// The GraphQL type's documentation follows. +// +// A composite registry's upstream +type getNodeNodeCompositeRegistryUpstream struct { + Typename string `json:"__typename"` +} + +// GetTypename returns getNodeNodeCompositeRegistryUpstream.Typename, and is useful for accessing the field via an interface. +func (v *getNodeNodeCompositeRegistryUpstream) GetTypename() string { return v.Typename } + // getNodeNodeEmail includes the requested fields of the GraphQL type Email. // The GraphQL type's documentation follows. // @@ -8087,6 +8346,7 @@ func (v *getPipelineScheduleBySlugResponse) GetPipelineSchedule() getPipelineSch // getPipelineScheduleNodeClusterQueue // getPipelineScheduleNodeClusterQueueToken // getPipelineScheduleNodeClusterToken +// getPipelineScheduleNodeCompositeRegistryUpstream // getPipelineScheduleNodeEmail // getPipelineScheduleNodeJobEventAssigned // getPipelineScheduleNodeJobEventBuildStepUploadCreated @@ -8163,7 +8423,9 @@ func (v *getPipelineScheduleNodeClusterQueue) implementsGraphQLInterfacegetPipel func (v *getPipelineScheduleNodeClusterQueueToken) implementsGraphQLInterfacegetPipelineScheduleNode() { } func (v *getPipelineScheduleNodeClusterToken) implementsGraphQLInterfacegetPipelineScheduleNode() {} -func (v *getPipelineScheduleNodeEmail) implementsGraphQLInterfacegetPipelineScheduleNode() {} +func (v *getPipelineScheduleNodeCompositeRegistryUpstream) implementsGraphQLInterfacegetPipelineScheduleNode() { +} +func (v *getPipelineScheduleNodeEmail) implementsGraphQLInterfacegetPipelineScheduleNode() {} func (v *getPipelineScheduleNodeJobEventAssigned) implementsGraphQLInterfacegetPipelineScheduleNode() { } func (v *getPipelineScheduleNodeJobEventBuildStepUploadCreated) implementsGraphQLInterfacegetPipelineScheduleNode() { @@ -8296,6 +8558,9 @@ func __unmarshalgetPipelineScheduleNode(b []byte, v *getPipelineScheduleNode) er case "ClusterToken": *v = new(getPipelineScheduleNodeClusterToken) return json.Unmarshal(b, *v) + case "CompositeRegistryUpstream": + *v = new(getPipelineScheduleNodeCompositeRegistryUpstream) + return json.Unmarshal(b, *v) case "Email": *v = new(getPipelineScheduleNodeEmail) return json.Unmarshal(b, *v) @@ -8586,6 +8851,14 @@ func __marshalgetPipelineScheduleNode(v *getPipelineScheduleNode) ([]byte, error *getPipelineScheduleNodeClusterToken }{typename, v} return json.Marshal(result) + case *getPipelineScheduleNodeCompositeRegistryUpstream: + typename = "CompositeRegistryUpstream" + + result := struct { + TypeName string `json:"__typename"` + *getPipelineScheduleNodeCompositeRegistryUpstream + }{typename, v} + return json.Marshal(result) case *getPipelineScheduleNodeEmail: typename = "Email" @@ -9126,6 +9399,17 @@ type getPipelineScheduleNodeClusterToken struct { // GetTypename returns getPipelineScheduleNodeClusterToken.Typename, and is useful for accessing the field via an interface. func (v *getPipelineScheduleNodeClusterToken) GetTypename() string { return v.Typename } +// getPipelineScheduleNodeCompositeRegistryUpstream includes the requested fields of the GraphQL type CompositeRegistryUpstream. +// The GraphQL type's documentation follows. +// +// A composite registry's upstream +type getPipelineScheduleNodeCompositeRegistryUpstream struct { + Typename string `json:"__typename"` +} + +// GetTypename returns getPipelineScheduleNodeCompositeRegistryUpstream.Typename, and is useful for accessing the field via an interface. +func (v *getPipelineScheduleNodeCompositeRegistryUpstream) GetTypename() string { return v.Typename } + // getPipelineScheduleNodeEmail includes the requested fields of the GraphQL type Email. // The GraphQL type's documentation follows. // @@ -10343,6 +10627,17 @@ type getTestSuiteSuiteClusterToken struct { // GetTypename returns getTestSuiteSuiteClusterToken.Typename, and is useful for accessing the field via an interface. func (v *getTestSuiteSuiteClusterToken) GetTypename() string { return v.Typename } +// getTestSuiteSuiteCompositeRegistryUpstream includes the requested fields of the GraphQL type CompositeRegistryUpstream. +// The GraphQL type's documentation follows. +// +// A composite registry's upstream +type getTestSuiteSuiteCompositeRegistryUpstream struct { + Typename string `json:"__typename"` +} + +// GetTypename returns getTestSuiteSuiteCompositeRegistryUpstream.Typename, and is useful for accessing the field via an interface. +func (v *getTestSuiteSuiteCompositeRegistryUpstream) GetTypename() string { return v.Typename } + // getTestSuiteSuiteEmail includes the requested fields of the GraphQL type Email. // The GraphQL type's documentation follows. // @@ -10509,6 +10804,7 @@ func (v *getTestSuiteSuiteJobTypeWait) GetTypename() string { return v.Typename // getTestSuiteSuiteClusterQueue // getTestSuiteSuiteClusterQueueToken // getTestSuiteSuiteClusterToken +// getTestSuiteSuiteCompositeRegistryUpstream // getTestSuiteSuiteEmail // getTestSuiteSuiteJobEventAssigned // getTestSuiteSuiteJobEventBuildStepUploadCreated @@ -10578,8 +10874,10 @@ func (v *getTestSuiteSuiteCluster) implementsGraphQLInterfacegetTestSuiteSuiteNo func (v *getTestSuiteSuiteClusterQueue) implementsGraphQLInterfacegetTestSuiteSuiteNode() {} func (v *getTestSuiteSuiteClusterQueueToken) implementsGraphQLInterfacegetTestSuiteSuiteNode() {} func (v *getTestSuiteSuiteClusterToken) implementsGraphQLInterfacegetTestSuiteSuiteNode() {} -func (v *getTestSuiteSuiteEmail) implementsGraphQLInterfacegetTestSuiteSuiteNode() {} -func (v *getTestSuiteSuiteJobEventAssigned) implementsGraphQLInterfacegetTestSuiteSuiteNode() {} +func (v *getTestSuiteSuiteCompositeRegistryUpstream) implementsGraphQLInterfacegetTestSuiteSuiteNode() { +} +func (v *getTestSuiteSuiteEmail) implementsGraphQLInterfacegetTestSuiteSuiteNode() {} +func (v *getTestSuiteSuiteJobEventAssigned) implementsGraphQLInterfacegetTestSuiteSuiteNode() {} func (v *getTestSuiteSuiteJobEventBuildStepUploadCreated) implementsGraphQLInterfacegetTestSuiteSuiteNode() { } func (v *getTestSuiteSuiteJobEventCanceled) implementsGraphQLInterfacegetTestSuiteSuiteNode() {} @@ -10697,6 +10995,9 @@ func __unmarshalgetTestSuiteSuiteNode(b []byte, v *getTestSuiteSuiteNode) error case "ClusterToken": *v = new(getTestSuiteSuiteClusterToken) return json.Unmarshal(b, *v) + case "CompositeRegistryUpstream": + *v = new(getTestSuiteSuiteCompositeRegistryUpstream) + return json.Unmarshal(b, *v) case "Email": *v = new(getTestSuiteSuiteEmail) return json.Unmarshal(b, *v) @@ -10987,6 +11288,14 @@ func __marshalgetTestSuiteSuiteNode(v *getTestSuiteSuiteNode) ([]byte, error) { *getTestSuiteSuiteClusterToken }{typename, v} return json.Marshal(result) + case *getTestSuiteSuiteCompositeRegistryUpstream: + typename = "CompositeRegistryUpstream" + + result := struct { + TypeName string `json:"__typename"` + *getTestSuiteSuiteCompositeRegistryUpstream + }{typename, v} + return json.Marshal(result) case *getTestSuiteSuiteEmail: typename = "Email" @@ -13794,6 +14103,106 @@ func (v *upsertBannerResponse) GetOrganizationBannerUpsert() upsertBannerOrganiz return v.OrganizationBannerUpsert } +// The query or mutation executed by GetOrganizationMemberByEmail. +const GetOrganizationMemberByEmail_Operation = ` +query GetOrganizationMemberByEmail ($slug: ID!, $email: String) { + organization(slug: $slug) { + members(first: 1, email: $email) { + edges { + node { + user { + id + uuid + name + email + } + } + } + } + } +} +` + +func GetOrganizationMemberByEmail( + ctx_ context.Context, + client_ graphql.Client, + slug string, + email string, +) (*GetOrganizationMemberByEmailResponse, error) { + req_ := &graphql.Request{ + OpName: "GetOrganizationMemberByEmail", + Query: GetOrganizationMemberByEmail_Operation, + Variables: &__GetOrganizationMemberByEmailInput{ + Slug: slug, + Email: email, + }, + } + var err_ error + + var data_ GetOrganizationMemberByEmailResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + +// The query or mutation executed by GetOrganizationMembers. +const GetOrganizationMembers_Operation = ` +query GetOrganizationMembers ($slug: ID!, $cursor: String) { + organization(slug: $slug) { + members(first: 500, after: $cursor) { + pageInfo { + endCursor + hasNextPage + } + edges { + node { + user { + id + uuid + name + email + } + } + } + } + } +} +` + +func GetOrganizationMembers( + ctx_ context.Context, + client_ graphql.Client, + slug string, + cursor *string, +) (*GetOrganizationMembersResponse, error) { + req_ := &graphql.Request{ + OpName: "GetOrganizationMembers", + Query: GetOrganizationMembers_Operation, + Variables: &__GetOrganizationMembersInput{ + Slug: slug, + Cursor: cursor, + }, + } + var err_ error + + var data_ GetOrganizationMembersResponse + resp_ := &graphql.Response{Data: &data_} + + err_ = client_.MakeRequest( + ctx_, + req_, + resp_, + ) + + return &data_, err_ +} + // The query or mutation executed by GetTeamFromSlug. const GetTeamFromSlug_Operation = ` query GetTeamFromSlug ($slug: ID!) { diff --git a/buildkite/graphql/organization_member.graphql b/buildkite/graphql/organization_member.graphql new file mode 100644 index 00000000..cb7d21eb --- /dev/null +++ b/buildkite/graphql/organization_member.graphql @@ -0,0 +1,19 @@ +query GetOrganizationMemberByEmail( + $slug: ID!, + $email: String +) { + organization(slug: $slug) { + members(first: 1, email: $email) { + edges { + node { + user { + id + uuid + name + email + } + } + } + } + } +} diff --git a/buildkite/graphql/organization_members.graphql b/buildkite/graphql/organization_members.graphql new file mode 100644 index 00000000..d79b7e97 --- /dev/null +++ b/buildkite/graphql/organization_members.graphql @@ -0,0 +1,24 @@ +query GetOrganizationMembers( + $slug: ID!, + # @genqlient(pointer: true) + $cursor: String +) { + organization(slug: $slug) { + members(first: 500, after: $cursor) { + pageInfo { + endCursor + hasNextPage + } + edges { + node { + user { + id + uuid + name + email + } + } + } + } + } +} diff --git a/buildkite/provider.go b/buildkite/provider.go index 5dcc64cc..c0b5722a 100644 --- a/buildkite/provider.go +++ b/buildkite/provider.go @@ -111,6 +111,8 @@ func (*terraformProvider) DataSources(context.Context) []func() datasource.DataS newClusterDatasource, newMetaDatasource, newOrganizationDatasource, + newOrganizationMemberDatasource, + newOrganizationMembersDatasource, newOrganizationRuleDatasource, newPipelineDatasource, newPipelineTemplateDatasource, diff --git a/docs/data-sources/organization_member.md b/docs/data-sources/organization_member.md new file mode 100644 index 00000000..f240f6cf --- /dev/null +++ b/docs/data-sources/organization_member.md @@ -0,0 +1,47 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "buildkite_organization_member Data Source - terraform-provider-buildkite" +subcategory: "" +description: |- + Use this data source to retrieve a specific organization member, using their email. You can find out more about organization members in the Buildkite + documentation https://buildkite.com/docs/platform/team-management. +--- + +# buildkite_organization_member (Data Source) + +Use this data source to retrieve a specific organization member, using their email. You can find out more about organization members in the Buildkite +[documentation](https://buildkite.com/docs/platform/team-management). + +## Example Usage + +```terraform +data "buildkite_organization_member" "a_smith" { + email = "a.smith@company.com" +} + +resource "buildkite_team" "developers" { + name = "Developers" + privacy = "VISIBLE" + default_team = false + default_member_role = "MEMBER" +} + +resource "buildkite_team_member" "developers_a_smith" { + team_id = buildkite_team.developers.id + user_id = data.buildkite_organization_member.a_smith.id + role = "MEMBER" +} +``` + + +## Schema + +### Required + +- `email` (String) The email address of the organization member. + +### Read-Only + +- `id` (String) The GraphQL ID of the organization member. +- `name` (String) The name of the organization member. +- `uuid` (String) The UUID of the organization member. diff --git a/docs/data-sources/organization_members.md b/docs/data-sources/organization_members.md new file mode 100644 index 00000000..a6197f26 --- /dev/null +++ b/docs/data-sources/organization_members.md @@ -0,0 +1,36 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "buildkite_organization_members Data Source - terraform-provider-buildkite" +subcategory: "" +description: |- + Use this data source to retrieve a members of an organization. You can find out more about organization members in the Buildkite + documentation https://buildkite.com/docs/platform/team-management. +--- + +# buildkite_organization_members (Data Source) + +Use this data source to retrieve a members of an organization. You can find out more about organization members in the Buildkite +[documentation](https://buildkite.com/docs/platform/team-management). + +## Example Usage + +```terraform +data "buildkite_organization_members" "members" {} +``` + + +## Schema + +### Read-Only + +- `members` (Attributes List) (see [below for nested schema](#nestedatt--members)) + + +### Nested Schema for `members` + +Read-Only: + +- `email` (String) The email address of the organization member. +- `id` (String) The GraphQL ID of the organization member. +- `name` (String) The name of the organization member. +- `uuid` (String) The UUID of the organization member. diff --git a/examples/data-sources/buildkite_organization_member/data-source.tf b/examples/data-sources/buildkite_organization_member/data-source.tf new file mode 100644 index 00000000..fab7acb0 --- /dev/null +++ b/examples/data-sources/buildkite_organization_member/data-source.tf @@ -0,0 +1,16 @@ +data "buildkite_organization_member" "a_smith" { + email = "a.smith@company.com" +} + +resource "buildkite_team" "developers" { + name = "Developers" + privacy = "VISIBLE" + default_team = false + default_member_role = "MEMBER" +} + +resource "buildkite_team_member" "developers_a_smith" { + team_id = buildkite_team.developers.id + user_id = data.buildkite_organization_member.a_smith.id + role = "MEMBER" +} diff --git a/examples/data-sources/buildkite_organization_members/data-source.tf b/examples/data-sources/buildkite_organization_members/data-source.tf new file mode 100644 index 00000000..0eb959a3 --- /dev/null +++ b/examples/data-sources/buildkite_organization_members/data-source.tf @@ -0,0 +1 @@ +data "buildkite_organization_members" "members" {} diff --git a/schema.graphql b/schema.graphql index 062fa2a2..f3153952 100644 --- a/schema.graphql +++ b/schema.graphql @@ -141,6 +141,7 @@ type Agent implements Node{ type: [JobTypes!] state: [JobStates!] priority: Int +"""Filter jobs based on matching agent query rules (for example, a single tag match "queue=test", or an array of matches ["queue=test", "tag=value"])""" agentQueryRules: [String!] concurrency: JobConcurrencySearch """Whether or not the command job passed. Passing `false` will return all failed jobs (including "soft failed" jobs)""" @@ -496,6 +497,8 @@ enum AuditEventType { CLUSTER_TOKEN_DELETED CLUSTER_TOKEN_UPDATED CLUSTER_UPDATED + COMPOSITE_REGISTRY_UPSTREAM_ADDED + COMPOSITE_REGISTRY_UPSTREAM_REMOVED JOB_TERMINAL_SESSION_STARTED NOTIFICATION_SERVICE_BROKEN NOTIFICATION_SERVICE_CREATED @@ -532,6 +535,9 @@ enum AuditEventType { PIPELINE_UPDATED PIPELINE_VISIBILITY_CHANGED PIPELINE_WEBHOOK_URL_ROTATED + PORTAL_CREATED + PORTAL_DELETED + PORTAL_UPDATED REGISTRY_CREATED REGISTRY_DELETED REGISTRY_TOKEN_CREATED @@ -561,6 +567,7 @@ enum AuditEventType { SECRET_READ SECRET_UPDATED STORAGE_CREATED + SUBSCRIPTION_ACTIVATED SUBSCRIPTION_PLAN_ADDED SUBSCRIPTION_PLAN_CANCELATION_SCHEDULED SUBSCRIPTION_PLAN_CANCELED @@ -620,47 +627,49 @@ 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 | 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 +union AuditSubjectNode =APIAccessToken | AgentToken | AuthorizationBitbucket | AuthorizationGitHub | AuthorizationGitHubEnterprise | Cluster | ClusterPermission | ClusterQueue | ClusterQueueToken | ClusterToken | CompositeRegistryUpstream | 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 { - SCM_PIPELINE_SETTINGS - USER_EMAIL - SUBSCRIPTION - SUITE - TEAM - SECRET - USER_TOTP - SUITE_MONITOR - AUTHORIZATION - RULE - JOB - PIPELINE - USER - CLUSTER - CLUSTER_PERMISSION CLUSTER_TOKEN - CLUSTER_QUEUE_TOKEN - AGENT_TOKEN - API_ACCESS_TOKEN - CLUSTER_QUEUE - NOTIFICATION_SERVICE ORGANIZATION_BANNER ORGANIZATION_INVITATION ORGANIZATION_MEMBER ORGANIZATION_IMPERSONATION_REQUEST - PIPELINE_SCHEDULE + PIPELINE PIPELINE_TEMPLATE + PIPELINE_SCHEDULE TEAM_MEMBER + AUTHORIZATION + CLUSTER_QUEUE_TOKEN TEAM_PIPELINE - TEAM_REGISTRY - ORGANIZATION + PORTAL TEAM_SUITE - REGISTRY_TOKEN + COMPOSITE_REGISTRY_UPSTREAM + ORGANIZATION SSO_PROVIDER - SCM_SERVICE REGISTRY + REGISTRY_TOKEN + TEAM_REGISTRY + SCM_SERVICE + CLUSTER + SECRET + SUITE_MONITOR + USER_EMAIL + SCM_PIPELINE_SETTINGS + RULE + TEAM + SUITE + USER_TOTP SCM_REPOSITORY_HOST + USER + SUBSCRIPTION + JOB + CLUSTER_PERMISSION + AGENT_TOKEN + API_ACCESS_TOKEN + CLUSTER_QUEUE + NOTIFICATION_SERVICE } """Context for an audit event created during a web request""" @@ -794,6 +803,7 @@ type Build implements Node{ type: [JobTypes!] state: [JobStates!] priority: JobPrioritySearch +"""Filter jobs based on matching agent query rules (for example, a single tag match "queue=test", or an array of matches ["queue=test", "tag=value"])""" agentQueryRules: [String!] concurrency: JobConcurrencySearch """Whether or not the command job passed. Passing `false` will return all failed jobs (including "soft failed" jobs)""" @@ -1286,6 +1296,10 @@ type ClusterQueue implements Node{ dispatchPausedBy: User """Note describing why job dispatch was paused for this cluster queue""" dispatchPausedNote: String +"""Whether this queue powers by hosted or self-hosted agents""" + hosted: Boolean! +"""Settings for hosted agents used for jobs in this queue""" + hostedAgents: HostedAgentQueueSettings id: ID! key: String! """The public UUID for this cluster queue""" @@ -1310,6 +1324,10 @@ input ClusterQueueCreateInput { key: String! """Autogenerated input type of ClusterQueueCreate""" description: String +"""Autogenerated input type of ClusterQueueCreate""" + hosted: Boolean +"""Autogenerated input type of ClusterQueueCreate""" + hostedAgents: HostedAgentsQueueSettingsCreateInput } """Autogenerated return type of ClusterQueueCreate.""" @@ -1405,6 +1423,8 @@ input ClusterQueueUpdateInput { id: ID! """Autogenerated input type of ClusterQueueUpdate""" description: String +"""Autogenerated input type of ClusterQueueUpdate""" + hostedAgents: HostedAgentsQueueSettingsUpdateInput } """Autogenerated return type of ClusterQueueUpdate.""" @@ -1456,6 +1476,19 @@ type ClusterUpdatePayload { cluster: Cluster! } +"""A composite registry's upstream""" +type CompositeRegistryUpstream implements Node{ + compositeRegistry: Registry! +"""The time when the upstream was created""" + createdAt: DateTime + id: ID! + organization: Organization! + registry: Registry! +"""The time when the upstream was updated""" + updatedAt: DateTime + uuid: String! +} + interface Connection { count: Int! pageInfo: PageInfo @@ -1598,6 +1631,128 @@ type GraphQLSnippetCreatePayload { graphQLSnippet: GraphQLSnippet! } +"""Possible machine architectures for the hosted agent instance""" +enum HostedAgentArchitecture { +"""AMD64""" + AMD64 +"""ARM64""" + ARM64 +} + +"""The hosted agent instance configuration for this cluster queue""" +type HostedAgentInstanceShape { +"""Specifies the architecture of the hosted agent instance, such as AMD64 (x86_64) or ARM64 (AArch64), used in this cluster queue.""" + architecture: HostedAgentArchitecture +"""Specifies the type of machine used for the hosted agent instance in this cluster queue (e.g., Linux or MacOS).""" + machineType: HostedAgentMachineType +"""The amount of memory (in GB) available on each hosted agent instance in this cluster queue.""" + memory: Int +"""Name of the instance shape""" + name: HostedAgentInstanceShapeName +"""The overall size classification of the hosted agent instance, combining vCPU and memory, used in this cluster queue.""" + size: HostedAgentSize +"""The number of CPU cores allocated to the hosted agent instance in this cluster queue.""" + vcpu: Int +} + +"""Possible instance shapes for the hosted agent instance""" +enum HostedAgentInstanceShapeName { +"""Linux 4 vCPU x 16 GB Memory""" + LINUX_ARM64_4X16 +"""Linux 8 vCPU x 32 GB Memory""" + LINUX_ARM64_8X32 +"""Linux 16 vCPU x 64 GB Memory""" + LINUX_ARM64_16X64 +"""macOS 4 vCPU x 7 GB Memory""" + MACOS_M2_4X7 +"""macOS 6 vCPU x 14 GB Memory""" + MACOS_M2_6X14 +"""macOS 12 vCPU x 28 GB Memory""" + MACOS_M2_12X28 +"""macOS 12 vCPU x 56 GB Memory""" + MACOS_M4_12X56 +"""Linux 4 vCPU x 8 GB Memory (Deprecated)""" + LINUX_ARM64_4X8 +"""Linux 8 vCPU x 16 GB Memory (Deprecated)""" + LINUX_ARM64_8X16 +"""Linux 2 vCPU x 4 GB Memory""" + LINUX_AMD64_2X4 +"""Linux 4 vCPU x 16 GB Memory""" + LINUX_AMD64_4X16 +"""Linux 4 vCPU x 8 GB Memory (Deprecated)""" + LINUX_AMD64_4X8 +"""Linux 8 vCPU x 32 GB Memory""" + LINUX_AMD64_8X32 +"""Linux 8 vCPU x 16 GB Memory (Deprecated)""" + LINUX_AMD64_8X16 +"""Linux 16 vCPU x 64 GB Memory""" + LINUX_AMD64_16X64 +"""Linux 2 vCPU x 4 GB Memory""" + LINUX_ARM64_2X4 +} + +"""Configuration options specific to Linux hosted agent instances.""" +type HostedAgentLinuxSettings { +"""The image reference of a custom agent base image used by the hosted agent instances in this cluster queue. Note: this must be a public image, or image stored within the hosted agents internal registry.""" + agentImageRef: String +} + +"""Configuration options for the base image of hosted agent instances on macOS platforms.""" +type HostedAgentMacOSSettingsType { +"""The Xcode version to pre-select (via xcode-select) on macOS hosted agent instances for this cluster queue.""" + baseImageXcodeVersion: String +} + +"""Possible machine types for the hosted agent instance""" +enum HostedAgentMachineType { +"""Linux""" + LINUX +"""macOS""" + MACOS +} + +"""Platform-specific configuration for hosted agent instances.""" +type HostedAgentPlatformSettings { +"""Configuration options specific to Linux hosted agent instances.""" + linux: HostedAgentLinuxSettings +"""Configuration options specific to macOS hosted agent instances.""" + macos: HostedAgentMacOSSettingsType +} + +"""Platform-specific configuration for hosted agent instances.""" +type HostedAgentQueueSettings { +"""The hardware specifications of the hosted agent instance, such as CPU and memory""" + instanceShape: HostedAgentInstanceShape +"""Platform-specific configuration for Linux and macOS hosted agents.""" + platformSettings: HostedAgentPlatformSettings +} + +"""Possible sizes for the hosted agent instance, specifying vCPU and memory allocations.""" +enum HostedAgentSize { +"""Small capacity size: 2 vCPU, 4GB RAM (Linux); 4 vCPU, 7GB RAM (macOS).""" + SMALL +"""Medium capacity size: 4 vCPU, 16GB RAM (Linux); 6 vCPU, 14GB RAM (macOS).""" + MEDIUM +"""Large capacity size: 8 vCPU, 32GB RAM (Linux); 12 vCPU, 28GB RAM (macOS).""" + LARGE +"""Extra large capacity size: 12 vCPU, 28GB RAM (Linux); Not applicable for macOS.""" + EXTRA_LARGE +} + +"""Settings for hosted agents on this queue""" +input HostedAgentsQueueSettingsCreateInput { +"""Settings for hosted agents on this queue""" + instanceShape: HostedAgentInstanceShapeName! +} + +"""Settings for hosted agents on this queue""" +input HostedAgentsQueueSettingsUpdateInput { +"""Settings for hosted agents on this queue""" + instanceShape: HostedAgentInstanceShapeName +"""Settings for hosted agents on this queue""" + agentImageRef: String +} + """Represents a unique identifier that is Base64 obfuscated. It is often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"VXNlci0xMA=="`) or integer (such as `4`) input value will be accepted as an ID.""" scalar ID @@ -2852,6 +3007,7 @@ type Organization implements Node{ type: [JobTypes!] state: [JobStates!] priority: JobPrioritySearch +"""Filter jobs based on matching agent query rules (for example, a single tag match "queue=test", or an array of matches ["queue=test", "tag=value"])""" agentQueryRules: [String!] concurrency: JobConcurrencySearch """Whether or not the command job passed. Passing `false` will return all failed jobs (including "soft failed" jobs)""" @@ -3763,6 +3919,7 @@ type Pipeline implements Node{ type: [JobTypes!] state: [JobStates!] priority: JobPrioritySearch +"""Filter jobs based on matching agent query rules (for example, a single tag match "queue=test", or an array of matches ["queue=test", "tag=value"])""" agentQueryRules: [String!] concurrency: JobConcurrencySearch """Whether or not the command job passed. Passing `false` will return all failed jobs (including "soft failed" jobs)""" @@ -4967,10 +5124,10 @@ type Rule implements Node{ """The action a rule enforces""" enum RuleAction { -"""Trigger build""" - TRIGGER_BUILD """Artifacts read""" ARTIFACTS_READ +"""Trigger build""" + TRIGGER_BUILD } type RuleConnection implements Connection{ @@ -6500,6 +6657,7 @@ type Viewer implements Node{ type: [JobTypes!] state: [JobStates!] priority: JobPrioritySearch +"""Filter jobs based on matching agent query rules (for example, a single tag match "queue=test", or an array of matches ["queue=test", "tag=value"])""" agentQueryRules: [String!] """Order the jobs""" order: JobOrder