Skip to content

Commit

Permalink
Implemented gwctl describe policycrds
Browse files Browse the repository at this point in the history
  • Loading branch information
Devaansh-Kumar committed Apr 3, 2024
1 parent 437eff1 commit 9c219d8
Show file tree
Hide file tree
Showing 4 changed files with 269 additions and 1 deletion.
19 changes: 18 additions & 1 deletion gwctl/cmd/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func NewDescribeCommand() *cobra.Command {
var allNamespacesFlag bool

cmd := &cobra.Command{
Use: "describe {policies|httproutes|gateways|gatewayclasses|backends|namespace} RESOURCE_NAME",
Use: "describe {policies|httproutes|gateways|gatewayclasses|backends|namespace|policycrd} RESOURCE_NAME",
Short: "Show details of a specific resource or group of resources",
Args: cobra.RangeArgs(1, 2),
Run: func(cmd *cobra.Command, args []string) {
Expand Down Expand Up @@ -95,6 +95,23 @@ func runDescribe(cmd *cobra.Command, args []string, params *utils.CmdParams) {
}
}
policiesPrinter.PrintDescribeView(policyList)

case "policycrd", "policycrds":
var policyCrdList []policymanager.PolicyCRD
if len(args) == 1 {
policyCrdList = params.PolicyManager.GetCRDs()
} else {
var found bool
policyCrd, found := params.PolicyManager.GetCRD(args[1])
if !found {
fmt.Fprintf(os.Stderr, "failed to find PolicyCrd: %v\n", err)
os.Exit(1)
}
if found {
policyCrdList = []policymanager.PolicyCRD{policyCrd}
}
}
policiesPrinter.PolicyCrd_PrintDescribeView(policyCrdList)

case "httproute", "httproutes":
filter := resourcediscovery.Filter{Namespace: ns}
Expand Down
35 changes: 35 additions & 0 deletions gwctl/pkg/policymanager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ func (p *PolicyManager) GetCRDs() []PolicyCRD {
return result
}

func (p *PolicyManager) GetCRD(name string) (PolicyCRD, bool) {
policyCrd, ok := p.policyCRDs[PolicyCrdID(name)]
return policyCrd, ok
}

func (p *PolicyManager) GetPolicies() []Policy {
var result []Policy
for _, policy := range p.policies {
Expand Down Expand Up @@ -196,6 +201,36 @@ func (p PolicyCRD) IsClusterScoped() bool {
return p.crd.Spec.Scope == apiextensionsv1.ClusterScoped
}

func (p PolicyCRD) Spec() map[string]interface{} {
spec := p.crd.Spec

var result map[string]interface{}
marshalledSpec, _ := json.Marshal(spec)
json.Unmarshal(marshalledSpec, &result)

return result
}

func (p PolicyCRD) Metadata() map[string]interface{} {
om := p.crd.ObjectMeta

var result map[string]interface{}
marshalledMetadata, _ := json.Marshal(om)
json.Unmarshal(marshalledMetadata, &result)

return result
}

func (p PolicyCRD) Status() map[string]interface{} {
status := p.crd.Status

var result map[string]interface{}
marshalledStatus, _ := json.Marshal(status)
json.Unmarshal(marshalledStatus, &result)

return result
}

type Policy struct {
u unstructured.Unstructured
// targetRef references the target object this policy is attached to. This
Expand Down
64 changes: 64 additions & 0 deletions gwctl/pkg/printer/policies.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import (
"sigs.k8s.io/gateway-api/gwctl/pkg/policymanager"
"sigs.k8s.io/yaml"

_ "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
_ "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/duration"
"k8s.io/utils/clock"
)
Expand Down Expand Up @@ -148,3 +150,65 @@ func (pp *PoliciesPrinter) PrintDescribeView(policies []policymanager.Policy) {
}
}
}

type policyCrdDescribeView struct {
// PolicyCrd *apiextensionsv1.CustomResourceDefinition `json:",omitempty"`
Name string `json:",omitempty"`
Namespace string `json:",omitempty"`
Labels map[string]string `json:",omitempty"`
Annotations map[string]string `json:",omitempty"`
APIVersion string `json:",omitempty"`
Kind string `json:",omitempty"`
Metadata map[string]interface{} `json:",omitempty"`
Spec map[string]interface{} `json:",omitempty"`
Status map[string]interface{} `json:",omitempty"`
}

func (pp *PoliciesPrinter) PolicyCrd_PrintDescribeView(policyCrds []policymanager.PolicyCRD) {
sort.Slice(policyCrds, func(i, j int) bool {
a := fmt.Sprintf("%v/%v", policyCrds[i].CRD().GetNamespace(), policyCrds[i].CRD().GetName())
b := fmt.Sprintf("%v/%v", policyCrds[j].CRD().GetNamespace(), policyCrds[j].CRD().GetName())
return a < b
})

for i, policyCrd := range policyCrds {
crd := policyCrd.CRD()

views := []policyCrdDescribeView{
{
Name: crd.Name,
Namespace: crd.Namespace,
},
{
Labels: crd.Labels,
Annotations: crd.Annotations,
},
{
APIVersion: crd.APIVersion,
Kind: crd.Kind,
},
{
Metadata: policyCrd.Metadata(),
},
{
Spec: policyCrd.Spec(),
},
{
Status: policyCrd.Status(),
},
}

for _, view := range views {
b, err := yaml.Marshal(view)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to marshal to yaml: %v\n", err)
os.Exit(1)
}
fmt.Fprint(pp.Out, string(b))
}

if i+1 != len(policyCrds) {
fmt.Fprintf(pp.Out, "\n\n")
}
}
}
152 changes: 152 additions & 0 deletions gwctl/pkg/printer/policies_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,3 +354,155 @@ timeoutpolicies.bar.com Direct Namespaced 5m
t.Errorf("Unexpected diff\ngot=\n%v\nwant=\n%v\ndiff (-want +got)=\n%v", got, want, diff)
}
}

func TestPolicyCrd_PrintDescribeView(t *testing.T) {
// fakeClock := testingclock.NewFakeClock(time.Now())
objects := []runtime.Object{
&apiextensionsv1.CustomResourceDefinition{
ObjectMeta: metav1.ObjectMeta{
Name: "healthcheckpolicies.foo.com",
Labels: map[string]string{
gatewayv1alpha2.PolicyLabelKey: "inherited",
},
},
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
Scope: apiextensionsv1.ClusterScoped,
Group: "foo.com",
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{{Name: "v1"}},
Names: apiextensionsv1.CustomResourceDefinitionNames{
Plural: "healthcheckpolicies",
Kind: "HealthCheckPolicy",
},
},
},
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "foo.com/v1",
"kind": "HealthCheckPolicy",
"metadata": map[string]interface{}{
"name": "health-check-gateway",
},
"spec": map[string]interface{}{
"override": map[string]interface{}{
"key1": "value-child-1",
},
"default": map[string]interface{}{
"key2": "value-child-2",
"key5": "value-child-5",
},
"targetRef": map[string]interface{}{
"group": "gateway.networking.k8s.io",
"kind": "Gateway",
"name": "foo-gateway",
"namespace": "default",
},
},
},
},

&apiextensionsv1.CustomResourceDefinition{
ObjectMeta: metav1.ObjectMeta{
Name: "timeoutpolicies.bar.com",
Labels: map[string]string{
gatewayv1alpha2.PolicyLabelKey: "direct",
},
},
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
Scope: apiextensionsv1.NamespaceScoped,
Group: "bar.com",
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{{Name: "v1"}},
Names: apiextensionsv1.CustomResourceDefinitionNames{
Plural: "timeoutpolicies",
Kind: "TimeoutPolicy",
},
},
},
&unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "bar.com/v1",
"kind": "TimeoutPolicy",
"metadata": map[string]interface{}{
"name": "timeout-policy-namespace",
},
"spec": map[string]interface{}{
"condition": "path=/abc",
"seconds": int64(30),
"targetRef": map[string]interface{}{
"kind": "Namespace",
"name": "default",
},
},
},
},
}

params := utils.MustParamsForTest(t, common.MustClientsForTest(t, objects...))
pp := &PoliciesPrinter{
Out: &bytes.Buffer{},
// Clock: fakeClock,
}
pp.PolicyCrd_PrintDescribeView(params.PolicyManager.GetCRDs())

got := pp.Out.(*bytes.Buffer).String()
want := `
Name: healthcheckpolicies.foo.com
Labels:
gateway.networking.k8s.io/policy: inherited
APIVersion: apiextensions.k8s.io/v1
Kind: CustomResourceDefinition
Metadata:
creationTimestamp: null
labels:
gateway.networking.k8s.io/policy: inherited
name: healthcheckpolicies.foo.com
resourceVersion: "999"
Spec:
group: foo.com
names:
kind: HealthCheckPolicy
plural: healthcheckpolicies
scope: Cluster
versions:
- name: v1
served: false
storage: false
Status:
acceptedNames:
kind: ""
plural: ""
conditions: null
storedVersions: null
Name: timeoutpolicies.bar.com
Labels:
gateway.networking.k8s.io/policy: direct
APIVersion: apiextensions.k8s.io/v1
Kind: CustomResourceDefinition
Metadata:
creationTimestamp: null
labels:
gateway.networking.k8s.io/policy: direct
name: timeoutpolicies.bar.com
resourceVersion: "999"
Spec:
group: bar.com
names:
kind: TimeoutPolicy
plural: timeoutpolicies
scope: Namespaced
versions:
- name: v1
served: false
storage: false
Status:
acceptedNames:
kind: ""
plural: ""
conditions: null
storedVersions: null
`
if diff := cmp.Diff(common.YamlString(want), common.YamlString(got), common.YamlStringTransformer); diff != "" {
t.Errorf("Unexpected diff\ngot=\n%v\nwant=\n%v\ndiff (-want +got)=\n%v", got, want, diff)
}
}

0 comments on commit 9c219d8

Please sign in to comment.