Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go/fn/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -870,7 +870,7 @@ func IsGVK(group, version, kind string) func(*KubeObject) bool {

// GetRootKptfile returns the root Kptfile. Nested kpt packages can have multiple Kptfile files of the same GVKNN.
func (o KubeObjects) GetRootKptfile() *KubeObject {
kptfiles := o.Where(IsGVK(v1.KptFileGroup, v1.KptFileVersion, v1.KptFileKind))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I think the kptfile v1 is only merged into kpt repo, while this lib uses https://github.com/GoogleContainerTools/kpt-functions-sdk/blob/master/go/api/kptfile/v1/types.go

kptfiles := o.Where(IsGVK(v1.KptFileGVK))
if len(kptfiles) == 0 {
return nil
}
Expand Down
46 changes: 46 additions & 0 deletions go/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
module github.com/GoogleContainerTools/kpt-functions-sdk/go

go 1.17

require (
github.com/GoogleContainerTools/kpt-functions-sdk/go/api v0.0.0-20220720212527-133180134b93 // indirect
github.com/go-errors/errors v1.0.1 // indirect
github.com/stretchr/testify v1.7.1 // indirect
// We must not include any core k8s modules (e.g. k8s.io/apimachinery) in
// the dependencies, depending on them will likely to cause version skew for
// consumers. The dependencies for tests and examples should be isolated.
k8s.io/klog/v2 v2.70.1 // indirect
sigs.k8s.io/kustomize/kyaml v0.13.7-0.20220418212550-9d5491c2e20c // indirect

)

require (
github.com/GoogleContainerTools/kpt-functions-sdk/go/fn v0.0.0-20220812180116-970f3e4cbc5a
k8s.io/apimachinery v0.25.2
)

require (
github.com/PuerkitoBio/purell v1.1.1 // indirect
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-logr/logr v1.2.3 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.19.6 // indirect
github.com/go-openapi/swag v0.21.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/gnostic v0.5.7-v3refs // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/kr/pretty v0.2.1 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/xlab/treeprint v1.1.0 // indirect
golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
golang.org/x/text v0.3.7 // indirect
google.golang.org/protobuf v1.28.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 // indirect
)
745 changes: 745 additions & 0 deletions go/go.sum

Large diffs are not rendered by default.

22 changes: 22 additions & 0 deletions go/pkg/meta/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package meta

// This package holds some schema-aware functions that can visit references
// in objects, even where those references are not obvious, e.g. metadata.namespace
// is a reference to a Namespace object.
//
// It is currently based on hard-coding, but we would like to extend the kubernetes
// OpenAPI to include this information and rebase on that instead.
90 changes: 90 additions & 0 deletions go/pkg/meta/kinds.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package meta

import (
"fmt"

"k8s.io/apimachinery/pkg/runtime/schema"
)

// IsClusterScoped returns true if the specified GVK is cluster scoped, or an error if this cannot be determined.
func IsClusterScoped(gvk schema.GroupVersionKind) (bool, error) {
ki := findKindInfo(gvk)
if ki == nil {
return false, fmt.Errorf("kind %v not known", gvk)
}
return ki.ClusterScoped, nil
}

type kindInfo struct {
GVK schema.GroupVersionKind
ClusterScoped bool
}

// kindInfos holds a hard-coded list of type information.
// This should be replaced with OpenAPI-derived information in the future.
var kindInfos = []kindInfo{
{
GVK: schema.GroupVersionKind{Group: "container.cnrm.cloud.google.com", Version: "v1beta1", Kind: "ContainerCluster"},
ClusterScoped: false,
},
{
GVK: schema.GroupVersionKind{Group: "container.cnrm.cloud.google.com", Version: "v1beta1", Kind: "ContainerNodePool"},
ClusterScoped: false,
},
{
GVK: schema.GroupVersionKind{Group: "iam.cnrm.cloud.google.com", Version: "v1beta1", Kind: "IAMPolicyMember"},
ClusterScoped: false,
},
{
GVK: schema.GroupVersionKind{Group: "iam.cnrm.cloud.google.com", Version: "v1beta1", Kind: "IAMServiceAccount"},
ClusterScoped: false,
},
{
GVK: schema.GroupVersionKind{Group: "resourcemanager.cnrm.cloud.google.com", Version: "v1beta1", Kind: "Project"},
ClusterScoped: false,
},
{
GVK: schema.GroupVersionKind{Group: "resourcemanager.cnrm.cloud.google.com", Version: "v1beta1", Kind: "Folder"},
ClusterScoped: false,
},
{
GVK: schema.GroupVersionKind{Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "ClusterRole"},
ClusterScoped: true,
},
{
GVK: schema.GroupVersionKind{Group: "rbac.authorization.k8s.io", Version: "v1", Kind: "Role"},
ClusterScoped: false,
},
{
GVK: schema.GroupVersionKind{Group: "", Version: "v1", Kind: "ServiceAccount"},
ClusterScoped: false,
},
{
GVK: schema.GroupVersionKind{Group: "config.porch.kpt.dev", Version: "v1alpha1", Kind: "WorkloadIdentityBinding"},
ClusterScoped: false,
},
}

func findKindInfo(gvk schema.GroupVersionKind) *kindInfo {
for i := range kindInfos {
ki := &kindInfos[i]
if ki.GVK == gvk {
return ki
}
}
return nil
}
82 changes: 82 additions & 0 deletions go/pkg/meta/namespaceref.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package meta

import (
"fmt"

"github.com/GoogleContainerTools/kpt-functions-sdk/go/fn"
"k8s.io/apimachinery/pkg/runtime/schema"
)

type namespaceRef struct {
parentObject *fn.SubObject

name string
fieldPath []string
}

func buildMetadataNamespaceReference(parentObject *fn.KubeObject) (Ref, error) {
namespace := parentObject.GetMap("metadata").GetString("namespace")
if namespace == "" {
return nil, fmt.Errorf("expected namespace to be set")
}
return &namespaceRef{
name: namespace,
parentObject: &parentObject.SubObject,
fieldPath: []string{"metadata", "namespace"},
}, nil
}

// buildRefNamespaceReference returns a Ref represented the namespace in a reference
func buildRefNamespaceReference(ref *fn.SubObject, fieldPath ...string) (Ref, error) {
namespace, _, _ := ref.NestedString(fieldPath...)
if namespace == "" {
return nil, fmt.Errorf("expected namespace to be set")
}
return &namespaceRef{
name: namespace,
parentObject: ref,
fieldPath: fieldPath,
}, nil
}

var _ Ref = &namespaceRef{}

func (r *namespaceRef) GetName() string {
return r.name
}

func (r *namespaceRef) SetName(name string) {
r.parentObject.SetNestedString(name, r.fieldPath...)
// r.parentObject.SetNestedString(name, "metadata", "namespace")
r.name = name
}

func (r *namespaceRef) GetNamespace() string {
return ""
}

func (r *namespaceRef) SetNamespace(namespace string) error {
return fmt.Errorf("cannot set namespace on Namespace ref")
}

func (r *namespaceRef) GroupVersionKind() schema.GroupVersionKind {
return schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Namespace"}
}

func (r *namespaceRef) GroupKind() schema.GroupKind {
return schema.GroupKind{Group: "", Kind: "Namespace"}
}
106 changes: 106 additions & 0 deletions go/pkg/meta/ownerref.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package meta

import (
"fmt"

"github.com/GoogleContainerTools/kpt-functions-sdk/go/fn"
"k8s.io/apimachinery/pkg/runtime/schema"
)

type ownerRef struct {
ref *fn.SubObject

gvk schema.GroupVersionKind
name string
namespace string
}

// buildOwnerReferences returns a Ref for any ownerReferences.
func buildOwnerReferences(parentObject *fn.KubeObject) ([]Ref, error) {
var refs []Ref
ownerReferences := parentObject.GetMap("metadata").GetSlice("ownerReferences")
for _, ownerReference := range ownerReferences {
namespace := ownerReference.GetString("namespace")
if namespace == "" {
namespace = parentObject.GetNamespace()
}
name := ownerReference.GetString("name")
if name == "" {
return nil, fmt.Errorf("expected name to be set")
}
apiVersion := ownerReference.GetString("apiVersion")
if apiVersion == "" {
return nil, fmt.Errorf("expected apiVersion to be set")
}
kind := ownerReference.GetString("kind")
if kind == "" {
return nil, fmt.Errorf("expected kind to be set")
}

gk, err := schema.ParseGroupVersion(apiVersion)
if err != nil {
return nil, fmt.Errorf("error parsing apiVersion %q: %w", apiVersion, err)
}
gvk := gk.WithKind(kind)
refs = append(refs, &ownerRef{
name: name,
namespace: namespace,
ref: ownerReference,
gvk: gvk,
})

if namespace != "" {
// TODO: Should we allow this? It's not part of the "real" ownerReference
r, err := buildRefNamespaceReference(ownerReference, "namespace")
if err != nil {
return nil, err
}
refs = append(refs, r)
}
}
return refs, nil
}

var _ Ref = &ownerRef{}

func (r *ownerRef) GetName() string {
return r.name
}

func (r *ownerRef) SetName(name string) {
r.ref.SetNestedString(name, "name")
r.name = name
}

func (r *ownerRef) GetNamespace() string {
return r.namespace
}

func (r *ownerRef) SetNamespace(namespace string) error {
if namespace == r.namespace {
return nil
}

return fmt.Errorf("cannot change namespace on ownerReference")
}

func (r *ownerRef) GroupVersionKind() schema.GroupVersionKind {
return r.gvk
}

func (r *ownerRef) GroupKind() schema.GroupKind {
return r.gvk.GroupKind()
}
Loading