Skip to content

Commit

Permalink
feat: add trace and pprof (#14)
Browse files Browse the repository at this point in the history
Signed-off-by: Yusan Kurban <[email protected]>
  • Loading branch information
yusank authored Mar 15, 2023
1 parent 6827122 commit 0e9bec9
Show file tree
Hide file tree
Showing 9 changed files with 303 additions and 64 deletions.
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,12 @@ If you want to use it in clientside with client-go, please use [pidalio](https:/

## Quick Start

### Apply crd files to your cluster
### Add Helm source
```shell
kubectl apply -f https://raw.githubusercontent.com/k-cloud-labs/pkg/main/charts/_crds/bases/policy.kcloudlabs.io_overridepolicies.yaml
kubectl apply -f https://raw.githubusercontent.com/k-cloud-labs/pkg/main/charts/_crds/bases/policy.kcloudlabs.io_clusteroverridepolicies.yaml
kubectl apply -f https://raw.githubusercontent.com/k-cloud-labs/pkg/main/charts/_crds/bases/policy.kcloudlabs.io_clustervalidatepolicies.yaml
helm repo add k-cloud-labs https://k-cloud-labs.github.io/helm-charts
```

### Deploy webhook to cluster
### Install
All resources will be applied to `kinitiras-system` namespace by default. You can modify the deployment files as your expect.

Pay attention to the deploy/webhook-configuration.yaml file. The default config will mutate and validate all kubernetes resources filtered by label `kinitiras.kcloudlabs.io/webhook: enabled`.
Expand All @@ -31,7 +29,7 @@ Pay attention to the deploy/webhook-configuration.yaml file. The default config
After all changes done, just apply it to your cluster.

```shell
kubectl apply -f deploy/
helm install kinitiras-webhook k-cloud-labs/kinitiras --namespace kinitiras-system --create-namespace
```

### Create policy
Expand Down
121 changes: 99 additions & 22 deletions cmd/app/options/options.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package options

import (
"fmt"
"strings"

"github.com/spf13/pflag"
Expand Down Expand Up @@ -42,7 +43,9 @@ type Options struct {
// KubeAPIBurst is the burst to allow while talking with kube-apiserver.
KubeAPIBurst int
// PreCacheResources is a list of resources name to pre-cache when start up.
PreCacheResources string
PreCacheResources *ResourceSlice
// EnablePProf is switch to enable/disable net/http/pprof. Default value as false.
EnablePProf bool
}

// NewOptions builds an empty options.
Expand All @@ -52,6 +55,7 @@ func NewOptions() *Options {

// AddFlags adds flags to the specified FlagSet.
func (o *Options) AddFlags(flags *pflag.FlagSet) {
o.PreCacheResources = NewPreCacheResources([]string{"Deployment/apps/v1", "ReplicaSet/apps/v1"})
flags.StringVar(&o.BindAddress, "bind-address", defaultBindAddress,
"The IP address on which to listen for the --secure-port port.")
flags.IntVar(&o.SecurePort, "secure-port", defaultPort,
Expand All @@ -63,8 +67,9 @@ func (o *Options) AddFlags(flags *pflag.FlagSet) {
flags.StringVar(&o.TLSMinVersion, "tls-min-version", defaultTLSMinVersion, "Minimum TLS version supported. Possible values: 1.0, 1.1, 1.2, 1.3.")
flags.Float32Var(&o.KubeAPIQPS, "kube-api-qps", 40.0, "QPS to use while talking with kube-apiserver. Doesn't cover events and node heartbeat apis which rate limiting is controlled by a different set of flags.")
flags.IntVar(&o.KubeAPIBurst, "kube-api-burst", 60, "Burst to use while talking with kube-apiserver. Doesn't cover events and node heartbeat apis which rate limiting is controlled by a different set of flags.")
flags.StringVar(&o.PreCacheResources, "pre-cache-resources", "Deployment/apps/v1,Replicas/apps/v1", "Resources list separate by comma, for example: Pod/v1,Deployment/apps/v1"+
flags.VarP(o.PreCacheResources, "pre-cache-resources", "", "Resources list separate by comma, for example: Pod/v1,Deployment/apps/v1"+
". Will pre cache those resources to get it quicker when policies refer resources from cluster.")
flags.BoolVar(&o.EnablePProf, "enable-pprof", false, "EnablePProf is switch to enable/disable net/http/pprof. Default value as false.")

globalflag.AddGlobalFlags(flags, "global")
}
Expand All @@ -76,31 +81,103 @@ func PrintFlags(flags *pflag.FlagSet) {
})
}

func (o *Options) PreCacheResourcesToGVKList() []schema.GroupVersionKind {
var (
resourceList = strings.Split(o.PreCacheResources, ",")
gvkList = make([]schema.GroupVersionKind, 0, len(resourceList))
)

for _, resource := range resourceList {
items := strings.Split(resource, "/")
if len(items) <= 1 {
// ignore it
continue
}
type ResourceSlice struct {
value *[]schema.GroupVersionKind
changed bool
}

func NewPreCacheResources(slice []string) *ResourceSlice {
value := make([]schema.GroupVersionKind, 0)
s := &ResourceSlice{value: &value}
_ = s.Replace(slice)
return s
}

gvk := schema.GroupVersionKind{
Kind: items[0],
Version: items[1],
func (s *ResourceSlice) String() string {
sb := &strings.Builder{}

for i, gvk := range *s.value {
if i != 0 {
sb.WriteString(",")
}
sb.WriteString(gvk.Kind + "/" + gvk.GroupVersion().String())
}

return "[" + sb.String() + "]"
}

func (s *ResourceSlice) Set(val string) error {
if s.value == nil {
return fmt.Errorf("no target (nil pointer to []string)")
}
if !s.changed {
*s.value = make([]schema.GroupVersionKind, 0)
}
gvk, err := s.readResource(val)
if err != nil {
return err
}
*s.value = append(*s.value, gvk)
s.changed = true
return nil
}

func (s *ResourceSlice) Type() string {
return "resourceSlice"
}

func (s *ResourceSlice) Append(val string) error {
gvk, err := s.readResource(val)
if err != nil {
return err
}

*s.value = append(*s.value, gvk)
return nil
}

if len(items) == 3 {
gvk.Group = items[1]
gvk.Version = items[2]
func (s *ResourceSlice) Replace(slice []string) error {
value := make([]schema.GroupVersionKind, 0, len(slice))
for _, str := range slice {
gvk, err := s.readResource(str)
if err != nil {
return err
}

gvkList = append(gvkList, gvk)
value = append(value, gvk)
}

return gvkList
*s.value = value
return nil
}

func (s *ResourceSlice) GetSlice() []string {
var slice = make([]string, 0, len(*s.value))
for _, gvk := range *s.value {
slice = append(slice, gvk.Kind+"/"+gvk.GroupVersion().String())
}

return slice
}

func (s *ResourceSlice) readResource(val string) (schema.GroupVersionKind, error) {
var gvk schema.GroupVersionKind
items := strings.Split(val, "/")
if len(items) <= 1 {
return gvk, fmt.Errorf("invalid gvk(%v)", val)
}

gvk.Kind = items[0]
gvk.Version = items[1]

if len(items) == 3 {
gvk.Group = items[1]
gvk.Version = items[2]
}

return gvk, nil
}

func (o *Options) PreCacheResourcesToGVKList() []schema.GroupVersionKind {
return *o.PreCacheResources.value
}
Loading

0 comments on commit 0e9bec9

Please sign in to comment.