diff --git a/.changes/unreleased/Feature-20250515-145437.yaml b/.changes/unreleased/Feature-20250515-145437.yaml new file mode 100644 index 00000000..3e25bee9 --- /dev/null +++ b/.changes/unreleased/Feature-20250515-145437.yaml @@ -0,0 +1,3 @@ +kind: Feature +body: Add client functions to create, update and delete "RelationshipDefinition"'s +time: 2025-05-15T14:54:37.070312-05:00 diff --git a/input.go b/input.go index 64c39573..a7af7c07 100644 --- a/input.go +++ b/input.go @@ -987,9 +987,26 @@ type PropertyInput struct { // RelationshipDefinition A source, target and relationship type specifying a relationship between two resources type RelationshipDefinition struct { - Source IdentifierInput `json:"source" yaml:"source"` // The resource that is the source of the relationship. alias is ambiguous in this context and is not supported. Please supply an id (Required) - Target IdentifierInput `json:"target" yaml:"target"` // The resource that is the target of the relationship. alias is ambiguous in this context and is not supported. Please supply an id (Required) - Type RelationshipTypeEnum `json:"type" yaml:"type" example:"belongs_to"` // The type of the relationship between source and target (Required) + RelationshipDefinition *IdentifierInput `json:"relationshipDefinition,omitempty" yaml:"relationshipDefinition,omitempty"` // A dynamic definition that specifies how the source and target are related (Optional) + Source IdentifierInput `json:"source" yaml:"source"` // The resource that is the source of the relationship (Required) + Target IdentifierInput `json:"target" yaml:"target"` // The resource that is the target of the relationship (Required) + Type RelationshipTypeEnum `json:"type" yaml:"type" example:"belongs_to"` // The type of the relationship between source and target (Required) +} + +// RelationshipDefinitionInput The input for defining a relationship on a component type +type RelationshipDefinitionInput struct { + Alias *string `json:"alias,omitempty" yaml:"alias,omitempty" example:"example_value"` // The unique identifier of the relationship (Optional) + ComponentType *IdentifierInput `json:"componentType,omitempty" yaml:"componentType,omitempty"` // The component type to create the relationship on (Optional) + Description *Nullable[string] `json:"description,omitempty" yaml:"description,omitempty" example:"example_value"` // The description of the relationship (Optional) + Metadata *RelationshipDefinitionMetadataInput `json:"metadata,omitempty" yaml:"metadata,omitempty"` // The metadata of the relationship (Optional) + Name *string `json:"name,omitempty" yaml:"name,omitempty" example:"example_value"` // The name of the relationship (Optional) +} + +// RelationshipDefinitionMetadataInput The metadata of the relationship +type RelationshipDefinitionMetadataInput struct { + AllowedTypes []string `json:"allowedTypes,omitempty" yaml:"allowedTypes,omitempty" example:"LIST_TODO"` // The aliases of which types this relationship can target. Valid values include any component type alias on your account, or `team` (Optional) + MaxItems *int `json:"maxItems,omitempty" yaml:"maxItems,omitempty" example:"3"` // The maximum number of records this relationship can associate to the component type. Defaults to null (no maximum) (Optional) + MinItems *int `json:"minItems,omitempty" yaml:"minItems,omitempty" example:"3"` // The minimum number of records this relationship must associate to the component type. Defaults to 0 (optional) (Optional) } // RepositoryUpdateInput Specifies the input fields used to update a repository diff --git a/object.go b/object.go index a73b3e83..2c76f3ee 100644 --- a/object.go +++ b/object.go @@ -338,6 +338,30 @@ type Predicate struct { Value string // The value of the condition (Optional) } +// RelationshipDefinitionMetadata The metadata of the relationship +type RelationshipDefinitionMetadata struct { + AllowedTypes []string // The aliases of which types this relationship can target. Valid values include any component type alias on your account, or `team` (Required) + MaxItems int // The maximum number of records this relationship can associate to the component type. Defaults to null (no maximum) (Optional) + MinItems int // The minimum number of records this relationship must associate to the component type. Defaults to 0 (optional) (Optional) +} + +// RelationshipDefinitionType A dynamic definition for a relationship between one catalog entity to another +type RelationshipDefinitionType struct { + Alias string // The programmatic alias that can be used to reference the relationship in OpsLevel tooling (Required) + ComponentType ComponentTypeId // The component type that the relationship belongs to (Required) + Description string // The long-form descripion of what the relationship represents (Optional) + Id ID // The ID of the relationship definition (Required) + Metadata RelationshipDefinitionMetadata // JSON data that defines rules for how the relationship should be validated internally (Required) + Name string // The human-readable name for a relationship (Required) +} + +// RelationshipNode The relationship between two resources. A pair of source and destination resources +type RelationshipNode struct { + Destination RelationshipResource // The catalog item that a relationship points to (Required) + Id ID // The ID of the relationship (Required) + Source RelationshipResource // The catalog item that a relationship stems from (Required) +} + // RepositoryPath The repository path used for this service type RepositoryPath struct { Href string // The deep link to the repository path where the linked service's code exists (Required) diff --git a/relationship.go b/relationship.go new file mode 100644 index 00000000..dfd5586d --- /dev/null +++ b/relationship.go @@ -0,0 +1,44 @@ +package opslevel + +type RelationshipDefinitionPayload struct { + Definition RelationshipDefinitionType // The relationship that was defined. + BasePayload +} + +func (client *Client) CreateRelationshipDefinition(input RelationshipDefinitionInput) (*RelationshipDefinitionType, error) { + var m struct { + Payload RelationshipDefinitionPayload `graphql:"relationshipDefinitionCreate(input: $input)"` + } + v := PayloadVariables{ + "input": input, + } + err := client.Mutate(&m, v, WithName("RelationshipDefinitionCreate")) + return &m.Payload.Definition, HandleErrors(err, m.Payload.Errors) +} + +func (client *Client) UpdateRelationshipDefinition(identifier string, input RelationshipDefinitionInput) (*RelationshipDefinitionType, error) { + var m struct { + Payload RelationshipDefinitionPayload `graphql:"relationshipDefinitionUpdate(relationshipDefinition: $identifier, input: $input)"` + } + v := PayloadVariables{ + "identifier": NewIdentifier(identifier), + "input": input, + } + err := client.Mutate(&m, v, WithName("RelationshipDefinitionUpdate")) + return &m.Payload.Definition, HandleErrors(err, m.Payload.Errors) +} + +func (client *Client) DeleteRelationshipDefinition(identifier string) (*ID, error) { + var m struct { + Payload struct { + DeletedId ID `graphql:"deletedId"` + Errors []Error `graphql:"errors"` + } `graphql:"relationshipDefinitionDelete(resource: $input)"` + } + input := *NewIdentifier(identifier) + v := PayloadVariables{ + "input": input, + } + err := client.Mutate(&m, v, WithName("RelationshipDefinitionDelete")) + return &m.Payload.DeletedId, HandleErrors(err, m.Payload.Errors) +}