From b518cfdf70a0a87d2b2d8098b6efbb31fee7ec4b Mon Sep 17 00:00:00 2001 From: Michael Goff Date: Thu, 22 Sep 2022 16:56:51 -0700 Subject: [PATCH 1/4] Add `xrmResourceTree` to get a list of all descendantes of a given XRM Resource. Resovles #95 --- internal/graph/generated/generated.go | 541 ++++++++++++++++++++++++- internal/graph/model/generated.go | 28 ++ internal/graph/resolvers/query.go | 69 ++++ internal/graph/resolvers/query_test.go | 190 ++++++++- schema/queries.gql | 39 ++ 5 files changed, 863 insertions(+), 4 deletions(-) diff --git a/internal/graph/generated/generated.go b/internal/graph/generated/generated.go index 9fa1e8d..3efe8ff 100644 --- a/internal/graph/generated/generated.go +++ b/internal/graph/generated/generated.go @@ -577,6 +577,7 @@ type ComplexityRoot struct { ProviderRevisions func(childComplexity int, provider *model.ReferenceID, active *bool) int Providers func(childComplexity int) int Secret func(childComplexity int, namespace string, name string) int + XrmResourceTree func(childComplexity int, id model.ReferenceID) int } Secret struct { @@ -603,6 +604,16 @@ type ComplexityRoot struct { UpdateKubernetesResourcePayload struct { Resource func(childComplexity int) int } + + XRMResourceTreeConnection struct { + Nodes func(childComplexity int) int + TotalCount func(childComplexity int) int + } + + XRMResourceTreeNode struct { + ParentID func(childComplexity int) int + Resource func(childComplexity int) int + } } type CompositeResourceResolver interface { @@ -712,6 +723,7 @@ type QueryResolver interface { ConfigurationRevisions(ctx context.Context, configuration *model.ReferenceID, active *bool) (*model.ConfigurationRevisionConnection, error) CompositeResourceDefinitions(ctx context.Context, revision *model.ReferenceID, dangling *bool) (*model.CompositeResourceDefinitionConnection, error) Compositions(ctx context.Context, revision *model.ReferenceID, dangling *bool) (*model.CompositionConnection, error) + XrmResourceTree(ctx context.Context, id model.ReferenceID) (*model.XRMResourceTreeConnection, error) } type SecretResolver interface { Events(ctx context.Context, obj *model.Secret) (*model.EventConnection, error) @@ -2962,6 +2974,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Secret(childComplexity, args["namespace"].(string), args["name"].(string)), true + case "Query.xrmResourceTree": + if e.complexity.Query.XrmResourceTree == nil { + break + } + + args, err := ec.field_Query_xrmResourceTree_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.XrmResourceTree(childComplexity, args["id"].(model.ReferenceID)), true + case "Secret.apiVersion": if e.complexity.Secret.APIVersion == nil { break @@ -3058,6 +3082,34 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.UpdateKubernetesResourcePayload.Resource(childComplexity), true + case "XRMResourceTreeConnection.nodes": + if e.complexity.XRMResourceTreeConnection.Nodes == nil { + break + } + + return e.complexity.XRMResourceTreeConnection.Nodes(childComplexity), true + + case "XRMResourceTreeConnection.totalCount": + if e.complexity.XRMResourceTreeConnection.TotalCount == nil { + break + } + + return e.complexity.XRMResourceTreeConnection.TotalCount(childComplexity), true + + case "XRMResourceTreeNode.parentId": + if e.complexity.XRMResourceTreeNode.ParentID == nil { + break + } + + return e.complexity.XRMResourceTreeNode.ParentID(childComplexity), true + + case "XRMResourceTreeNode.resource": + if e.complexity.XRMResourceTreeNode.Resource == nil { + break + } + + return e.complexity.XRMResourceTreeNode.Resource(childComplexity), true + } return 0, false } @@ -5260,6 +5312,45 @@ type Query { """ dangling: Boolean = false ): CompositionConnection! + + """ + Get an ` + "`" + `XRMResource` + "`" + ` and its descendants which form a tree. + """ + xrmResourceTree( + "The ` + "`" + `ID` + "`" + ` of an ` + "`" + `XRMResource` + "`" + `" + id: ID! + ): XRMResourceTreeConnection! +} + +""" +A XRM Resource which is either a ` + "`" + `CompositeResource` + "`" + `, ` + "`" + `CompositeResourceClaim` + "`" + ` +or ` + "`" + `ManagedResource` + "`" + ` +""" +union XRMResource = CompositeResource | CompositeResourceClaim | ManagedResource + +""" +A ` + "`" + `XRMResourceTreeConnection` + "`" + ` reprsents a connection to ` + "`" + `XRMDescendant` + "`" + `s +""" +type XRMResourceTreeConnection { + "Connected nodes." + nodes: [XRMResourceTreeNode!] + + "The total number of connected nodes." + totalCount: Int! +} + +""" +An ` + "`" + `XRMResourceTreeNode` + "`" + ` is an ` + "`" + `XRMResource` + "`" + ` with a ` + "`" + `ID` + "`" + ` of its parent +` + "`" + `XRMResource` + "`" + `. + +Note: A ` + "`" + `NULL` + "`" + ` ` + "`" + `parentId` + "`" + ` represents the root of the descendant tree. +""" +type XRMResourceTreeNode { + "The ` + "`" + `ID` + "`" + ` of the parent ` + "`" + `XRMResource` + "`" + ` (` + "`" + `NULL` + "`" + ` is the root of the tree)" + parentId: ID + + "The ` + "`" + `XRMResource` + "`" + ` object of this ` + "`" + `XRMResourceTreeNode` + "`" + `" + resource: XRMResource! } """ @@ -5725,6 +5816,21 @@ func (ec *executionContext) field_Query_secret_args(ctx context.Context, rawArgs return args, nil } +func (ec *executionContext) field_Query_xrmResourceTree_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 model.ReferenceID + if tmp, ok := rawArgs["id"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + arg0, err = ec.unmarshalNID2githubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐReferenceID(ctx, tmp) + if err != nil { + return nil, err + } + } + args["id"] = arg0 + return args, nil +} + func (ec *executionContext) field_Secret_data_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -20552,6 +20658,67 @@ func (ec *executionContext) fieldContext_Query_compositions(ctx context.Context, return fc, nil } +func (ec *executionContext) _Query_xrmResourceTree(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_xrmResourceTree(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().XrmResourceTree(rctx, fc.Args["id"].(model.ReferenceID)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.XRMResourceTreeConnection) + fc.Result = res + return ec.marshalNXRMResourceTreeConnection2ᚖgithubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐXRMResourceTreeConnection(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_xrmResourceTree(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "nodes": + return ec.fieldContext_XRMResourceTreeConnection_nodes(ctx, field) + case "totalCount": + return ec.fieldContext_XRMResourceTreeConnection_totalCount(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type XRMResourceTreeConnection", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_xrmResourceTree_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return + } + return fc, nil +} + func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Query___type(ctx, field) if err != nil { @@ -21287,6 +21454,182 @@ func (ec *executionContext) fieldContext_UpdateKubernetesResourcePayload_resourc return fc, nil } +func (ec *executionContext) _XRMResourceTreeConnection_nodes(ctx context.Context, field graphql.CollectedField, obj *model.XRMResourceTreeConnection) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_XRMResourceTreeConnection_nodes(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Nodes, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]model.XRMResourceTreeNode) + fc.Result = res + return ec.marshalOXRMResourceTreeNode2ᚕgithubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐXRMResourceTreeNodeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_XRMResourceTreeConnection_nodes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "XRMResourceTreeConnection", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "parentId": + return ec.fieldContext_XRMResourceTreeNode_parentId(ctx, field) + case "resource": + return ec.fieldContext_XRMResourceTreeNode_resource(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type XRMResourceTreeNode", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _XRMResourceTreeConnection_totalCount(ctx context.Context, field graphql.CollectedField, obj *model.XRMResourceTreeConnection) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_XRMResourceTreeConnection_totalCount(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.TotalCount, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_XRMResourceTreeConnection_totalCount(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "XRMResourceTreeConnection", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _XRMResourceTreeNode_parentId(ctx context.Context, field graphql.CollectedField, obj *model.XRMResourceTreeNode) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_XRMResourceTreeNode_parentId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ParentID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.ReferenceID) + fc.Result = res + return ec.marshalOID2ᚖgithubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐReferenceID(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_XRMResourceTreeNode_parentId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "XRMResourceTreeNode", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _XRMResourceTreeNode_resource(ctx context.Context, field graphql.CollectedField, obj *model.XRMResourceTreeNode) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_XRMResourceTreeNode_resource(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Resource, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(model.XRMResource) + fc.Result = res + return ec.marshalNXRMResource2githubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐXRMResource(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_XRMResourceTreeNode_resource(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "XRMResourceTreeNode", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type XRMResource does not have child fields") + }, + } + return fc, nil +} + func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { fc, err := ec.fieldContext___Directive_name(ctx, field) if err != nil { @@ -23511,11 +23854,41 @@ func (ec *executionContext) _ProviderConfigDefinition(ctx context.Context, sel a } } +func (ec *executionContext) _XRMResource(ctx context.Context, sel ast.SelectionSet, obj model.XRMResource) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: + return graphql.Null + case model.CompositeResource: + return ec._CompositeResource(ctx, sel, &obj) + case *model.CompositeResource: + if obj == nil { + return graphql.Null + } + return ec._CompositeResource(ctx, sel, obj) + case model.CompositeResourceClaim: + return ec._CompositeResourceClaim(ctx, sel, &obj) + case *model.CompositeResourceClaim: + if obj == nil { + return graphql.Null + } + return ec._CompositeResourceClaim(ctx, sel, obj) + case model.ManagedResource: + return ec._ManagedResource(ctx, sel, &obj) + case *model.ManagedResource: + if obj == nil { + return graphql.Null + } + return ec._ManagedResource(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) + } +} + // endregion ************************** interface.gotpl *************************** // region **************************** object.gotpl **************************** -var compositeResourceImplementors = []string{"CompositeResource", "Node", "KubernetesResource"} +var compositeResourceImplementors = []string{"CompositeResource", "Node", "KubernetesResource", "XRMResource"} func (ec *executionContext) _CompositeResource(ctx context.Context, sel ast.SelectionSet, obj *model.CompositeResource) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, compositeResourceImplementors) @@ -23619,7 +23992,7 @@ func (ec *executionContext) _CompositeResource(ctx context.Context, sel ast.Sele return out } -var compositeResourceClaimImplementors = []string{"CompositeResourceClaim", "Node", "KubernetesResource"} +var compositeResourceClaimImplementors = []string{"CompositeResourceClaim", "Node", "KubernetesResource", "XRMResource"} func (ec *executionContext) _CompositeResourceClaim(ctx context.Context, sel ast.SelectionSet, obj *model.CompositeResourceClaim) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, compositeResourceClaimImplementors) @@ -26063,7 +26436,7 @@ func (ec *executionContext) _LocalObjectReference(ctx context.Context, sel ast.S return out } -var managedResourceImplementors = []string{"ManagedResource", "Node", "KubernetesResource"} +var managedResourceImplementors = []string{"ManagedResource", "Node", "KubernetesResource", "XRMResource"} func (ec *executionContext) _ManagedResource(ctx context.Context, sel ast.SelectionSet, obj *model.ManagedResource) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, managedResourceImplementors) @@ -27457,6 +27830,29 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) } + out.Concurrently(i, func() graphql.Marshaler { + return rrm(innerCtx) + }) + case "xrmResourceTree": + field := field + + innerFunc := func(ctx context.Context) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_xrmResourceTree(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, innerFunc) + } + out.Concurrently(i, func() graphql.Marshaler { return rrm(innerCtx) }) @@ -27662,6 +28058,70 @@ func (ec *executionContext) _UpdateKubernetesResourcePayload(ctx context.Context return out } +var xRMResourceTreeConnectionImplementors = []string{"XRMResourceTreeConnection"} + +func (ec *executionContext) _XRMResourceTreeConnection(ctx context.Context, sel ast.SelectionSet, obj *model.XRMResourceTreeConnection) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, xRMResourceTreeConnectionImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("XRMResourceTreeConnection") + case "nodes": + + out.Values[i] = ec._XRMResourceTreeConnection_nodes(ctx, field, obj) + + case "totalCount": + + out.Values[i] = ec._XRMResourceTreeConnection_totalCount(ctx, field, obj) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var xRMResourceTreeNodeImplementors = []string{"XRMResourceTreeNode"} + +func (ec *executionContext) _XRMResourceTreeNode(ctx context.Context, sel ast.SelectionSet, obj *model.XRMResourceTreeNode) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, xRMResourceTreeNodeImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("XRMResourceTreeNode") + case "parentId": + + out.Values[i] = ec._XRMResourceTreeNode_parentId(ctx, field, obj) + + case "resource": + + out.Values[i] = ec._XRMResourceTreeNode_resource(ctx, field, obj) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + var __DirectiveImplementors = []string{"__Directive"} func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { @@ -28568,6 +29028,34 @@ func (ec *executionContext) marshalNUpdateKubernetesResourcePayload2ᚖgithubᚗ return ec._UpdateKubernetesResourcePayload(ctx, sel, v) } +func (ec *executionContext) marshalNXRMResource2githubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐXRMResource(ctx context.Context, sel ast.SelectionSet, v model.XRMResource) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._XRMResource(ctx, sel, v) +} + +func (ec *executionContext) marshalNXRMResourceTreeConnection2githubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐXRMResourceTreeConnection(ctx context.Context, sel ast.SelectionSet, v model.XRMResourceTreeConnection) graphql.Marshaler { + return ec._XRMResourceTreeConnection(ctx, sel, &v) +} + +func (ec *executionContext) marshalNXRMResourceTreeConnection2ᚖgithubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐXRMResourceTreeConnection(ctx context.Context, sel ast.SelectionSet, v *model.XRMResourceTreeConnection) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._XRMResourceTreeConnection(ctx, sel, v) +} + +func (ec *executionContext) marshalNXRMResourceTreeNode2githubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐXRMResourceTreeNode(ctx context.Context, sel ast.SelectionSet, v model.XRMResourceTreeNode) graphql.Marshaler { + return ec._XRMResourceTreeNode(ctx, sel, &v) +} + func (ec *executionContext) marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx context.Context, sel ast.SelectionSet, v introspection.Directive) graphql.Marshaler { return ec.___Directive(ctx, sel, &v) } @@ -30069,6 +30557,53 @@ func (ec *executionContext) marshalOTypeReference2ᚖgithubᚗcomᚋupboundᚋxg return ec._TypeReference(ctx, sel, v) } +func (ec *executionContext) marshalOXRMResourceTreeNode2ᚕgithubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐXRMResourceTreeNodeᚄ(ctx context.Context, sel ast.SelectionSet, v []model.XRMResourceTreeNode) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNXRMResourceTreeNode2githubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐXRMResourceTreeNode(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { if v == nil { return graphql.Null diff --git a/internal/graph/model/generated.go b/internal/graph/model/generated.go index a606ac3..7086b79 100644 --- a/internal/graph/model/generated.go +++ b/internal/graph/model/generated.go @@ -43,6 +43,12 @@ type ProviderConfigDefinition interface { IsProviderConfigDefinition() } +// A XRM Resource which is either a `CompositeResource`, `CompositeResourceClaim` +// or `ManagedResource` +type XRMResource interface { + IsXRMResource() +} + // A CompositeResource is a resource this is reconciled by composing other // composite or managed resources. Composite resources use a Composition to // determine which resources to compose, and how. @@ -69,6 +75,7 @@ type CompositeResource struct { func (CompositeResource) IsNode() {} func (CompositeResource) IsKubernetesResource() {} +func (CompositeResource) IsXRMResource() {} // A CompositeResourceClaim is a namespaced proxy for a composite resource. type CompositeResourceClaim struct { @@ -94,6 +101,7 @@ type CompositeResourceClaim struct { func (CompositeResourceClaim) IsNode() {} func (CompositeResourceClaim) IsKubernetesResource() {} +func (CompositeResourceClaim) IsXRMResource() {} // A CompositeResourceConnection represents a connection to composite resource // claims. @@ -675,6 +683,7 @@ type ManagedResource struct { func (ManagedResource) IsNode() {} func (ManagedResource) IsKubernetesResource() {} +func (ManagedResource) IsXRMResource() {} // A ManagedResourceStatus represents the observed state of a managed resource. type ManagedResourceStatus struct { @@ -959,6 +968,25 @@ type UpdateKubernetesResourcePayload struct { Resource KubernetesResource `json:"resource"` } +// A `XRMResourceTreeConnection` reprsents a connection to `XRMDescendant`s +type XRMResourceTreeConnection struct { + // Connected nodes. + Nodes []XRMResourceTreeNode `json:"nodes"` + // The total number of connected nodes. + TotalCount int `json:"totalCount"` +} + +// An `XRMResourceTreeNode` is an `XRMResource` with a `ID` of its parent +// `XRMResource`. +// +// Note: A `NULL` `parentId` represents the root of the descendant tree. +type XRMResourceTreeNode struct { + // The `ID` of the parent `XRMResource` (`NULL` is the root of the tree) + ParentID *ReferenceID `json:"parentId"` + // The `XRMResource` object of this `XRMResourceTreeNode` + Resource XRMResource `json:"resource"` +} + // A ConditionStatus represensts the status of a condition. type ConditionStatus string diff --git a/internal/graph/resolvers/query.go b/internal/graph/resolvers/query.go index bd3093e..25e7e0d 100644 --- a/internal/graph/resolvers/query.go +++ b/internal/graph/resolvers/query.go @@ -16,6 +16,7 @@ package resolvers import ( "context" + "fmt" "sort" "github.com/99designs/gqlgen/graphql" @@ -50,6 +51,74 @@ type query struct { clients ClientCache } +// Recursively collect `XRMResourceTreeNode`s from the given KubernetesResource +func (r *query) getAllDecedents(ctx context.Context, res model.KubernetesResource, parentID *model.ReferenceID) ([]model.XRMResourceTreeNode, error) { //nolint:gocyclo + // This isn't _really_ that complex; it's a long but simple switch. + + switch typedRes := res.(type) { + case model.CompositeResource: + list := []model.XRMResourceTreeNode{{ParentID: parentID, Resource: typedRes}} + + compositeResolver := compositeResourceSpec{clients: r.clients} + resources, err := compositeResolver.Resources(ctx, typedRes.Spec) + if err != nil || len(graphql.GetErrors(ctx)) > 0 { + return nil, err + } + + for _, childRes := range resources.Nodes { + childList, err := r.getAllDecedents(ctx, childRes, &typedRes.ID) + if err != nil || len(graphql.GetErrors(ctx)) > 0 { + return nil, err + } + + list = append(list, childList...) + } + + return list, nil + case model.CompositeResourceClaim: + list := []model.XRMResourceTreeNode{{ParentID: parentID, Resource: typedRes}} + + claimResolver := compositeResourceClaimSpec{clients: r.clients} + composite, err := claimResolver.Resource(ctx, typedRes.Spec) + if err != nil || len(graphql.GetErrors(ctx)) > 0 { + return nil, err + } + + if composite == nil { + return list, nil + } + + childList, err := r.getAllDecedents(ctx, *composite, &typedRes.ID) + if err != nil || len(graphql.GetErrors(ctx)) > 0 { + return nil, err + } + + return append(list, childList...), nil + case model.ManagedResource: + return []model.XRMResourceTreeNode{{ParentID: parentID, Resource: typedRes}}, nil + default: + graphql.AddError(ctx, fmt.Errorf("was not a `CompositeResource`, `CompositeResourceClaim`, or `ManagedResource` got: %T", res)) + return nil, nil + } +} + +func (r *query) XrmResourceTree(ctx context.Context, id model.ReferenceID) (*model.XRMResourceTreeConnection, error) { + ctx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + + rootRes, err := r.KubernetesResource(ctx, id) + if err != nil || len(graphql.GetErrors(ctx)) > 0 { + return nil, err + } + + list, err := r.getAllDecedents(ctx, rootRes, nil) + if err != nil || len(graphql.GetErrors(ctx)) > 0 { + return nil, err + } + + return &model.XRMResourceTreeConnection{Nodes: list, TotalCount: len(list)}, nil +} + func (r *query) KubernetesResource(ctx context.Context, id model.ReferenceID) (model.KubernetesResource, error) { ctx, cancel := context.WithTimeout(ctx, timeout) defer cancel() diff --git a/internal/graph/resolvers/query_test.go b/internal/graph/resolvers/query_test.go index ec15ad6..533b138 100644 --- a/internal/graph/resolvers/query_test.go +++ b/internal/graph/resolvers/query_test.go @@ -32,6 +32,7 @@ import ( "github.com/google/go-cmp/cmp/cmpopts" "sigs.k8s.io/controller-runtime/pkg/client" + "github.com/crossplane/crossplane-runtime/pkg/fieldpath" "github.com/crossplane/crossplane-runtime/pkg/test" extv1 "github.com/crossplane/crossplane/apis/apiextensions/v1" pkgv1 "github.com/crossplane/crossplane/apis/pkg/v1" @@ -44,6 +45,193 @@ import ( var _ generated.QueryResolver = &query{} +func TestXrmResourceTree(t *testing.T) { + errBoom := errors.New("boom") + + type args struct { + ctx context.Context + id model.ReferenceID + } + type want struct { + kr *model.XRMResourceTreeConnection + err error + errs gqlerror.List + } + + namespace := "default" + deletionPolicyDelete := model.DeletionPolicyDelete + + cases := map[string]struct { + reason string + clients ClientCache + args args + want want + }{ + "GetKubernetesResourceError": { + reason: "If we can't get a client we should add the error to the GraphQL context and return early.", + clients: ClientCacheFn(func(_ auth.Credentials, _ ...clients.GetOption) (client.Client, error) { + return &test.MockClient{}, errBoom + }), + args: args{ + ctx: graphql.WithResponseContext(context.Background(), graphql.DefaultErrorPresenter, graphql.DefaultRecover), + }, + want: want{ + errs: gqlerror.List{ + gqlerror.Errorf(errors.Wrap(errBoom, errGetClient).Error()), + }, + }, + }, + "getAllDecendentsNotXRMResourceError": { + reason: "If the passed resource ID is not for a XRMResource we error", + clients: ClientCacheFn(func(_ auth.Credentials, _ ...clients.GetOption) (client.Client, error) { + return &test.MockClient{ + MockGet: test.NewMockGetFn(nil), + }, nil + }), + args: args{ + ctx: graphql.WithResponseContext(context.Background(), graphql.DefaultErrorPresenter, graphql.DefaultRecover), + }, + want: want{ + errs: gqlerror.List{ + gqlerror.Errorf("was not a `CompositeResource`, `CompositeResourceClaim`, or `ManagedResource` got: model.GenericResource"), + }, + }, + }, + "SuccessWithNoComposite": { + reason: "It is a successful call", + clients: ClientCacheFn(func(_ auth.Credentials, _ ...clients.GetOption) (client.Client, error) { + return &test.MockClient{ + MockGet: func(_ context.Context, key client.ObjectKey, obj client.Object) error { + switch key.Name { + case "root": + u := *obj.(*unstructured.Unstructured) + u.SetNamespace(namespace) + fieldpath.Pave(u.Object).SetValue("spec.compositionRef", &corev1.ObjectReference{ + Name: "coolcomposition", + }) + default: + t.Fatalf("unknown get with name: %s", key.Name) + } + return nil + }, + }, nil + }), + args: args{ + ctx: graphql.WithResponseContext(context.Background(), graphql.DefaultErrorPresenter, graphql.DefaultRecover), + id: model.ReferenceID{Name: "root"}, + }, + want: want{ + kr: &model.XRMResourceTreeConnection{TotalCount: 1, Nodes: []model.XRMResourceTreeNode{ + { + Resource: model.CompositeResourceClaim{ + ID: model.ReferenceID{Namespace: namespace}, + Metadata: &model.ObjectMeta{Namespace: &namespace}, + Spec: &model.CompositeResourceClaimSpec{CompositionReference: &corev1.ObjectReference{Name: "coolcomposition"}}, + }, + }, + }}, + }, + }, + "Success": { + reason: "It is a successful call", + clients: ClientCacheFn(func(_ auth.Credentials, _ ...clients.GetOption) (client.Client, error) { + return &test.MockClient{ + MockGet: func(_ context.Context, key client.ObjectKey, obj client.Object) error { + u := *obj.(*unstructured.Unstructured) + u.SetName(key.Name) + + switch key.Name { + case "root": + u.SetNamespace(namespace) + fieldpath.Pave(u.Object).SetValue("spec.resourceRef", &corev1.ObjectReference{Name: "composite"}) + case "composite": + fieldpath.Pave(u.Object).SetValue("spec.resourceRefs", []corev1.ObjectReference{{Name: "managed1"}, {Name: "child-composite"}}) + case "child-composite": + fieldpath.Pave(u.Object).SetValue("spec.resourceRefs", []corev1.ObjectReference{{Name: "managed2"}}) + case "managed1": + fallthrough + case "managed2": + fieldpath.Pave(u.Object).SetValue("spec.providerConfigRef.name", "") + default: + t.Fatalf("unknown get with name: %s", key.Name) + } + return nil + }, + }, nil + }), + args: args{ + ctx: graphql.WithResponseContext(context.Background(), graphql.DefaultErrorPresenter, graphql.DefaultRecover), + id: model.ReferenceID{Name: "root"}, + }, + want: want{ + kr: &model.XRMResourceTreeConnection{TotalCount: 5, Nodes: []model.XRMResourceTreeNode{ + { + Resource: model.CompositeResourceClaim{ + ID: model.ReferenceID{Namespace: namespace, Name: "root"}, + Metadata: &model.ObjectMeta{Namespace: &namespace, Name: "root"}, + Spec: &model.CompositeResourceClaimSpec{ResourceReference: &corev1.ObjectReference{Name: "composite"}}, + }, + }, + { + ParentID: &model.ReferenceID{Namespace: "default", Name: "root"}, + Resource: model.CompositeResource{ + ID: model.ReferenceID{Name: "composite"}, + Metadata: &model.ObjectMeta{Name: "composite"}, + Spec: &model.CompositeResourceSpec{ResourceReferences: []corev1.ObjectReference{{Name: "managed1"}, {Name: "child-composite"}}}, + }, + }, + { + ParentID: &model.ReferenceID{Name: "composite"}, + Resource: model.CompositeResource{ + ID: model.ReferenceID{Name: "child-composite"}, + Metadata: &model.ObjectMeta{Name: "child-composite"}, + Spec: &model.CompositeResourceSpec{ResourceReferences: []corev1.ObjectReference{{Name: "managed2"}}}, + }, + }, + { + ParentID: &model.ReferenceID{Name: "child-composite"}, + Resource: model.ManagedResource{ + ID: model.ReferenceID{Name: "managed2"}, + Metadata: &model.ObjectMeta{Name: "managed2"}, + Spec: &model.ManagedResourceSpec{ProviderConfigRef: &model.ProviderConfigReference{}, DeletionPolicy: &deletionPolicyDelete}, + }, + }, + { + ParentID: &model.ReferenceID{Name: "composite"}, + Resource: model.ManagedResource{ + ID: model.ReferenceID{Name: "managed1"}, + Metadata: &model.ObjectMeta{Name: "managed1"}, + Spec: &model.ManagedResourceSpec{ProviderConfigRef: &model.ProviderConfigReference{}, DeletionPolicy: &deletionPolicyDelete}, + }, + }, + }}, + }, + }, + } + + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + q := &query{clients: tc.clients} + + // Our GraphQL resolvers never return errors. We instead add an + // error to the GraphQL context and return early. + got, err := q.XrmResourceTree(tc.args.ctx, tc.args.id) + errs := graphql.GetErrors(tc.args.ctx) + + if diff := cmp.Diff(tc.want.err, err, test.EquateErrors()); diff != "" { + t.Errorf("\n%s\ns.KubernetesResource(...): -want error, +got error:\n%s\n", tc.reason, diff) + } + if diff := cmp.Diff(tc.want.errs, errs, test.EquateErrors()); diff != "" { + t.Errorf("\n%s\ns.KubernetesResource(...): -want GraphQL errors, +got GraphQL errors:\n%s\n", tc.reason, diff) + } + + if diff := cmp.Diff(tc.want.kr, got, cmpopts.IgnoreFields(model.CompositeResourceClaim{}, "Unstructured"), cmpopts.IgnoreFields(model.CompositeResource{}, "Unstructured"), cmpopts.IgnoreFields(model.ManagedResource{}, "Unstructured"), cmpopts.IgnoreUnexported(model.ObjectMeta{})); diff != "" { + t.Errorf("\n%s\ns.KubernetesResource(...): -want, +got:\n%s\n", tc.reason, diff) + } + }) + } +} + func TestQueryKubernetesResource(t *testing.T) { errBoom := errors.New("boom") @@ -96,7 +284,7 @@ func TestQueryKubernetesResource(t *testing.T) { }, }, "Success": { - reason: "If we can get and model the resource we should return it.", + reason: "If we can get and model the resource we should return it.", clients: ClientCacheFn(func(_ auth.Credentials, _ ...clients.GetOption) (client.Client, error) { return &test.MockClient{ MockGet: test.NewMockGetFn(nil), diff --git a/schema/queries.gql b/schema/queries.gql index 0f1b60c..dac8cb0 100644 --- a/schema/queries.gql +++ b/schema/queries.gql @@ -155,6 +155,45 @@ type Query { """ dangling: Boolean = false ): CompositionConnection! + + """ + Get an `XRMResource` and its descendants which form a tree. + """ + xrmResourceTree( + "The `ID` of an `XRMResource`" + id: ID! + ): XRMResourceTreeConnection! +} + +""" +A XRM Resource which is either a `CompositeResource`, `CompositeResourceClaim` +or `ManagedResource` +""" +union XRMResource = CompositeResource | CompositeResourceClaim | ManagedResource + +""" +A `XRMResourceTreeConnection` reprsents a connection to `XRMDescendant`s +""" +type XRMResourceTreeConnection { + "Connected nodes." + nodes: [XRMResourceTreeNode!] + + "The total number of connected nodes." + totalCount: Int! +} + +""" +An `XRMResourceTreeNode` is an `XRMResource` with a `ID` of its parent +`XRMResource`. + +Note: A `NULL` `parentId` represents the root of the descendant tree. +""" +type XRMResourceTreeNode { + "The `ID` of the parent `XRMResource` (`NULL` is the root of the tree)" + parentId: ID + + "The `XRMResource` object of this `XRMResourceTreeNode`" + resource: XRMResource! } """ From 5650c0d37e6f7901ae8f06abc07257eb47a52fbe Mon Sep 17 00:00:00 2001 From: Michael Goff Date: Mon, 26 Sep 2022 15:30:04 -0700 Subject: [PATCH 2/4] Update schema/queries.gql Co-authored-by: Nic Cope --- schema/queries.gql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema/queries.gql b/schema/queries.gql index dac8cb0..7581ca9 100644 --- a/schema/queries.gql +++ b/schema/queries.gql @@ -172,7 +172,7 @@ or `ManagedResource` union XRMResource = CompositeResource | CompositeResourceClaim | ManagedResource """ -A `XRMResourceTreeConnection` reprsents a connection to `XRMDescendant`s +A `XRMResourceTreeConnection` represents a connection to `XRMDescendant`s """ type XRMResourceTreeConnection { "Connected nodes." From d1c4d3aae9a7c8ee62fc4aa229b5de61576d28a9 Mon Sep 17 00:00:00 2001 From: Michael Goff Date: Mon, 26 Sep 2022 16:06:03 -0700 Subject: [PATCH 3/4] Changes due to code review (will be squashed) --- internal/graph/generated/generated.go | 915 +++++++++++++------------ internal/graph/model/generated.go | 57 +- internal/graph/resolvers/query.go | 16 +- internal/graph/resolvers/query_test.go | 38 +- schema/queries.gql | 32 +- 5 files changed, 547 insertions(+), 511 deletions(-) diff --git a/internal/graph/generated/generated.go b/internal/graph/generated/generated.go index 3efe8ff..ce91ffc 100644 --- a/internal/graph/generated/generated.go +++ b/internal/graph/generated/generated.go @@ -312,6 +312,16 @@ type ComplexityRoot struct { Resource func(childComplexity int) int } + CrossplaneResourceTreeConnection struct { + Nodes func(childComplexity int) int + TotalCount func(childComplexity int) int + } + + CrossplaneResourceTreeNode struct { + ParentID func(childComplexity int) int + Resource func(childComplexity int) int + } + CustomResourceDefinition struct { APIVersion func(childComplexity int) int DefinedResources func(childComplexity int, version *string) int @@ -570,6 +580,7 @@ type ComplexityRoot struct { ConfigMap func(childComplexity int, namespace string, name string) int ConfigurationRevisions func(childComplexity int, configuration *model.ReferenceID, active *bool) int Configurations func(childComplexity int) int + CrossplaneResourceTree func(childComplexity int, id model.ReferenceID) int CustomResourceDefinitions func(childComplexity int, revision *model.ReferenceID) int Events func(childComplexity int, involved *model.ReferenceID) int KubernetesResource func(childComplexity int, id model.ReferenceID) int @@ -577,7 +588,6 @@ type ComplexityRoot struct { ProviderRevisions func(childComplexity int, provider *model.ReferenceID, active *bool) int Providers func(childComplexity int) int Secret func(childComplexity int, namespace string, name string) int - XrmResourceTree func(childComplexity int, id model.ReferenceID) int } Secret struct { @@ -604,16 +614,6 @@ type ComplexityRoot struct { UpdateKubernetesResourcePayload struct { Resource func(childComplexity int) int } - - XRMResourceTreeConnection struct { - Nodes func(childComplexity int) int - TotalCount func(childComplexity int) int - } - - XRMResourceTreeNode struct { - ParentID func(childComplexity int) int - Resource func(childComplexity int) int - } } type CompositeResourceResolver interface { @@ -723,7 +723,7 @@ type QueryResolver interface { ConfigurationRevisions(ctx context.Context, configuration *model.ReferenceID, active *bool) (*model.ConfigurationRevisionConnection, error) CompositeResourceDefinitions(ctx context.Context, revision *model.ReferenceID, dangling *bool) (*model.CompositeResourceDefinitionConnection, error) Compositions(ctx context.Context, revision *model.ReferenceID, dangling *bool) (*model.CompositionConnection, error) - XrmResourceTree(ctx context.Context, id model.ReferenceID) (*model.XRMResourceTreeConnection, error) + CrossplaneResourceTree(ctx context.Context, id model.ReferenceID) (*model.CrossplaneResourceTreeConnection, error) } type SecretResolver interface { Events(ctx context.Context, obj *model.Secret) (*model.EventConnection, error) @@ -1781,6 +1781,34 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.CreateKubernetesResourcePayload.Resource(childComplexity), true + case "CrossplaneResourceTreeConnection.nodes": + if e.complexity.CrossplaneResourceTreeConnection.Nodes == nil { + break + } + + return e.complexity.CrossplaneResourceTreeConnection.Nodes(childComplexity), true + + case "CrossplaneResourceTreeConnection.totalCount": + if e.complexity.CrossplaneResourceTreeConnection.TotalCount == nil { + break + } + + return e.complexity.CrossplaneResourceTreeConnection.TotalCount(childComplexity), true + + case "CrossplaneResourceTreeNode.parentId": + if e.complexity.CrossplaneResourceTreeNode.ParentID == nil { + break + } + + return e.complexity.CrossplaneResourceTreeNode.ParentID(childComplexity), true + + case "CrossplaneResourceTreeNode.resource": + if e.complexity.CrossplaneResourceTreeNode.Resource == nil { + break + } + + return e.complexity.CrossplaneResourceTreeNode.Resource(childComplexity), true + case "CustomResourceDefinition.apiVersion": if e.complexity.CustomResourceDefinition.APIVersion == nil { break @@ -2895,6 +2923,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Configurations(childComplexity), true + case "Query.crossplaneResourceTree": + if e.complexity.Query.CrossplaneResourceTree == nil { + break + } + + args, err := ec.field_Query_crossplaneResourceTree_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.CrossplaneResourceTree(childComplexity, args["id"].(model.ReferenceID)), true + case "Query.customResourceDefinitions": if e.complexity.Query.CustomResourceDefinitions == nil { break @@ -2974,18 +3014,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Secret(childComplexity, args["namespace"].(string), args["name"].(string)), true - case "Query.xrmResourceTree": - if e.complexity.Query.XrmResourceTree == nil { - break - } - - args, err := ec.field_Query_xrmResourceTree_args(context.TODO(), rawArgs) - if err != nil { - return 0, false - } - - return e.complexity.Query.XrmResourceTree(childComplexity, args["id"].(model.ReferenceID)), true - case "Secret.apiVersion": if e.complexity.Secret.APIVersion == nil { break @@ -3082,34 +3110,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.UpdateKubernetesResourcePayload.Resource(childComplexity), true - case "XRMResourceTreeConnection.nodes": - if e.complexity.XRMResourceTreeConnection.Nodes == nil { - break - } - - return e.complexity.XRMResourceTreeConnection.Nodes(childComplexity), true - - case "XRMResourceTreeConnection.totalCount": - if e.complexity.XRMResourceTreeConnection.TotalCount == nil { - break - } - - return e.complexity.XRMResourceTreeConnection.TotalCount(childComplexity), true - - case "XRMResourceTreeNode.parentId": - if e.complexity.XRMResourceTreeNode.ParentID == nil { - break - } - - return e.complexity.XRMResourceTreeNode.ParentID(childComplexity), true - - case "XRMResourceTreeNode.resource": - if e.complexity.XRMResourceTreeNode.Resource == nil { - break - } - - return e.complexity.XRMResourceTreeNode.Resource(childComplexity), true - } return 0, false } @@ -5314,43 +5314,47 @@ type Query { ): CompositionConnection! """ - Get an ` + "`" + `XRMResource` + "`" + ` and its descendants which form a tree. + Get an ` + "`" + `CrossplaneResource` + "`" + ` and its descendants which form a tree. """ - xrmResourceTree( - "The ` + "`" + `ID` + "`" + ` of an ` + "`" + `XRMResource` + "`" + `" + crossplaneResourceTree( + "The ` + "`" + `ID` + "`" + ` of an ` + "`" + `CrossplaneResource` + "`" + `" id: ID! - ): XRMResourceTreeConnection! + ): CrossplaneResourceTreeConnection! } """ A XRM Resource which is either a ` + "`" + `CompositeResource` + "`" + `, ` + "`" + `CompositeResourceClaim` + "`" + ` or ` + "`" + `ManagedResource` + "`" + ` """ -union XRMResource = CompositeResource | CompositeResourceClaim | ManagedResource +union CrossplaneResource = + CompositeResource + | CompositeResourceClaim + | ManagedResource + | ProviderConfig """ -A ` + "`" + `XRMResourceTreeConnection` + "`" + ` reprsents a connection to ` + "`" + `XRMDescendant` + "`" + `s +A ` + "`" + `CrossplaneResourceTreeConnection` + "`" + ` represents a connection to ` + "`" + `XRMDescendant` + "`" + `s """ -type XRMResourceTreeConnection { +type CrossplaneResourceTreeConnection { "Connected nodes." - nodes: [XRMResourceTreeNode!] + nodes: [CrossplaneResourceTreeNode!] "The total number of connected nodes." totalCount: Int! } """ -An ` + "`" + `XRMResourceTreeNode` + "`" + ` is an ` + "`" + `XRMResource` + "`" + ` with a ` + "`" + `ID` + "`" + ` of its parent -` + "`" + `XRMResource` + "`" + `. +An ` + "`" + `CrossplaneResourceTreeNode` + "`" + ` is an ` + "`" + `CrossplaneResource` + "`" + ` with a ` + "`" + `ID` + "`" + ` of its parent +` + "`" + `CrossplaneResource` + "`" + `. Note: A ` + "`" + `NULL` + "`" + ` ` + "`" + `parentId` + "`" + ` represents the root of the descendant tree. """ -type XRMResourceTreeNode { - "The ` + "`" + `ID` + "`" + ` of the parent ` + "`" + `XRMResource` + "`" + ` (` + "`" + `NULL` + "`" + ` is the root of the tree)" +type CrossplaneResourceTreeNode { + "The ` + "`" + `ID` + "`" + ` of the parent ` + "`" + `CrossplaneResource` + "`" + ` (` + "`" + `NULL` + "`" + ` is the root of the tree)" parentId: ID - "The ` + "`" + `XRMResource` + "`" + ` object of this ` + "`" + `XRMResourceTreeNode` + "`" + `" - resource: XRMResource! + "The ` + "`" + `CrossplaneResource` + "`" + ` object of this ` + "`" + `CrossplaneResourceTreeNode` + "`" + `" + resource: CrossplaneResource! } """ @@ -5681,6 +5685,21 @@ func (ec *executionContext) field_Query_configurationRevisions_args(ctx context. return args, nil } +func (ec *executionContext) field_Query_crossplaneResourceTree_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 model.ReferenceID + if tmp, ok := rawArgs["id"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + arg0, err = ec.unmarshalNID2githubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐReferenceID(ctx, tmp) + if err != nil { + return nil, err + } + } + args["id"] = arg0 + return args, nil +} + func (ec *executionContext) field_Query_customResourceDefinitions_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -5816,21 +5835,6 @@ func (ec *executionContext) field_Query_secret_args(ctx context.Context, rawArgs return args, nil } -func (ec *executionContext) field_Query_xrmResourceTree_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 model.ReferenceID - if tmp, ok := rawArgs["id"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) - arg0, err = ec.unmarshalNID2githubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐReferenceID(ctx, tmp) - if err != nil { - return nil, err - } - } - args["id"] = arg0 - return args, nil -} - func (ec *executionContext) field_Secret_data_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -13039,6 +13043,182 @@ func (ec *executionContext) fieldContext_CreateKubernetesResourcePayload_resourc return fc, nil } +func (ec *executionContext) _CrossplaneResourceTreeConnection_nodes(ctx context.Context, field graphql.CollectedField, obj *model.CrossplaneResourceTreeConnection) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_CrossplaneResourceTreeConnection_nodes(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Nodes, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]model.CrossplaneResourceTreeNode) + fc.Result = res + return ec.marshalOCrossplaneResourceTreeNode2ᚕgithubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐCrossplaneResourceTreeNodeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_CrossplaneResourceTreeConnection_nodes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CrossplaneResourceTreeConnection", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "parentId": + return ec.fieldContext_CrossplaneResourceTreeNode_parentId(ctx, field) + case "resource": + return ec.fieldContext_CrossplaneResourceTreeNode_resource(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type CrossplaneResourceTreeNode", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _CrossplaneResourceTreeConnection_totalCount(ctx context.Context, field graphql.CollectedField, obj *model.CrossplaneResourceTreeConnection) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_CrossplaneResourceTreeConnection_totalCount(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.TotalCount, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_CrossplaneResourceTreeConnection_totalCount(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CrossplaneResourceTreeConnection", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _CrossplaneResourceTreeNode_parentId(ctx context.Context, field graphql.CollectedField, obj *model.CrossplaneResourceTreeNode) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_CrossplaneResourceTreeNode_parentId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ParentID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.ReferenceID) + fc.Result = res + return ec.marshalOID2ᚖgithubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐReferenceID(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_CrossplaneResourceTreeNode_parentId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CrossplaneResourceTreeNode", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _CrossplaneResourceTreeNode_resource(ctx context.Context, field graphql.CollectedField, obj *model.CrossplaneResourceTreeNode) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_CrossplaneResourceTreeNode_resource(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Resource, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(model.CrossplaneResource) + fc.Result = res + return ec.marshalNCrossplaneResource2githubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐCrossplaneResource(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_CrossplaneResourceTreeNode_resource(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "CrossplaneResourceTreeNode", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type CrossplaneResource does not have child fields") + }, + } + return fc, nil +} + func (ec *executionContext) _CustomResourceDefinition_id(ctx context.Context, field graphql.CollectedField, obj *model.CustomResourceDefinition) (ret graphql.Marshaler) { fc, err := ec.fieldContext_CustomResourceDefinition_id(ctx, field) if err != nil { @@ -20658,8 +20838,8 @@ func (ec *executionContext) fieldContext_Query_compositions(ctx context.Context, return fc, nil } -func (ec *executionContext) _Query_xrmResourceTree(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Query_xrmResourceTree(ctx, field) +func (ec *executionContext) _Query_crossplaneResourceTree(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_crossplaneResourceTree(ctx, field) if err != nil { return graphql.Null } @@ -20672,7 +20852,7 @@ func (ec *executionContext) _Query_xrmResourceTree(ctx context.Context, field gr }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Query().XrmResourceTree(rctx, fc.Args["id"].(model.ReferenceID)) + return ec.resolvers.Query().CrossplaneResourceTree(rctx, fc.Args["id"].(model.ReferenceID)) }) if err != nil { ec.Error(ctx, err) @@ -20684,12 +20864,12 @@ func (ec *executionContext) _Query_xrmResourceTree(ctx context.Context, field gr } return graphql.Null } - res := resTmp.(*model.XRMResourceTreeConnection) + res := resTmp.(*model.CrossplaneResourceTreeConnection) fc.Result = res - return ec.marshalNXRMResourceTreeConnection2ᚖgithubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐXRMResourceTreeConnection(ctx, field.Selections, res) + return ec.marshalNCrossplaneResourceTreeConnection2ᚖgithubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐCrossplaneResourceTreeConnection(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Query_xrmResourceTree(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Query_crossplaneResourceTree(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Query", Field: field, @@ -20698,11 +20878,11 @@ func (ec *executionContext) fieldContext_Query_xrmResourceTree(ctx context.Conte Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "nodes": - return ec.fieldContext_XRMResourceTreeConnection_nodes(ctx, field) + return ec.fieldContext_CrossplaneResourceTreeConnection_nodes(ctx, field) case "totalCount": - return ec.fieldContext_XRMResourceTreeConnection_totalCount(ctx, field) + return ec.fieldContext_CrossplaneResourceTreeConnection_totalCount(ctx, field) } - return nil, fmt.Errorf("no field named %q was found under type XRMResourceTreeConnection", field.Name) + return nil, fmt.Errorf("no field named %q was found under type CrossplaneResourceTreeConnection", field.Name) }, } defer func() { @@ -20712,7 +20892,7 @@ func (ec *executionContext) fieldContext_Query_xrmResourceTree(ctx context.Conte } }() ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Query_xrmResourceTree_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + if fc.Args, err = ec.field_Query_crossplaneResourceTree_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) return } @@ -21454,8 +21634,8 @@ func (ec *executionContext) fieldContext_UpdateKubernetesResourcePayload_resourc return fc, nil } -func (ec *executionContext) _XRMResourceTreeConnection_nodes(ctx context.Context, field graphql.CollectedField, obj *model.XRMResourceTreeConnection) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_XRMResourceTreeConnection_nodes(ctx, field) +func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_name(ctx, field) if err != nil { return graphql.Null } @@ -21468,202 +21648,26 @@ func (ec *executionContext) _XRMResourceTreeConnection_nodes(ctx context.Context }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Nodes, nil + return obj.Name, nil }) if err != nil { ec.Error(ctx, err) return graphql.Null } if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } return graphql.Null } - res := resTmp.([]model.XRMResourceTreeNode) + res := resTmp.(string) fc.Result = res - return ec.marshalOXRMResourceTreeNode2ᚕgithubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐXRMResourceTreeNodeᚄ(ctx, field.Selections, res) + return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_XRMResourceTreeConnection_nodes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Directive_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "XRMResourceTreeConnection", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "parentId": - return ec.fieldContext_XRMResourceTreeNode_parentId(ctx, field) - case "resource": - return ec.fieldContext_XRMResourceTreeNode_resource(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type XRMResourceTreeNode", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _XRMResourceTreeConnection_totalCount(ctx context.Context, field graphql.CollectedField, obj *model.XRMResourceTreeConnection) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_XRMResourceTreeConnection_totalCount(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.TotalCount, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_XRMResourceTreeConnection_totalCount(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "XRMResourceTreeConnection", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _XRMResourceTreeNode_parentId(ctx context.Context, field graphql.CollectedField, obj *model.XRMResourceTreeNode) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_XRMResourceTreeNode_parentId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ParentID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*model.ReferenceID) - fc.Result = res - return ec.marshalOID2ᚖgithubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐReferenceID(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_XRMResourceTreeNode_parentId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "XRMResourceTreeNode", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _XRMResourceTreeNode_resource(ctx context.Context, field graphql.CollectedField, obj *model.XRMResourceTreeNode) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_XRMResourceTreeNode_resource(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Resource, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(model.XRMResource) - fc.Result = res - return ec.marshalNXRMResource2githubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐXRMResource(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_XRMResourceTreeNode_resource(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "XRMResourceTreeNode", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type XRMResource does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Directive_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Directive_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Directive", + Object: "__Directive", Field: field, IsMethod: false, IsResolver: false, @@ -23601,6 +23605,43 @@ func (ec *executionContext) _ConditionedStatus(ctx context.Context, sel ast.Sele } } +func (ec *executionContext) _CrossplaneResource(ctx context.Context, sel ast.SelectionSet, obj model.CrossplaneResource) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: + return graphql.Null + case model.CompositeResource: + return ec._CompositeResource(ctx, sel, &obj) + case *model.CompositeResource: + if obj == nil { + return graphql.Null + } + return ec._CompositeResource(ctx, sel, obj) + case model.CompositeResourceClaim: + return ec._CompositeResourceClaim(ctx, sel, &obj) + case *model.CompositeResourceClaim: + if obj == nil { + return graphql.Null + } + return ec._CompositeResourceClaim(ctx, sel, obj) + case model.ManagedResource: + return ec._ManagedResource(ctx, sel, &obj) + case *model.ManagedResource: + if obj == nil { + return graphql.Null + } + return ec._ManagedResource(ctx, sel, obj) + case model.ProviderConfig: + return ec._ProviderConfig(ctx, sel, &obj) + case *model.ProviderConfig: + if obj == nil { + return graphql.Null + } + return ec._ProviderConfig(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) + } +} + func (ec *executionContext) _KubernetesResource(ctx context.Context, sel ast.SelectionSet, obj model.KubernetesResource) graphql.Marshaler { switch obj := (obj).(type) { case nil: @@ -23854,41 +23895,11 @@ func (ec *executionContext) _ProviderConfigDefinition(ctx context.Context, sel a } } -func (ec *executionContext) _XRMResource(ctx context.Context, sel ast.SelectionSet, obj model.XRMResource) graphql.Marshaler { - switch obj := (obj).(type) { - case nil: - return graphql.Null - case model.CompositeResource: - return ec._CompositeResource(ctx, sel, &obj) - case *model.CompositeResource: - if obj == nil { - return graphql.Null - } - return ec._CompositeResource(ctx, sel, obj) - case model.CompositeResourceClaim: - return ec._CompositeResourceClaim(ctx, sel, &obj) - case *model.CompositeResourceClaim: - if obj == nil { - return graphql.Null - } - return ec._CompositeResourceClaim(ctx, sel, obj) - case model.ManagedResource: - return ec._ManagedResource(ctx, sel, &obj) - case *model.ManagedResource: - if obj == nil { - return graphql.Null - } - return ec._ManagedResource(ctx, sel, obj) - default: - panic(fmt.Errorf("unexpected type %T", obj)) - } -} - // endregion ************************** interface.gotpl *************************** // region **************************** object.gotpl **************************** -var compositeResourceImplementors = []string{"CompositeResource", "Node", "KubernetesResource", "XRMResource"} +var compositeResourceImplementors = []string{"CompositeResource", "Node", "KubernetesResource", "CrossplaneResource"} func (ec *executionContext) _CompositeResource(ctx context.Context, sel ast.SelectionSet, obj *model.CompositeResource) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, compositeResourceImplementors) @@ -23992,7 +24003,7 @@ func (ec *executionContext) _CompositeResource(ctx context.Context, sel ast.Sele return out } -var compositeResourceClaimImplementors = []string{"CompositeResourceClaim", "Node", "KubernetesResource", "XRMResource"} +var compositeResourceClaimImplementors = []string{"CompositeResourceClaim", "Node", "KubernetesResource", "CrossplaneResource"} func (ec *executionContext) _CompositeResourceClaim(ctx context.Context, sel ast.SelectionSet, obj *model.CompositeResourceClaim) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, compositeResourceClaimImplementors) @@ -25764,6 +25775,70 @@ func (ec *executionContext) _CreateKubernetesResourcePayload(ctx context.Context return out } +var crossplaneResourceTreeConnectionImplementors = []string{"CrossplaneResourceTreeConnection"} + +func (ec *executionContext) _CrossplaneResourceTreeConnection(ctx context.Context, sel ast.SelectionSet, obj *model.CrossplaneResourceTreeConnection) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, crossplaneResourceTreeConnectionImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("CrossplaneResourceTreeConnection") + case "nodes": + + out.Values[i] = ec._CrossplaneResourceTreeConnection_nodes(ctx, field, obj) + + case "totalCount": + + out.Values[i] = ec._CrossplaneResourceTreeConnection_totalCount(ctx, field, obj) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var crossplaneResourceTreeNodeImplementors = []string{"CrossplaneResourceTreeNode"} + +func (ec *executionContext) _CrossplaneResourceTreeNode(ctx context.Context, sel ast.SelectionSet, obj *model.CrossplaneResourceTreeNode) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, crossplaneResourceTreeNodeImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("CrossplaneResourceTreeNode") + case "parentId": + + out.Values[i] = ec._CrossplaneResourceTreeNode_parentId(ctx, field, obj) + + case "resource": + + out.Values[i] = ec._CrossplaneResourceTreeNode_resource(ctx, field, obj) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + var customResourceDefinitionImplementors = []string{"CustomResourceDefinition", "Node", "KubernetesResource", "ManagedResourceDefinition", "ProviderConfigDefinition"} func (ec *executionContext) _CustomResourceDefinition(ctx context.Context, sel ast.SelectionSet, obj *model.CustomResourceDefinition) graphql.Marshaler { @@ -26436,7 +26511,7 @@ func (ec *executionContext) _LocalObjectReference(ctx context.Context, sel ast.S return out } -var managedResourceImplementors = []string{"ManagedResource", "Node", "KubernetesResource", "XRMResource"} +var managedResourceImplementors = []string{"ManagedResource", "Node", "KubernetesResource", "CrossplaneResource"} func (ec *executionContext) _ManagedResource(ctx context.Context, sel ast.SelectionSet, obj *model.ManagedResource) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, managedResourceImplementors) @@ -27046,7 +27121,7 @@ func (ec *executionContext) _Provider(ctx context.Context, sel ast.SelectionSet, return out } -var providerConfigImplementors = []string{"ProviderConfig", "Node", "KubernetesResource"} +var providerConfigImplementors = []string{"ProviderConfig", "Node", "KubernetesResource", "CrossplaneResource"} func (ec *executionContext) _ProviderConfig(ctx context.Context, sel ast.SelectionSet, obj *model.ProviderConfig) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, providerConfigImplementors) @@ -27833,7 +27908,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr out.Concurrently(i, func() graphql.Marshaler { return rrm(innerCtx) }) - case "xrmResourceTree": + case "crossplaneResourceTree": field := field innerFunc := func(ctx context.Context) (res graphql.Marshaler) { @@ -27842,7 +27917,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._Query_xrmResourceTree(ctx, field) + res = ec._Query_crossplaneResourceTree(ctx, field) if res == graphql.Null { atomic.AddUint32(&invalids, 1) } @@ -28058,70 +28133,6 @@ func (ec *executionContext) _UpdateKubernetesResourcePayload(ctx context.Context return out } -var xRMResourceTreeConnectionImplementors = []string{"XRMResourceTreeConnection"} - -func (ec *executionContext) _XRMResourceTreeConnection(ctx context.Context, sel ast.SelectionSet, obj *model.XRMResourceTreeConnection) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, xRMResourceTreeConnectionImplementors) - out := graphql.NewFieldSet(fields) - var invalids uint32 - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("XRMResourceTreeConnection") - case "nodes": - - out.Values[i] = ec._XRMResourceTreeConnection_nodes(ctx, field, obj) - - case "totalCount": - - out.Values[i] = ec._XRMResourceTreeConnection_totalCount(ctx, field, obj) - - if out.Values[i] == graphql.Null { - invalids++ - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch() - if invalids > 0 { - return graphql.Null - } - return out -} - -var xRMResourceTreeNodeImplementors = []string{"XRMResourceTreeNode"} - -func (ec *executionContext) _XRMResourceTreeNode(ctx context.Context, sel ast.SelectionSet, obj *model.XRMResourceTreeNode) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, xRMResourceTreeNodeImplementors) - out := graphql.NewFieldSet(fields) - var invalids uint32 - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("XRMResourceTreeNode") - case "parentId": - - out.Values[i] = ec._XRMResourceTreeNode_parentId(ctx, field, obj) - - case "resource": - - out.Values[i] = ec._XRMResourceTreeNode_resource(ctx, field, obj) - - if out.Values[i] == graphql.Null { - invalids++ - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch() - if invalids > 0 { - return graphql.Null - } - return out -} - var __DirectiveImplementors = []string{"__Directive"} func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { @@ -28670,6 +28681,34 @@ func (ec *executionContext) marshalNCreateKubernetesResourcePayload2ᚖgithubᚗ return ec._CreateKubernetesResourcePayload(ctx, sel, v) } +func (ec *executionContext) marshalNCrossplaneResource2githubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐCrossplaneResource(ctx context.Context, sel ast.SelectionSet, v model.CrossplaneResource) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._CrossplaneResource(ctx, sel, v) +} + +func (ec *executionContext) marshalNCrossplaneResourceTreeConnection2githubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐCrossplaneResourceTreeConnection(ctx context.Context, sel ast.SelectionSet, v model.CrossplaneResourceTreeConnection) graphql.Marshaler { + return ec._CrossplaneResourceTreeConnection(ctx, sel, &v) +} + +func (ec *executionContext) marshalNCrossplaneResourceTreeConnection2ᚖgithubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐCrossplaneResourceTreeConnection(ctx context.Context, sel ast.SelectionSet, v *model.CrossplaneResourceTreeConnection) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._CrossplaneResourceTreeConnection(ctx, sel, v) +} + +func (ec *executionContext) marshalNCrossplaneResourceTreeNode2githubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐCrossplaneResourceTreeNode(ctx context.Context, sel ast.SelectionSet, v model.CrossplaneResourceTreeNode) graphql.Marshaler { + return ec._CrossplaneResourceTreeNode(ctx, sel, &v) +} + func (ec *executionContext) marshalNCustomResourceDefinition2githubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐCustomResourceDefinition(ctx context.Context, sel ast.SelectionSet, v model.CustomResourceDefinition) graphql.Marshaler { return ec._CustomResourceDefinition(ctx, sel, &v) } @@ -29028,34 +29067,6 @@ func (ec *executionContext) marshalNUpdateKubernetesResourcePayload2ᚖgithubᚗ return ec._UpdateKubernetesResourcePayload(ctx, sel, v) } -func (ec *executionContext) marshalNXRMResource2githubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐXRMResource(ctx context.Context, sel ast.SelectionSet, v model.XRMResource) graphql.Marshaler { - if v == nil { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - return graphql.Null - } - return ec._XRMResource(ctx, sel, v) -} - -func (ec *executionContext) marshalNXRMResourceTreeConnection2githubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐXRMResourceTreeConnection(ctx context.Context, sel ast.SelectionSet, v model.XRMResourceTreeConnection) graphql.Marshaler { - return ec._XRMResourceTreeConnection(ctx, sel, &v) -} - -func (ec *executionContext) marshalNXRMResourceTreeConnection2ᚖgithubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐXRMResourceTreeConnection(ctx context.Context, sel ast.SelectionSet, v *model.XRMResourceTreeConnection) graphql.Marshaler { - if v == nil { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - return graphql.Null - } - return ec._XRMResourceTreeConnection(ctx, sel, v) -} - -func (ec *executionContext) marshalNXRMResourceTreeNode2githubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐXRMResourceTreeNode(ctx context.Context, sel ast.SelectionSet, v model.XRMResourceTreeNode) graphql.Marshaler { - return ec._XRMResourceTreeNode(ctx, sel, &v) -} - func (ec *executionContext) marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx context.Context, sel ast.SelectionSet, v introspection.Directive) graphql.Marshaler { return ec.___Directive(ctx, sel, &v) } @@ -29830,6 +29841,53 @@ func (ec *executionContext) marshalOConfigurationStatus2ᚖgithubᚗcomᚋupboun return ec._ConfigurationStatus(ctx, sel, v) } +func (ec *executionContext) marshalOCrossplaneResourceTreeNode2ᚕgithubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐCrossplaneResourceTreeNodeᚄ(ctx context.Context, sel ast.SelectionSet, v []model.CrossplaneResourceTreeNode) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNCrossplaneResourceTreeNode2githubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐCrossplaneResourceTreeNode(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + func (ec *executionContext) marshalOCustomResourceDefinition2ᚕgithubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐCustomResourceDefinitionᚄ(ctx context.Context, sel ast.SelectionSet, v []model.CustomResourceDefinition) graphql.Marshaler { if v == nil { return graphql.Null @@ -30557,53 +30615,6 @@ func (ec *executionContext) marshalOTypeReference2ᚖgithubᚗcomᚋupboundᚋxg return ec._TypeReference(ctx, sel, v) } -func (ec *executionContext) marshalOXRMResourceTreeNode2ᚕgithubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐXRMResourceTreeNodeᚄ(ctx context.Context, sel ast.SelectionSet, v []model.XRMResourceTreeNode) graphql.Marshaler { - if v == nil { - return graphql.Null - } - ret := make(graphql.Array, len(v)) - var wg sync.WaitGroup - isLen1 := len(v) == 1 - if !isLen1 { - wg.Add(len(v)) - } - for i := range v { - i := i - fc := &graphql.FieldContext{ - Index: &i, - Result: &v[i], - } - ctx := graphql.WithFieldContext(ctx, fc) - f := func(i int) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() - if !isLen1 { - defer wg.Done() - } - ret[i] = ec.marshalNXRMResourceTreeNode2githubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐXRMResourceTreeNode(ctx, sel, v[i]) - } - if isLen1 { - f(i) - } else { - go f(i) - } - - } - wg.Wait() - - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - - return ret -} - func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { if v == nil { return graphql.Null diff --git a/internal/graph/model/generated.go b/internal/graph/model/generated.go index 7086b79..c6b852b 100644 --- a/internal/graph/model/generated.go +++ b/internal/graph/model/generated.go @@ -15,6 +15,12 @@ type ConditionedStatus interface { IsConditionedStatus() } +// A XRM Resource which is either a `CompositeResource`, `CompositeResourceClaim` +// or `ManagedResource` +type CrossplaneResource interface { + IsCrossplaneResource() +} + // An object that corresponds to a Kubernetes API resource. type KubernetesResource interface { IsKubernetesResource() @@ -43,12 +49,6 @@ type ProviderConfigDefinition interface { IsProviderConfigDefinition() } -// A XRM Resource which is either a `CompositeResource`, `CompositeResourceClaim` -// or `ManagedResource` -type XRMResource interface { - IsXRMResource() -} - // A CompositeResource is a resource this is reconciled by composing other // composite or managed resources. Composite resources use a Composition to // determine which resources to compose, and how. @@ -75,7 +75,7 @@ type CompositeResource struct { func (CompositeResource) IsNode() {} func (CompositeResource) IsKubernetesResource() {} -func (CompositeResource) IsXRMResource() {} +func (CompositeResource) IsCrossplaneResource() {} // A CompositeResourceClaim is a namespaced proxy for a composite resource. type CompositeResourceClaim struct { @@ -101,7 +101,7 @@ type CompositeResourceClaim struct { func (CompositeResourceClaim) IsNode() {} func (CompositeResourceClaim) IsKubernetesResource() {} -func (CompositeResourceClaim) IsXRMResource() {} +func (CompositeResourceClaim) IsCrossplaneResource() {} // A CompositeResourceConnection represents a connection to composite resource // claims. @@ -483,6 +483,25 @@ type CreateKubernetesResourcePayload struct { Resource KubernetesResource `json:"resource"` } +// A `CrossplaneResourceTreeConnection` represents a connection to `XRMDescendant`s +type CrossplaneResourceTreeConnection struct { + // Connected nodes. + Nodes []CrossplaneResourceTreeNode `json:"nodes"` + // The total number of connected nodes. + TotalCount int `json:"totalCount"` +} + +// An `CrossplaneResourceTreeNode` is an `CrossplaneResource` with a `ID` of its parent +// `CrossplaneResource`. +// +// Note: A `NULL` `parentId` represents the root of the descendant tree. +type CrossplaneResourceTreeNode struct { + // The `ID` of the parent `CrossplaneResource` (`NULL` is the root of the tree) + ParentID *ReferenceID `json:"parentId"` + // The `CrossplaneResource` object of this `CrossplaneResourceTreeNode` + Resource CrossplaneResource `json:"resource"` +} + // A CustomResourceDefinition defines a type of custom resource that extends the // set of resources supported by the Kubernetes API. type CustomResourceDefinition struct { @@ -683,7 +702,7 @@ type ManagedResource struct { func (ManagedResource) IsNode() {} func (ManagedResource) IsKubernetesResource() {} -func (ManagedResource) IsXRMResource() {} +func (ManagedResource) IsCrossplaneResource() {} // A ManagedResourceStatus represents the observed state of a managed resource. type ManagedResourceStatus struct { @@ -823,6 +842,7 @@ type ProviderConfig struct { func (ProviderConfig) IsNode() {} func (ProviderConfig) IsKubernetesResource() {} +func (ProviderConfig) IsCrossplaneResource() {} // A reference to the ProviderConfig used by a particular managed resource. type ProviderConfigReference struct { @@ -968,25 +988,6 @@ type UpdateKubernetesResourcePayload struct { Resource KubernetesResource `json:"resource"` } -// A `XRMResourceTreeConnection` reprsents a connection to `XRMDescendant`s -type XRMResourceTreeConnection struct { - // Connected nodes. - Nodes []XRMResourceTreeNode `json:"nodes"` - // The total number of connected nodes. - TotalCount int `json:"totalCount"` -} - -// An `XRMResourceTreeNode` is an `XRMResource` with a `ID` of its parent -// `XRMResource`. -// -// Note: A `NULL` `parentId` represents the root of the descendant tree. -type XRMResourceTreeNode struct { - // The `ID` of the parent `XRMResource` (`NULL` is the root of the tree) - ParentID *ReferenceID `json:"parentId"` - // The `XRMResource` object of this `XRMResourceTreeNode` - Resource XRMResource `json:"resource"` -} - // A ConditionStatus represensts the status of a condition. type ConditionStatus string diff --git a/internal/graph/resolvers/query.go b/internal/graph/resolvers/query.go index 25e7e0d..eea19a6 100644 --- a/internal/graph/resolvers/query.go +++ b/internal/graph/resolvers/query.go @@ -51,13 +51,13 @@ type query struct { clients ClientCache } -// Recursively collect `XRMResourceTreeNode`s from the given KubernetesResource -func (r *query) getAllDecedents(ctx context.Context, res model.KubernetesResource, parentID *model.ReferenceID) ([]model.XRMResourceTreeNode, error) { //nolint:gocyclo +// Recursively collect `CrossplaneResourceTreeNode`s from the given KubernetesResource +func (r *query) getAllDecedents(ctx context.Context, res model.KubernetesResource, parentID *model.ReferenceID) ([]model.CrossplaneResourceTreeNode, error) { //nolint:gocyclo // This isn't _really_ that complex; it's a long but simple switch. switch typedRes := res.(type) { case model.CompositeResource: - list := []model.XRMResourceTreeNode{{ParentID: parentID, Resource: typedRes}} + list := []model.CrossplaneResourceTreeNode{{ParentID: parentID, Resource: typedRes}} compositeResolver := compositeResourceSpec{clients: r.clients} resources, err := compositeResolver.Resources(ctx, typedRes.Spec) @@ -76,7 +76,7 @@ func (r *query) getAllDecedents(ctx context.Context, res model.KubernetesResourc return list, nil case model.CompositeResourceClaim: - list := []model.XRMResourceTreeNode{{ParentID: parentID, Resource: typedRes}} + list := []model.CrossplaneResourceTreeNode{{ParentID: parentID, Resource: typedRes}} claimResolver := compositeResourceClaimSpec{clients: r.clients} composite, err := claimResolver.Resource(ctx, typedRes.Spec) @@ -94,15 +94,17 @@ func (r *query) getAllDecedents(ctx context.Context, res model.KubernetesResourc } return append(list, childList...), nil + case model.ProviderConfig: + return []model.CrossplaneResourceTreeNode{{ParentID: parentID, Resource: typedRes}}, nil case model.ManagedResource: - return []model.XRMResourceTreeNode{{ParentID: parentID, Resource: typedRes}}, nil + return []model.CrossplaneResourceTreeNode{{ParentID: parentID, Resource: typedRes}}, nil default: graphql.AddError(ctx, fmt.Errorf("was not a `CompositeResource`, `CompositeResourceClaim`, or `ManagedResource` got: %T", res)) return nil, nil } } -func (r *query) XrmResourceTree(ctx context.Context, id model.ReferenceID) (*model.XRMResourceTreeConnection, error) { +func (r *query) CrossplaneResourceTree(ctx context.Context, id model.ReferenceID) (*model.CrossplaneResourceTreeConnection, error) { ctx, cancel := context.WithTimeout(ctx, timeout) defer cancel() @@ -116,7 +118,7 @@ func (r *query) XrmResourceTree(ctx context.Context, id model.ReferenceID) (*mod return nil, err } - return &model.XRMResourceTreeConnection{Nodes: list, TotalCount: len(list)}, nil + return &model.CrossplaneResourceTreeConnection{Nodes: list, TotalCount: len(list)}, nil } func (r *query) KubernetesResource(ctx context.Context, id model.ReferenceID) (model.KubernetesResource, error) { diff --git a/internal/graph/resolvers/query_test.go b/internal/graph/resolvers/query_test.go index 533b138..0d0a064 100644 --- a/internal/graph/resolvers/query_test.go +++ b/internal/graph/resolvers/query_test.go @@ -45,7 +45,7 @@ import ( var _ generated.QueryResolver = &query{} -func TestXrmResourceTree(t *testing.T) { +func TestCrossplaneResourceTree(t *testing.T) { errBoom := errors.New("boom") type args struct { @@ -53,7 +53,7 @@ func TestXrmResourceTree(t *testing.T) { id model.ReferenceID } type want struct { - kr *model.XRMResourceTreeConnection + kr *model.CrossplaneResourceTreeConnection err error errs gqlerror.List } @@ -81,8 +81,8 @@ func TestXrmResourceTree(t *testing.T) { }, }, }, - "getAllDecendentsNotXRMResourceError": { - reason: "If the passed resource ID is not for a XRMResource we error", + "getAllDecendentsNotCrossplaneResourceError": { + reason: "If the passed resource ID is not for a CrossplaneResource we error", clients: ClientCacheFn(func(_ auth.Credentials, _ ...clients.GetOption) (client.Client, error) { return &test.MockClient{ MockGet: test.NewMockGetFn(nil), @@ -121,7 +121,7 @@ func TestXrmResourceTree(t *testing.T) { id: model.ReferenceID{Name: "root"}, }, want: want{ - kr: &model.XRMResourceTreeConnection{TotalCount: 1, Nodes: []model.XRMResourceTreeNode{ + kr: &model.CrossplaneResourceTreeConnection{TotalCount: 1, Nodes: []model.CrossplaneResourceTreeNode{ { Resource: model.CompositeResourceClaim{ ID: model.ReferenceID{Namespace: namespace}, @@ -147,11 +147,13 @@ func TestXrmResourceTree(t *testing.T) { case "composite": fieldpath.Pave(u.Object).SetValue("spec.resourceRefs", []corev1.ObjectReference{{Name: "managed1"}, {Name: "child-composite"}}) case "child-composite": - fieldpath.Pave(u.Object).SetValue("spec.resourceRefs", []corev1.ObjectReference{{Name: "managed2"}}) + fieldpath.Pave(u.Object).SetValue("spec.resourceRefs", []corev1.ObjectReference{{Name: "managed2"}, {Name: "provider-config"}}) case "managed1": fallthrough case "managed2": fieldpath.Pave(u.Object).SetValue("spec.providerConfigRef.name", "") + case "provider-config": + u.SetKind("ProviderConfig") default: t.Fatalf("unknown get with name: %s", key.Name) } @@ -164,7 +166,7 @@ func TestXrmResourceTree(t *testing.T) { id: model.ReferenceID{Name: "root"}, }, want: want{ - kr: &model.XRMResourceTreeConnection{TotalCount: 5, Nodes: []model.XRMResourceTreeNode{ + kr: &model.CrossplaneResourceTreeConnection{TotalCount: 6, Nodes: []model.CrossplaneResourceTreeNode{ { Resource: model.CompositeResourceClaim{ ID: model.ReferenceID{Namespace: namespace, Name: "root"}, @@ -185,7 +187,15 @@ func TestXrmResourceTree(t *testing.T) { Resource: model.CompositeResource{ ID: model.ReferenceID{Name: "child-composite"}, Metadata: &model.ObjectMeta{Name: "child-composite"}, - Spec: &model.CompositeResourceSpec{ResourceReferences: []corev1.ObjectReference{{Name: "managed2"}}}, + Spec: &model.CompositeResourceSpec{ResourceReferences: []corev1.ObjectReference{{Name: "managed2"}, {Name: "provider-config"}}}, + }, + }, + { + ParentID: &model.ReferenceID{Name: "child-composite"}, + Resource: model.ProviderConfig{ + ID: model.ReferenceID{Kind: "ProviderConfig", Name: "provider-config"}, + Kind: "ProviderConfig", + Metadata: &model.ObjectMeta{Name: "provider-config"}, }, }, { @@ -215,7 +225,7 @@ func TestXrmResourceTree(t *testing.T) { // Our GraphQL resolvers never return errors. We instead add an // error to the GraphQL context and return early. - got, err := q.XrmResourceTree(tc.args.ctx, tc.args.id) + got, err := q.CrossplaneResourceTree(tc.args.ctx, tc.args.id) errs := graphql.GetErrors(tc.args.ctx) if diff := cmp.Diff(tc.want.err, err, test.EquateErrors()); diff != "" { @@ -225,7 +235,15 @@ func TestXrmResourceTree(t *testing.T) { t.Errorf("\n%s\ns.KubernetesResource(...): -want GraphQL errors, +got GraphQL errors:\n%s\n", tc.reason, diff) } - if diff := cmp.Diff(tc.want.kr, got, cmpopts.IgnoreFields(model.CompositeResourceClaim{}, "Unstructured"), cmpopts.IgnoreFields(model.CompositeResource{}, "Unstructured"), cmpopts.IgnoreFields(model.ManagedResource{}, "Unstructured"), cmpopts.IgnoreUnexported(model.ObjectMeta{})); diff != "" { + diffOptions := []cmp.Option{ + cmpopts.IgnoreFields(model.CompositeResourceClaim{}, "Unstructured"), + cmpopts.IgnoreFields(model.CompositeResource{}, "Unstructured"), + cmpopts.IgnoreFields(model.ManagedResource{}, "Unstructured"), + cmpopts.IgnoreFields(model.ProviderConfig{}, "Unstructured"), + cmpopts.IgnoreUnexported(model.ObjectMeta{}), + } + + if diff := cmp.Diff(tc.want.kr, got, diffOptions...); diff != "" { t.Errorf("\n%s\ns.KubernetesResource(...): -want, +got:\n%s\n", tc.reason, diff) } }) diff --git a/schema/queries.gql b/schema/queries.gql index 7581ca9..227c172 100644 --- a/schema/queries.gql +++ b/schema/queries.gql @@ -157,43 +157,47 @@ type Query { ): CompositionConnection! """ - Get an `XRMResource` and its descendants which form a tree. + Get an `CrossplaneResource` and its descendants which form a tree. """ - xrmResourceTree( - "The `ID` of an `XRMResource`" + crossplaneResourceTree( + "The `ID` of an `CrossplaneResource`" id: ID! - ): XRMResourceTreeConnection! + ): CrossplaneResourceTreeConnection! } """ A XRM Resource which is either a `CompositeResource`, `CompositeResourceClaim` or `ManagedResource` """ -union XRMResource = CompositeResource | CompositeResourceClaim | ManagedResource +union CrossplaneResource = + CompositeResource + | CompositeResourceClaim + | ManagedResource + | ProviderConfig """ -A `XRMResourceTreeConnection` represents a connection to `XRMDescendant`s +A `CrossplaneResourceTreeConnection` represents a connection to `XRMDescendant`s """ -type XRMResourceTreeConnection { +type CrossplaneResourceTreeConnection { "Connected nodes." - nodes: [XRMResourceTreeNode!] + nodes: [CrossplaneResourceTreeNode!] "The total number of connected nodes." totalCount: Int! } """ -An `XRMResourceTreeNode` is an `XRMResource` with a `ID` of its parent -`XRMResource`. +An `CrossplaneResourceTreeNode` is an `CrossplaneResource` with a `ID` of its parent +`CrossplaneResource`. Note: A `NULL` `parentId` represents the root of the descendant tree. """ -type XRMResourceTreeNode { - "The `ID` of the parent `XRMResource` (`NULL` is the root of the tree)" +type CrossplaneResourceTreeNode { + "The `ID` of the parent `CrossplaneResource` (`NULL` is the root of the tree)" parentId: ID - "The `XRMResource` object of this `XRMResourceTreeNode`" - resource: XRMResource! + "The `CrossplaneResource` object of this `CrossplaneResourceTreeNode`" + resource: CrossplaneResource! } """ From f153dc3b460c5ffca26f99f366a995424a371621 Mon Sep 17 00:00:00 2001 From: Michael Goff Date: Tue, 27 Sep 2022 08:58:57 -0700 Subject: [PATCH 4/4] Expand crossplaneResourceTree to include support for composing all `KubernetesResources` (Will be squashed) --- internal/graph/generated/generated.go | 86 +++++--------------------- internal/graph/model/generated.go | 20 ++---- internal/graph/resolvers/query.go | 8 +-- internal/graph/resolvers/query_test.go | 16 ----- schema/queries.gql | 25 +++----- 5 files changed, 31 insertions(+), 124 deletions(-) diff --git a/internal/graph/generated/generated.go b/internal/graph/generated/generated.go index ce91ffc..624ffb9 100644 --- a/internal/graph/generated/generated.go +++ b/internal/graph/generated/generated.go @@ -5314,7 +5314,10 @@ type Query { ): CompositionConnection! """ - Get an ` + "`" + `CrossplaneResource` + "`" + ` and its descendants which form a tree. + Get an ` + "`" + `KubernetesResource` + "`" + ` and its descendants which form a tree. The two + ` + "`" + `KubernetesResource` + "`" + `s that have descendants are ` + "`" + `CompositeResourceClaim` + "`" + ` (its + ` + "`" + `CompositeResource` + "`" + `) and ` + "`" + `CompositeResource` + "`" + ` (the ` + "`" + `KubernetesResource` + "`" + `s it + composes via a ` + "`" + `Composition` + "`" + `). """ crossplaneResourceTree( "The ` + "`" + `ID` + "`" + ` of an ` + "`" + `CrossplaneResource` + "`" + `" @@ -5323,17 +5326,7 @@ type Query { } """ -A XRM Resource which is either a ` + "`" + `CompositeResource` + "`" + `, ` + "`" + `CompositeResourceClaim` + "`" + ` -or ` + "`" + `ManagedResource` + "`" + ` -""" -union CrossplaneResource = - CompositeResource - | CompositeResourceClaim - | ManagedResource - | ProviderConfig - -""" -A ` + "`" + `CrossplaneResourceTreeConnection` + "`" + ` represents a connection to ` + "`" + `XRMDescendant` + "`" + `s +A ` + "`" + `CrossplaneResourceTreeConnection` + "`" + ` represents a connection to ` + "`" + `CrossplaneResourceTreeNode` + "`" + `s """ type CrossplaneResourceTreeConnection { "Connected nodes." @@ -5344,17 +5337,17 @@ type CrossplaneResourceTreeConnection { } """ -An ` + "`" + `CrossplaneResourceTreeNode` + "`" + ` is an ` + "`" + `CrossplaneResource` + "`" + ` with a ` + "`" + `ID` + "`" + ` of its parent +An ` + "`" + `CrossplaneResourceTreeNode` + "`" + ` is an ` + "`" + `KubernetesResource` + "`" + ` with a ` + "`" + `ID` + "`" + ` of its parent ` + "`" + `CrossplaneResource` + "`" + `. Note: A ` + "`" + `NULL` + "`" + ` ` + "`" + `parentId` + "`" + ` represents the root of the descendant tree. """ type CrossplaneResourceTreeNode { - "The ` + "`" + `ID` + "`" + ` of the parent ` + "`" + `CrossplaneResource` + "`" + ` (` + "`" + `NULL` + "`" + ` is the root of the tree)" + "The ` + "`" + `ID` + "`" + ` of the parent ` + "`" + `KubernetesResource` + "`" + ` (` + "`" + `NULL` + "`" + ` is the root of the tree)" parentId: ID - "The ` + "`" + `CrossplaneResource` + "`" + ` object of this ` + "`" + `CrossplaneResourceTreeNode` + "`" + `" - resource: CrossplaneResource! + "The ` + "`" + `KubernetesResource` + "`" + ` object of this ` + "`" + `CrossplaneResourceTreeNode` + "`" + `" + resource: KubernetesResource! } """ @@ -13201,9 +13194,9 @@ func (ec *executionContext) _CrossplaneResourceTreeNode_resource(ctx context.Con } return graphql.Null } - res := resTmp.(model.CrossplaneResource) + res := resTmp.(model.KubernetesResource) fc.Result = res - return ec.marshalNCrossplaneResource2githubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐCrossplaneResource(ctx, field.Selections, res) + return ec.marshalNKubernetesResource2githubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐKubernetesResource(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_CrossplaneResourceTreeNode_resource(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -13213,7 +13206,7 @@ func (ec *executionContext) fieldContext_CrossplaneResourceTreeNode_resource(ctx IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type CrossplaneResource does not have child fields") + return nil, errors.New("FieldContext.Child cannot be called on type INTERFACE") }, } return fc, nil @@ -23605,43 +23598,6 @@ func (ec *executionContext) _ConditionedStatus(ctx context.Context, sel ast.Sele } } -func (ec *executionContext) _CrossplaneResource(ctx context.Context, sel ast.SelectionSet, obj model.CrossplaneResource) graphql.Marshaler { - switch obj := (obj).(type) { - case nil: - return graphql.Null - case model.CompositeResource: - return ec._CompositeResource(ctx, sel, &obj) - case *model.CompositeResource: - if obj == nil { - return graphql.Null - } - return ec._CompositeResource(ctx, sel, obj) - case model.CompositeResourceClaim: - return ec._CompositeResourceClaim(ctx, sel, &obj) - case *model.CompositeResourceClaim: - if obj == nil { - return graphql.Null - } - return ec._CompositeResourceClaim(ctx, sel, obj) - case model.ManagedResource: - return ec._ManagedResource(ctx, sel, &obj) - case *model.ManagedResource: - if obj == nil { - return graphql.Null - } - return ec._ManagedResource(ctx, sel, obj) - case model.ProviderConfig: - return ec._ProviderConfig(ctx, sel, &obj) - case *model.ProviderConfig: - if obj == nil { - return graphql.Null - } - return ec._ProviderConfig(ctx, sel, obj) - default: - panic(fmt.Errorf("unexpected type %T", obj)) - } -} - func (ec *executionContext) _KubernetesResource(ctx context.Context, sel ast.SelectionSet, obj model.KubernetesResource) graphql.Marshaler { switch obj := (obj).(type) { case nil: @@ -23899,7 +23855,7 @@ func (ec *executionContext) _ProviderConfigDefinition(ctx context.Context, sel a // region **************************** object.gotpl **************************** -var compositeResourceImplementors = []string{"CompositeResource", "Node", "KubernetesResource", "CrossplaneResource"} +var compositeResourceImplementors = []string{"CompositeResource", "Node", "KubernetesResource"} func (ec *executionContext) _CompositeResource(ctx context.Context, sel ast.SelectionSet, obj *model.CompositeResource) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, compositeResourceImplementors) @@ -24003,7 +23959,7 @@ func (ec *executionContext) _CompositeResource(ctx context.Context, sel ast.Sele return out } -var compositeResourceClaimImplementors = []string{"CompositeResourceClaim", "Node", "KubernetesResource", "CrossplaneResource"} +var compositeResourceClaimImplementors = []string{"CompositeResourceClaim", "Node", "KubernetesResource"} func (ec *executionContext) _CompositeResourceClaim(ctx context.Context, sel ast.SelectionSet, obj *model.CompositeResourceClaim) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, compositeResourceClaimImplementors) @@ -26511,7 +26467,7 @@ func (ec *executionContext) _LocalObjectReference(ctx context.Context, sel ast.S return out } -var managedResourceImplementors = []string{"ManagedResource", "Node", "KubernetesResource", "CrossplaneResource"} +var managedResourceImplementors = []string{"ManagedResource", "Node", "KubernetesResource"} func (ec *executionContext) _ManagedResource(ctx context.Context, sel ast.SelectionSet, obj *model.ManagedResource) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, managedResourceImplementors) @@ -27121,7 +27077,7 @@ func (ec *executionContext) _Provider(ctx context.Context, sel ast.SelectionSet, return out } -var providerConfigImplementors = []string{"ProviderConfig", "Node", "KubernetesResource", "CrossplaneResource"} +var providerConfigImplementors = []string{"ProviderConfig", "Node", "KubernetesResource"} func (ec *executionContext) _ProviderConfig(ctx context.Context, sel ast.SelectionSet, obj *model.ProviderConfig) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, providerConfigImplementors) @@ -28681,16 +28637,6 @@ func (ec *executionContext) marshalNCreateKubernetesResourcePayload2ᚖgithubᚗ return ec._CreateKubernetesResourcePayload(ctx, sel, v) } -func (ec *executionContext) marshalNCrossplaneResource2githubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐCrossplaneResource(ctx context.Context, sel ast.SelectionSet, v model.CrossplaneResource) graphql.Marshaler { - if v == nil { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - return graphql.Null - } - return ec._CrossplaneResource(ctx, sel, v) -} - func (ec *executionContext) marshalNCrossplaneResourceTreeConnection2githubᚗcomᚋupboundᚋxgqlᚋinternalᚋgraphᚋmodelᚐCrossplaneResourceTreeConnection(ctx context.Context, sel ast.SelectionSet, v model.CrossplaneResourceTreeConnection) graphql.Marshaler { return ec._CrossplaneResourceTreeConnection(ctx, sel, &v) } diff --git a/internal/graph/model/generated.go b/internal/graph/model/generated.go index c6b852b..332a0a6 100644 --- a/internal/graph/model/generated.go +++ b/internal/graph/model/generated.go @@ -15,12 +15,6 @@ type ConditionedStatus interface { IsConditionedStatus() } -// A XRM Resource which is either a `CompositeResource`, `CompositeResourceClaim` -// or `ManagedResource` -type CrossplaneResource interface { - IsCrossplaneResource() -} - // An object that corresponds to a Kubernetes API resource. type KubernetesResource interface { IsKubernetesResource() @@ -75,7 +69,6 @@ type CompositeResource struct { func (CompositeResource) IsNode() {} func (CompositeResource) IsKubernetesResource() {} -func (CompositeResource) IsCrossplaneResource() {} // A CompositeResourceClaim is a namespaced proxy for a composite resource. type CompositeResourceClaim struct { @@ -101,7 +94,6 @@ type CompositeResourceClaim struct { func (CompositeResourceClaim) IsNode() {} func (CompositeResourceClaim) IsKubernetesResource() {} -func (CompositeResourceClaim) IsCrossplaneResource() {} // A CompositeResourceConnection represents a connection to composite resource // claims. @@ -483,7 +475,7 @@ type CreateKubernetesResourcePayload struct { Resource KubernetesResource `json:"resource"` } -// A `CrossplaneResourceTreeConnection` represents a connection to `XRMDescendant`s +// A `CrossplaneResourceTreeConnection` represents a connection to `CrossplaneResourceTreeNode`s type CrossplaneResourceTreeConnection struct { // Connected nodes. Nodes []CrossplaneResourceTreeNode `json:"nodes"` @@ -491,15 +483,15 @@ type CrossplaneResourceTreeConnection struct { TotalCount int `json:"totalCount"` } -// An `CrossplaneResourceTreeNode` is an `CrossplaneResource` with a `ID` of its parent +// An `CrossplaneResourceTreeNode` is an `KubernetesResource` with a `ID` of its parent // `CrossplaneResource`. // // Note: A `NULL` `parentId` represents the root of the descendant tree. type CrossplaneResourceTreeNode struct { - // The `ID` of the parent `CrossplaneResource` (`NULL` is the root of the tree) + // The `ID` of the parent `KubernetesResource` (`NULL` is the root of the tree) ParentID *ReferenceID `json:"parentId"` - // The `CrossplaneResource` object of this `CrossplaneResourceTreeNode` - Resource CrossplaneResource `json:"resource"` + // The `KubernetesResource` object of this `CrossplaneResourceTreeNode` + Resource KubernetesResource `json:"resource"` } // A CustomResourceDefinition defines a type of custom resource that extends the @@ -702,7 +694,6 @@ type ManagedResource struct { func (ManagedResource) IsNode() {} func (ManagedResource) IsKubernetesResource() {} -func (ManagedResource) IsCrossplaneResource() {} // A ManagedResourceStatus represents the observed state of a managed resource. type ManagedResourceStatus struct { @@ -842,7 +833,6 @@ type ProviderConfig struct { func (ProviderConfig) IsNode() {} func (ProviderConfig) IsKubernetesResource() {} -func (ProviderConfig) IsCrossplaneResource() {} // A reference to the ProviderConfig used by a particular managed resource. type ProviderConfigReference struct { diff --git a/internal/graph/resolvers/query.go b/internal/graph/resolvers/query.go index eea19a6..491b9a5 100644 --- a/internal/graph/resolvers/query.go +++ b/internal/graph/resolvers/query.go @@ -16,7 +16,6 @@ package resolvers import ( "context" - "fmt" "sort" "github.com/99designs/gqlgen/graphql" @@ -94,13 +93,8 @@ func (r *query) getAllDecedents(ctx context.Context, res model.KubernetesResourc } return append(list, childList...), nil - case model.ProviderConfig: - return []model.CrossplaneResourceTreeNode{{ParentID: parentID, Resource: typedRes}}, nil - case model.ManagedResource: - return []model.CrossplaneResourceTreeNode{{ParentID: parentID, Resource: typedRes}}, nil default: - graphql.AddError(ctx, fmt.Errorf("was not a `CompositeResource`, `CompositeResourceClaim`, or `ManagedResource` got: %T", res)) - return nil, nil + return []model.CrossplaneResourceTreeNode{{ParentID: parentID, Resource: typedRes}}, nil } } diff --git a/internal/graph/resolvers/query_test.go b/internal/graph/resolvers/query_test.go index 0d0a064..ea17f41 100644 --- a/internal/graph/resolvers/query_test.go +++ b/internal/graph/resolvers/query_test.go @@ -81,22 +81,6 @@ func TestCrossplaneResourceTree(t *testing.T) { }, }, }, - "getAllDecendentsNotCrossplaneResourceError": { - reason: "If the passed resource ID is not for a CrossplaneResource we error", - clients: ClientCacheFn(func(_ auth.Credentials, _ ...clients.GetOption) (client.Client, error) { - return &test.MockClient{ - MockGet: test.NewMockGetFn(nil), - }, nil - }), - args: args{ - ctx: graphql.WithResponseContext(context.Background(), graphql.DefaultErrorPresenter, graphql.DefaultRecover), - }, - want: want{ - errs: gqlerror.List{ - gqlerror.Errorf("was not a `CompositeResource`, `CompositeResourceClaim`, or `ManagedResource` got: model.GenericResource"), - }, - }, - }, "SuccessWithNoComposite": { reason: "It is a successful call", clients: ClientCacheFn(func(_ auth.Credentials, _ ...clients.GetOption) (client.Client, error) { diff --git a/schema/queries.gql b/schema/queries.gql index 227c172..764d8be 100644 --- a/schema/queries.gql +++ b/schema/queries.gql @@ -157,7 +157,10 @@ type Query { ): CompositionConnection! """ - Get an `CrossplaneResource` and its descendants which form a tree. + Get an `KubernetesResource` and its descendants which form a tree. The two + `KubernetesResource`s that have descendants are `CompositeResourceClaim` (its + `CompositeResource`) and `CompositeResource` (the `KubernetesResource`s it + composes via a `Composition`). """ crossplaneResourceTree( "The `ID` of an `CrossplaneResource`" @@ -166,17 +169,7 @@ type Query { } """ -A XRM Resource which is either a `CompositeResource`, `CompositeResourceClaim` -or `ManagedResource` -""" -union CrossplaneResource = - CompositeResource - | CompositeResourceClaim - | ManagedResource - | ProviderConfig - -""" -A `CrossplaneResourceTreeConnection` represents a connection to `XRMDescendant`s +A `CrossplaneResourceTreeConnection` represents a connection to `CrossplaneResourceTreeNode`s """ type CrossplaneResourceTreeConnection { "Connected nodes." @@ -187,17 +180,17 @@ type CrossplaneResourceTreeConnection { } """ -An `CrossplaneResourceTreeNode` is an `CrossplaneResource` with a `ID` of its parent +An `CrossplaneResourceTreeNode` is an `KubernetesResource` with a `ID` of its parent `CrossplaneResource`. Note: A `NULL` `parentId` represents the root of the descendant tree. """ type CrossplaneResourceTreeNode { - "The `ID` of the parent `CrossplaneResource` (`NULL` is the root of the tree)" + "The `ID` of the parent `KubernetesResource` (`NULL` is the root of the tree)" parentId: ID - "The `CrossplaneResource` object of this `CrossplaneResourceTreeNode`" - resource: CrossplaneResource! + "The `KubernetesResource` object of this `CrossplaneResourceTreeNode`" + resource: KubernetesResource! } """