Skip to content

Commit 2beb0aa

Browse files
committedSep 25, 2023
Add effective policy calculation
- Rewrite packages to use PolicyManager - Drift away from using templates and start using custom structs for printing describe views
1 parent d9cbece commit 2beb0aa

File tree

21 files changed

+1253
-408
lines changed

21 files changed

+1253
-408
lines changed
 

‎cmd/gwctl/main.go

+23-5
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,33 @@
11
package main
22

33
import (
4+
"context"
45
_ "embed"
6+
"flag"
57
"fmt"
68
"os"
79
"path"
810

11+
"k8s.io/client-go/discovery"
912
"k8s.io/client-go/dynamic"
1013
"k8s.io/client-go/tools/clientcmd"
14+
"k8s.io/klog/v2"
1115
"sigs.k8s.io/controller-runtime/pkg/client"
1216
gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
1317
gatewayv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
1418

1519
"github.com/gauravkghildiyal/gwctl/pkg/cmd"
20+
"github.com/gauravkghildiyal/gwctl/pkg/policymanager"
1621
"github.com/gauravkghildiyal/gwctl/pkg/types"
1722
"github.com/spf13/cobra"
23+
cobraflag "github.com/spf13/pflag"
1824
)
1925

2026
func main() {
27+
klog.InitFlags(nil)
28+
flag.Parse()
29+
cobraflag.CommandLine.AddGoFlagSet(flag.CommandLine)
30+
2131
kubeconfig := os.Getenv("KUBECONFIG")
2232
if kubeconfig == "" {
2333
kubeconfig = path.Join(os.Getenv("HOME"), ".kube/config")
@@ -37,16 +47,24 @@ func main() {
3747

3848
dc := dynamic.NewForConfigOrDie(restConfig)
3949

40-
clients := &types.Clients{
41-
Client: client,
42-
DC: dc,
50+
policyManager := policymanager.New(dc)
51+
if err := policyManager.Init(context.Background()); err != nil {
52+
panic(err)
53+
}
54+
55+
params := &types.Params{
56+
Client: client,
57+
DC: dc,
58+
PolicyManager: policyManager,
59+
DiscoveryClient: discovery.NewDiscoveryClientForConfigOrDie(restConfig),
4360
}
4461

4562
rootCmd := &cobra.Command{
4663
Use: "gwctl",
4764
}
48-
rootCmd.AddCommand(cmd.NewGetCommand(clients))
49-
rootCmd.AddCommand(cmd.NewDescribeCommand(clients))
65+
rootCmd.AddCommand(cmd.NewGetCommand(params))
66+
rootCmd.AddCommand(cmd.NewDescribeCommand(params))
67+
5068
if err := rootCmd.Execute(); err != nil {
5169
os.Exit(1)
5270
}

‎go.mod

+6-5
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,18 @@ module github.com/gauravkghildiyal/gwctl
33
go 1.21
44

55
require (
6+
github.com/evanphx/json-patch v4.12.0+incompatible
67
github.com/spf13/cobra v1.7.0
8+
github.com/spf13/pflag v1.0.5
9+
k8s.io/api v0.27.3
710
k8s.io/apiextensions-apiserver v0.27.3
811
k8s.io/apimachinery v0.27.3
912
k8s.io/client-go v0.27.3
13+
k8s.io/klog/v2 v2.100.1
14+
k8s.io/utils v0.0.0-20230209194617-a36077c30491
1015
sigs.k8s.io/controller-runtime v0.14.6
1116
sigs.k8s.io/gateway-api v0.7.1
17+
sigs.k8s.io/yaml v1.3.0
1218
)
1319

1420
require (
@@ -35,7 +41,6 @@ require (
3541
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
3642
github.com/pkg/errors v0.9.1 // indirect
3743
github.com/rogpeppe/go-internal v1.11.0 // indirect
38-
github.com/spf13/pflag v1.0.5 // indirect
3944
golang.org/x/net v0.8.0 // indirect
4045
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect
4146
golang.org/x/sys v0.6.0 // indirect
@@ -47,11 +52,7 @@ require (
4752
gopkg.in/inf.v0 v0.9.1 // indirect
4853
gopkg.in/yaml.v2 v2.4.0 // indirect
4954
gopkg.in/yaml.v3 v3.0.1 // indirect
50-
k8s.io/api v0.27.3 // indirect
51-
k8s.io/klog/v2 v2.100.1 // indirect
5255
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect
53-
k8s.io/utils v0.0.0-20230209194617-a36077c30491 // indirect
5456
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
5557
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
56-
sigs.k8s.io/yaml v1.3.0 // indirect
5758
)

‎go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
5555
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
5656
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
5757
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
58+
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
59+
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
5860
github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww=
5961
github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4=
6062
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=

‎pkg/cmd/describe.go

+51-24
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@ import (
44
"context"
55
"fmt"
66
"os"
7+
"strings"
78

8-
gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
9+
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
10+
gatewayv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
911

12+
"github.com/gauravkghildiyal/gwctl/pkg/resources/backends"
1013
"github.com/gauravkghildiyal/gwctl/pkg/resources/gatewayclasses"
1114
"github.com/gauravkghildiyal/gwctl/pkg/resources/gateways"
1215
"github.com/gauravkghildiyal/gwctl/pkg/resources/httproutes"
@@ -20,15 +23,15 @@ type describeFlags struct {
2023
allNamespaces bool
2124
}
2225

23-
func NewDescribeCommand(clients *types.Clients) *cobra.Command {
26+
func NewDescribeCommand(params *types.Params) *cobra.Command {
2427
flags := &describeFlags{}
2528

2629
cmd := &cobra.Command{
2730
Use: "describe {policies|httproutes|gateways|gatewayclasses} RESOURCE_NAME",
2831
Short: "Show details of a specific resource or group of resources",
2932
Args: cobra.RangeArgs(1, 2),
3033
Run: func(cmd *cobra.Command, args []string) {
31-
runDescribe(args, clients, flags)
34+
runDescribe(args, params, flags)
3235
},
3336
}
3437
cmd.Flags().StringVarP(&flags.namespace, "namespace", "n", "default", "")
@@ -37,7 +40,7 @@ func NewDescribeCommand(clients *types.Clients) *cobra.Command {
3740
return cmd
3841
}
3942

40-
func runDescribe(args []string, clients *types.Clients, flags *describeFlags) {
43+
func runDescribe(args []string, params *types.Params, flags *describeFlags) {
4144
kind := args[0]
4245
ns := flags.namespace
4346
if flags.allNamespaces {
@@ -46,59 +49,83 @@ func runDescribe(args []string, clients *types.Clients, flags *describeFlags) {
4649

4750
switch kind {
4851
case "policy", "policies":
49-
policyList, err := policies.List(context.TODO(), clients, ns)
50-
if err != nil {
51-
panic(err)
52-
}
53-
policies.PrintDescribeView(clients, policyList)
52+
policyList := params.PolicyManager.GetPolicies()
53+
policies.PrintDescribeView(params, policyList)
5454
case "httproute", "httproutes":
55-
var httpRoutes []gatewayv1alpha2.HTTPRoute
55+
var httpRoutes []gatewayv1beta1.HTTPRoute
5656
if len(args) == 1 {
5757
var err error
58-
httpRoutes, err = httproutes.List(context.TODO(), clients, ns)
58+
httpRoutes, err = httproutes.List(context.TODO(), params, ns)
5959
if err != nil {
6060
panic(err)
6161
}
6262
} else {
63-
httpRoute, err := httproutes.Get(context.TODO(), clients, ns, args[1])
63+
httpRoute, err := httproutes.Get(context.TODO(), params, ns, args[1])
6464
if err != nil {
6565
panic(err)
6666
}
67-
httpRoutes = []gatewayv1alpha2.HTTPRoute{httpRoute}
67+
httpRoutes = []gatewayv1beta1.HTTPRoute{httpRoute}
6868
}
69-
httproutes.PrintDescribeView(context.TODO(), clients, httpRoutes)
69+
httproutes.PrintDescribeView(context.TODO(), params, httpRoutes)
7070
case "gateway", "gateways":
71-
var gws []gatewayv1alpha2.Gateway
71+
var gws []gatewayv1beta1.Gateway
7272
if len(args) == 1 {
7373
var err error
74-
gws, err = gateways.List(context.TODO(), clients, ns)
74+
gws, err = gateways.List(context.TODO(), params, ns)
7575
if err != nil {
7676
panic(err)
7777
}
7878
} else {
79-
gw, err := gateways.Get(context.TODO(), clients, ns, args[1])
79+
gw, err := gateways.Get(context.TODO(), params, ns, args[1])
8080
if err != nil {
8181
panic(err)
8282
}
83-
gws = []gatewayv1alpha2.Gateway{gw}
83+
gws = []gatewayv1beta1.Gateway{gw}
8484
}
85-
gateways.PrintDescribeView(context.TODO(), clients, gws)
85+
gateways.PrintDescribeView(context.TODO(), params, gws)
8686
case "gatewayclass", "gatewayclasses":
87-
var gwClasses []gatewayv1alpha2.GatewayClass
87+
var gwClasses []gatewayv1beta1.GatewayClass
8888
if len(args) == 1 {
8989
var err error
90-
gwClasses, err = gatewayclasses.List(context.TODO(), clients)
90+
gwClasses, err = gatewayclasses.List(context.TODO(), params)
91+
if err != nil {
92+
panic(err)
93+
}
94+
} else {
95+
gwc, err := gatewayclasses.Get(context.TODO(), params, args[1])
96+
if err != nil {
97+
panic(err)
98+
}
99+
gwClasses = []gatewayv1beta1.GatewayClass{gwc}
100+
}
101+
gatewayclasses.PrintDescribeView(context.TODO(), params, gwClasses)
102+
case "backend", "backends":
103+
var backendsList []unstructured.Unstructured
104+
105+
resourceType := "service"
106+
var resourceName string
107+
if len(args) > 1 {
108+
resourceName = args[1]
109+
a, b, ok := strings.Cut(args[1], "/")
110+
if ok {
111+
resourceType, resourceName = a, b
112+
}
113+
}
114+
115+
if resourceName == "" {
116+
var err error
117+
backendsList, err = backends.List(context.TODO(), params, resourceType, ns)
91118
if err != nil {
92119
panic(err)
93120
}
94121
} else {
95-
gwc, err := gatewayclasses.Get(context.TODO(), clients, args[1])
122+
backend, err := backends.Get(context.TODO(), params, resourceType, ns, resourceName)
96123
if err != nil {
97124
panic(err)
98125
}
99-
gwClasses = []gatewayv1alpha2.GatewayClass{gwc}
126+
backendsList = []unstructured.Unstructured{backend}
100127
}
101-
gatewayclasses.PrintDescribeView(context.TODO(), clients, gwClasses)
128+
backends.PrintDescribeView(context.TODO(), params, backendsList)
102129
default:
103130
fmt.Fprintf(os.Stderr, "Unrecognized RESOURCE_TYPE\n")
104131
}

‎pkg/cmd/get.go

+6-12
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ type getFlags struct {
1616
allNamespaces bool
1717
}
1818

19-
func NewGetCommand(clients *types.Clients) *cobra.Command {
19+
func NewGetCommand(params *types.Params) *cobra.Command {
2020
flags := &getFlags{}
2121

2222
cmd := &cobra.Command{
2323
Use: "get {policies|policycrds|httproutes}",
2424
Short: "Display one or many resources",
2525
Args: cobra.ExactArgs(1),
2626
Run: func(cmd *cobra.Command, args []string) {
27-
runGet(args, clients, flags)
27+
runGet(args, params, flags)
2828
},
2929
}
3030
cmd.Flags().StringVarP(&flags.namespace, "namespace", "n", "default", "")
@@ -33,7 +33,7 @@ func NewGetCommand(clients *types.Clients) *cobra.Command {
3333
return cmd
3434
}
3535

36-
func runGet(args []string, clients *types.Clients, flags *getFlags) {
36+
func runGet(args []string, params *types.Params, flags *getFlags) {
3737
kind := args[0]
3838
ns := flags.namespace
3939
if flags.allNamespaces {
@@ -42,19 +42,13 @@ func runGet(args []string, clients *types.Clients, flags *getFlags) {
4242

4343
switch kind {
4444
case "policy", "policies":
45-
list, err := policies.List(context.TODO(), clients, ns)
46-
if err != nil {
47-
panic(err)
48-
}
45+
list := params.PolicyManager.GetPolicies()
4946
policies.Print(list)
5047
case "policycrds":
51-
list, err := policies.ListCRDs(context.TODO(), clients)
52-
if err != nil {
53-
panic(err)
54-
}
48+
list := params.PolicyManager.GetCRDs()
5549
policies.PrintCRDs(list)
5650
case "httproute", "httproutes":
57-
list, err := httproutes.List(context.TODO(), clients, ns)
51+
list, err := httproutes.List(context.TODO(), params, ns)
5852
if err != nil {
5953
panic(err)
6054
}

‎pkg/policymanager/helpers.go

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package policymanager
2+
3+
// ToPolicyRefs returns the Object references of all given policies. Note that
4+
// these are not the value of targetRef within the Policies but rather the
5+
// reference to the Policy object itself.
6+
func ToPolicyRefs(policies []Policy) []ObjRef {
7+
var result []ObjRef
8+
for _, policy := range policies {
9+
result = append(result, ObjRef{
10+
Group: policy.Unstructured().GroupVersionKind().Group,
11+
Kind: policy.Unstructured().GroupVersionKind().Kind,
12+
Name: policy.Unstructured().GetName(),
13+
Namespace: policy.Unstructured().GetNamespace(),
14+
})
15+
}
16+
return result
17+
}

0 commit comments

Comments
 (0)
Please sign in to comment.