diff --git a/cmd/caelus/app/server.go b/cmd/caelus/app/server.go index ab03f29f..24f7e35c 100644 --- a/cmd/caelus/app/server.go +++ b/cmd/caelus/app/server.go @@ -24,7 +24,7 @@ import ( "github.com/tencent/caelus/pkg/caelus/checkpoint" "github.com/tencent/caelus/pkg/caelus/cpi" "github.com/tencent/caelus/pkg/caelus/diskquota" - "github.com/tencent/caelus/pkg/caelus/healthcheck" + health "github.com/tencent/caelus/pkg/caelus/healthcheck" "github.com/tencent/caelus/pkg/caelus/healthcheck/conflict" "github.com/tencent/caelus/pkg/caelus/metrics" "github.com/tencent/caelus/pkg/caelus/online" @@ -244,9 +244,13 @@ func (o *options) initModules(caelus *types.CaelusConfig, ctx *context.CaelusCon o.ApiOption.loadStatsMetric(metrics.StatsMetricDiskQuota, diskquotaManager) } // health check manager - healthCheckManager = health.NewHealthManager(types.InitHealthCheckConfigFunc(&caelus.Metrics.Node, - &caelus.Predicts[0].ReserveResource), stStore, resourceManager, qosManager, - conflictMn, podInformer) + nodeInformer := ctx.GetNodeFactory().Core().V1().Nodes() + ruleCheckInformer := ctx.GetCaelusFactory().Caelus().V1().RuleChecks() + cgroupNotifyInformer := ctx.GetCaelusFactory().Caelus().V1().CgroupNotifies() + + healthCheckManager = health.NewHealthManager(stStore, resourceManager, qosManager, conflictMn, podInformer, + nodeInformer, ruleCheckInformer, cgroupNotifyInformer, &caelus.Predicts[0].ReserveResource, + types.RuleCheckAvailableFunc(&caelus.Metrics.Node, &caelus.Predicts[0].ReserveResource)) modules = append(modules, healthCheckManager) return modules diff --git a/cmd/caelus/context/context.go b/cmd/caelus/context/context.go index 8982d808..448093d0 100644 --- a/cmd/caelus/context/context.go +++ b/cmd/caelus/context/context.go @@ -18,22 +18,29 @@ package context import ( "time" + caelusclient "github.com/tencent/caelus/pkg/generated/clientset/versioned" + caelusfake "github.com/tencent/caelus/pkg/generated/clientset/versioned/fake" + caelusinformers "github.com/tencent/caelus/pkg/generated/informers/externalversions" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/fields" "k8s.io/client-go/informers" clientset "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/fake" + "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" "k8s.io/klog/v2" ) -// CaelusContext stores k8s client and factory +// CaelusContext stores k8s&caelus client and factory type CaelusContext struct { Master string Kubeconfig string NodeName string kubeClient clientset.Interface + caelusClient caelusclient.Interface nodeFactory, podFactory informers.SharedInformerFactory + caelusFactory caelusinformers.SharedInformerFactory } const ( @@ -45,17 +52,35 @@ const ( // lazyInit build kubernetes client func (c *CaelusContext) lazyInit() { - if c.kubeClient != nil { - return + var kubeconfig *rest.Config = nil + var err error + if c.kubeClient == nil { + kubeconfig, err = clientcmd.BuildConfigFromFlags(c.Master, c.Kubeconfig) + if err != nil { + klog.Warning(err) + klog.Warning("fall back to creating fake kube-client") + // create a fake client to test caelus without k8s + c.kubeClient = fake.NewSimpleClientset() + } else { + c.kubeClient = clientset.NewForConfigOrDie(kubeconfig) + } + } - kubeconfig, err := clientcmd.BuildConfigFromFlags(c.Master, c.Kubeconfig) - if err != nil { - klog.Warning(err) - klog.Warning("fall back to creating fake kube-client") - // create a fake client to test caelus without k8s - c.kubeClient = fake.NewSimpleClientset() - } else { - c.kubeClient = clientset.NewForConfigOrDie(kubeconfig) + + // init caelus client + if c.caelusClient == nil { + err = nil + if kubeconfig == nil { + kubeconfig, err = clientcmd.BuildConfigFromFlags(c.Master, c.Kubeconfig) + } + if err != nil { + klog.Warning(err) + klog.Warning("fall back to creating fake caelus-client") + // create a fake client to test caelus without k8s + c.caelusClient = caelusfake.NewSimpleClientset() + } else { + c.caelusClient = caelusclient.NewForConfigOrDie(kubeconfig) + } } } @@ -65,6 +90,12 @@ func (c *CaelusContext) GetKubeClient() clientset.Interface { return c.kubeClient } +// GetCaelusClient returns caelus client +func (c *CaelusContext) GetCaelusClient() caelusclient.Interface { + c.lazyInit() + return c.caelusClient +} + // GetPodFactory returns pod factory func (c *CaelusContext) GetPodFactory() informers.SharedInformerFactory { if c.podFactory == nil { @@ -79,6 +110,14 @@ func (c *CaelusContext) GetPodFactory() informers.SharedInformerFactory { return c.podFactory } +// GetCaelusFactory returns ruleCheck factory +func (c *CaelusContext) GetCaelusFactory() caelusinformers.SharedInformerFactory { + if c.caelusFactory == nil { + c.caelusFactory = caelusinformers.NewSharedInformerFactoryWithOptions(c.GetCaelusClient(), 0) + } + return c.caelusFactory +} + // GetNodeFactory returns node factory func (c *CaelusContext) GetNodeFactory() informers.SharedInformerFactory { if c.nodeFactory == nil { @@ -105,4 +144,8 @@ func (c *CaelusContext) Run(stop <-chan struct{}) { c.nodeFactory.Start(stop) c.nodeFactory.WaitForCacheSync(stop) } + if c.caelusFactory != nil { + c.caelusFactory.Start(stop) + c.caelusFactory.WaitForCacheSync(stop) + } } diff --git a/doc/rules.md b/doc/rules.md index 4faf469f..25ad0ab5 100644 --- a/doc/rules.md +++ b/doc/rules.md @@ -1,9 +1,12 @@ # Detection configuration - Caelus dynamically checks abnormalities of various metrics based on [rules.json](../hack/config/rules.json), such as CPU + Caelus dynamically checks abnormalities of various metrics based on CRDs of `RuleCheck` and `CgroupNotify` + , such as CPU usage or online latency, to make sure online jobs run normally. Batch jobs will be throttled or even killed if interference detected. - This document describes how to configure [rules.json](../hack/config/rules.json) + This document describes how to configure these CRDs. + + > **Attention**: Multiple `RuleCheck` or `CgroupNotify` can exist in a cluster, and they will be merged based on the set priority and creation time. ## 1.Rules Rules are used to assign the algorithm to check if the timed metrics have significant fluctuations, such as EWMA, @@ -103,7 +106,7 @@ type NodeCpu struct { ... } ``` - Node rules example: + Node rules json example: ```json { "name": "cpu", @@ -145,6 +148,46 @@ type NodeCpu struct { ] } ``` +Node rules yaml example: +```yaml +apiVersion: caelus.io/v1 +kind: RuleCheck +metadata: + name: caelus-test1 + namespace: caelus-system +spec: + name: cpu + priority: 90 + nodeSelector: + disktype: "ssd" + type: node + metrics: + - cpu_avg + checkInterval: 10 + handleInterval: 10 + recoverInterval: 15 + rules: + - detects: + - name: expression + args: |- + { + "expression": "auto", + "warning_count": 10, + "warning_duration": "10s" + } + - actions: + - name: adjust + args: |- + { + "resources": [ + { + "step": "1000m" + }] + } + - name: schedule + args: |- + {} +``` ### Container rules Container rules describe how to detect metrics of container level, the supported metrics could be found from @@ -158,7 +201,7 @@ type CgroupStats struct { } ``` - Container rules example: + Container rules json example: ```json { "metrics": [ @@ -181,6 +224,34 @@ type CgroupStats struct { ] } ``` + +Container rules yaml example: +```yaml +apiVersion: caelus.io/v1 +kind: RuleCheck +metadata: + name: caelus-test2 + namespace: caelus-system +spec: + name: cpu + priority: 90 + nodeSelector: + disktype: "ssd" + type: container + metrics: + - nr_cpu_throttled + checkInterval: 5 + handleInterval: 10 + recoverInterval: 15 + rules: + - detects: + - name: expression + args: | + { + "expression": "nr_cpu_throttled > 0" + } +``` + ### App rules App rules describe how to detect metrics of app level, the metrics are provided by users themselves, in the way of executable command or http server, the example as flowing: @@ -336,3 +407,26 @@ type CgroupStats struct { ] } ``` + +Memory cgroup event yaml example: +```yaml +apiVersion: caelus.io/v1 +kind: CgroupNotify +metadata: + name: caelus-test1 + namespace: kube-system +spec: + priority: 90 + nodeSelector: + type: "memory" + memory_cgroup: + pressures: + - cgroups: ["/kubepods/offline"] + pressure_level: "low" + duration: 3 + count: 2 + usages: + - cgroups: ["/kubepods/offline/test"] + margin_mb: 2048 + duration: 60000 +``` \ No newline at end of file diff --git a/go.mod b/go.mod index e5e51ff4..f22ae86a 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,6 @@ require ( github.com/docker/engine-api v0.4.0 github.com/emicklei/go-restful v2.9.5+incompatible github.com/fatih/structs v1.1.0 - github.com/fsnotify/fsnotify v1.6.0 github.com/google/cadvisor v0.46.0 github.com/guillermo/go.procmeminfo v0.0.0-20131127224636-be4355a9fb0e github.com/json-iterator/go v1.1.12 @@ -22,7 +21,7 @@ require ( github.com/spf13/cobra v1.6.0 github.com/spf13/pflag v1.0.5 github.com/vishvananda/netlink v1.1.1-0.20200915183220-339a215d6544 - golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10 + golang.org/x/net v0.8.0 golang.org/x/sys v0.6.0 gotest.tools v2.2.0+incompatible k8s.io/api v0.26.0 @@ -30,7 +29,9 @@ require ( k8s.io/apiserver v0.26.0 k8s.io/autoscaler/vertical-pod-autoscaler v0.10.0 k8s.io/client-go v0.26.0 + k8s.io/code-generator v0.29.3 k8s.io/component-base v0.26.0 + k8s.io/klog v1.0.0 k8s.io/klog/v2 v2.80.1 k8s.io/kubernetes v1.26.0 k8s.io/utils v0.0.0-20221107191617-1a15be271d1d @@ -56,6 +57,7 @@ require ( github.com/emicklei/go-restful/v3 v3.9.0 // indirect github.com/euank/go-kmsg-parser v2.0.0+incompatible // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-ole/go-ole v1.2.4 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect @@ -95,15 +97,18 @@ require ( github.com/stretchr/testify v1.8.0 // indirect github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae // indirect + golang.org/x/mod v0.9.0 // indirect golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect - golang.org/x/term v0.3.0 // indirect - golang.org/x/text v0.5.0 // indirect + golang.org/x/term v0.6.0 // indirect + golang.org/x/text v0.8.0 // indirect golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect + golang.org/x/tools v0.7.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/gengo v0.0.0-20220902162205-c0856e24416d // indirect k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect moul.io/http2curl v1.0.0 // indirect sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect diff --git a/go.sum b/go.sum index ee0843cb..8d08cd3f 100644 --- a/go.sum +++ b/go.sum @@ -531,6 +531,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -572,8 +574,9 @@ golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10 h1:Frnccbp+ok2GkUS2tC84yAq/U9Vg+0sIO7aRL3T4Xnc= golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -596,6 +599,7 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sys v0.0.0-20160601133225-076b54675315/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -667,8 +671,9 @@ golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -677,8 +682,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -734,6 +740,8 @@ golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -879,12 +887,17 @@ k8s.io/autoscaler/vertical-pod-autoscaler v0.10.0 h1:mSO9phIinHH3bRuXQkHMIA2uJ4i k8s.io/autoscaler/vertical-pod-autoscaler v0.10.0/go.mod h1:sOm4JDB+0ZrrqFuscsbWL5KoFMMJuOrN1NE/6ulmYNA= k8s.io/client-go v0.26.0 h1:lT1D3OfO+wIi9UFolCrifbjUUgu7CpLca0AD8ghRLI8= k8s.io/client-go v0.26.0/go.mod h1:I2Sh57A79EQsDmn7F7ASpmru1cceh3ocVT9KlX2jEZg= +k8s.io/code-generator v0.24.2-rc.0 h1:YJ84GfXEa+pyes7haYF2aljlK6wj79qAPQTR1Dbg1tc= k8s.io/code-generator v0.24.2-rc.0/go.mod h1:dpVhs00hTuTdTY6jvVxvTFCk6gSMrtfRydbhZwHI15w= k8s.io/component-base v0.26.0 h1:0IkChOCohtDHttmKuz+EP3j3+qKmV55rM9gIFTXA7Vs= k8s.io/component-base v0.26.0/go.mod h1:lqHwlfV1/haa14F/Z5Zizk5QmzaVf23nQzCwVOQpfC8= k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/gengo v0.0.0-20211129171323-c02415ce4185/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/gengo v0.0.0-20220902162205-c0856e24416d h1:U9tB195lKdzwqicbJvyJeOXV7Klv+wNAWENRnXEGi08= +k8s.io/gengo v0.0.0-20220902162205-c0856e24416d/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= diff --git a/hack/boilerplate.go.txt b/hack/boilerplate.go.txt new file mode 100644 index 00000000..2fbfd10a --- /dev/null +++ b/hack/boilerplate.go.txt @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2021 THL A29 Limited, a Tencent company. + * + * 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. + */ \ No newline at end of file diff --git a/hack/tool.go b/hack/tool.go new file mode 100644 index 00000000..ed8aab6e --- /dev/null +++ b/hack/tool.go @@ -0,0 +1,3 @@ +package tools + +import _ "k8s.io/code-generator" diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh new file mode 100755 index 00000000..046c0225 --- /dev/null +++ b/hack/update-codegen.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +# Copyright (c) 2021 THL A29 Limited, a Tencent company. +# +# 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. + +set -o errexit +set -o nounset +set -o pipefail + +SCRIPT_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. +CODEGEN_PKG=$(go env GOPATH)/pkg/mod/k8s.io/code-generator@v0.24.2-rc.0 +echo $SCRIPT_ROOT +# generate the code with: +# --output-base because this script should also be able to run inside the vendor dir of +# k8s.io/kubernetes. The output-base is needed for the generators to output into the vendor dir +# instead of the $GOPATH directly. For normal projects this can be dropped. +bash "${CODEGEN_PKG}"/generate-groups.sh "deepcopy,client,informer,lister" \ + github.com/tencent/caelus/pkg/generated github.com/tencent/caelus/pkg/apis \ + caelus:v1 \ + --output-base "$(dirname "${BASH_SOURCE[0]}")/../../../.." \ + --go-header-file "${SCRIPT_ROOT}"/hack/boilerplate.go.txt + +# To use your own boilerplate text append: +# --go-header-file "${SCRIPT_ROOT}"/hack/custom-boilerplate.go.txt \ No newline at end of file diff --git a/hack/yaml/caelus.yaml b/hack/yaml/caelus.yaml index 97fcefa1..64386d1d 100644 --- a/hack/yaml/caelus.yaml +++ b/hack/yaml/caelus.yaml @@ -1,10 +1,274 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: rulechecks.caelus.io +spec: + group: caelus.io + names: + kind: RuleCheck + listKind: RuleCheckList + plural: rulechecks + singular: rulecheck + scope: Cluster + versions: + - name: v1 + schema: + openAPIV3Schema: + description: RuleCheck is a specification for a RuleCheck resource + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: RuleCheckSpec is the spec for a RuleCheck resource + properties: + checkInterval: + description: CheckInterval describes the interval to trigger detection + format: int64 + type: integer + handleInterval: + description: HandleInterval describes the interval to handle conflicts + after detecting abnormal result + format: int64 + type: integer + metrics: + items: + type: string + type: array + name: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + priority: + format: int32 + type: integer + recoverInterval: + description: RecoverInterval describes the interval to recover conflicts + after detecting normal result + format: int64 + type: integer + recoverRules: + items: + description: DetectActionRules define detectors and actions + properties: + actions: + items: + description: DetectAction define detector config + properties: + args: + type: string + name: + type: string + required: + - args + - name + type: object + type: array + detects: + items: + description: DetectAction define detector config + properties: + args: + type: string + name: + type: string + required: + - args + - name + type: object + type: array + type: object + type: array + rules: + items: + description: DetectActionRules define detectors and actions + properties: + actions: + items: + description: DetectAction define detector config + properties: + args: + type: string + name: + type: string + required: + - args + - name + type: object + type: array + detects: + items: + description: DetectAction define detector config + properties: + args: + type: string + name: + type: string + required: + - args + - name + type: object + type: array + type: object + type: array + type: + type: string + required: + - checkInterval + - handleInterval + - metrics + - name + - recoverInterval + - rules + - type + type: object + status: + description: RuleCheckStatus is the status for a RuleCheck resource + type: object + required: + - spec + type: object + served: true + storage: true +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: cgroupnotifies.caelus.io +spec: + group: caelus.io + names: + kind: CgroupNotify + listKind: CgroupNotifyList + plural: cgroupnotifies + singular: cgroupnotify + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: CgroupNotify is a specification for a CgroupNotify resource + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: CgroupNotifySpec is the spec for a CgroupNotify resource + properties: + memory_cgroup: + description: MemoryNotifyConfig describe memory cgroup notify + properties: + pressures: + items: + description: MemoryPressureNotifyConfig describe memory.pressure_level + notify data + properties: + cgroups: + items: + type: string + type: array + count: + description: assign event number in the duration time + type: integer + duration: + description: assign time duration the pressure has kept + format: int64 + type: integer + pressure_level: + type: string + required: + - cgroups + - count + - duration + - pressure_level + type: object + type: array + usages: + items: + description: MemoryUsageNotifyConfig describe memory.usage_in_bytes + notify data + properties: + cgroups: + items: + type: string + type: array + duration: + description: when to handle event after receiving event + format: int64 + type: integer + margin_mb: + description: the distance between limit and threshold + type: integer + required: + - cgroups + - duration + - margin_mb + type: object + type: array + required: + - pressures + - usages + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priority: + format: int32 + type: integer + required: + - memory_cgroup + type: object + status: + description: CgroupNotifyStatus is the status for a CgroupNotify resource + type: object + required: + - spec + type: object + served: true + storage: true +--- apiVersion: v1 kind: ServiceAccount metadata: name: caelus namespace: kube-system --- -apiVersion: rbac.authorization.k8s.io/v1beta1 +apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: labels: @@ -20,8 +284,13 @@ rules: - apiGroups: [""] resources: ["pods/eviction"] verbs: ["create"] + - apiGroups: ["caelus.io"] + resources: + - rulechecks + - cgroupnotifies + verbs: ["list", "watch", "get", "update", "delete"] --- -apiVersion: rbac.authorization.k8s.io/v1beta1 +apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: annotations: diff --git a/pkg/apis/caelus/register.go b/pkg/apis/caelus/register.go new file mode 100644 index 00000000..5246cfb0 --- /dev/null +++ b/pkg/apis/caelus/register.go @@ -0,0 +1,5 @@ +package caelus + +const ( + GroupName = "caelus.io" +) diff --git a/pkg/apis/caelus/v1/cgroupnotify_types.go b/pkg/apis/caelus/v1/cgroupnotify_types.go new file mode 100644 index 00000000..3ba5f5ec --- /dev/null +++ b/pkg/apis/caelus/v1/cgroupnotify_types.go @@ -0,0 +1,65 @@ +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/tencent/caelus/pkg/util/times" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CgroupNotify is a specification for a CgroupNotify resource +type CgroupNotify struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec CgroupNotifySpec `json:"spec"` + Status CgroupNotifyStatus `json:"status,omitempty"` +} + +// CgroupNotifySpec is the spec for a CgroupNotify resource +type CgroupNotifySpec struct { + MemoryCgroup MemoryNotifyConfig `json:"memory_cgroup"` + NodeSelector map[string]string `json:"nodeSelector,omitempty"` + Priority int32 `json:"priority,omitempty"` +} + +// MemoryNotifyConfig describe memory cgroup notify +type MemoryNotifyConfig struct { + Pressures []MemoryPressureNotifyConfig `json:"pressures"` + Usages []MemoryUsageNotifyConfig `json:"usages"` +} + +// MemoryPressureNotifyConfig describe memory.pressure_level notify data +type MemoryPressureNotifyConfig struct { + Cgroups []string `json:"cgroups"` + PressureLevel string `json:"pressure_level"` + // assign time duration the pressure has kept + Duration times.Duration `json:"duration"` + // assign event number in the duration time + Count int `json:"count"` +} + +// MemoryUsageNotifyConfig describe memory.usage_in_bytes notify data +type MemoryUsageNotifyConfig struct { + Cgroups []string `json:"cgroups"` + // the distance between limit and threshold + MarginMb int `json:"margin_mb"` + // when to handle event after receiving event + Duration times.Duration `json:"duration"` +} + +// CgroupNotifyStatus is the status for a CgroupNotify resource +type CgroupNotifyStatus struct { +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// CgroupNotifyList is a list of CgroupNotify resources +type CgroupNotifyList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []CgroupNotify `json:"items"` +} diff --git a/pkg/apis/caelus/v1/doc.go b/pkg/apis/caelus/v1/doc.go new file mode 100644 index 00000000..71fb844c --- /dev/null +++ b/pkg/apis/caelus/v1/doc.go @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2021 THL A29 Limited, a Tencent company. + * + * 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. + */ + +// +k8s:deepcopy-gen=package +// +groupName=caelus + +package v1 diff --git a/pkg/apis/caelus/v1/register.go b/pkg/apis/caelus/v1/register.go new file mode 100644 index 00000000..1ce75746 --- /dev/null +++ b/pkg/apis/caelus/v1/register.go @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021 THL A29 Limited, a Tencent company. + * + * 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 v1 + +import ( + "github.com/tencent/caelus/pkg/apis/caelus" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// SchemeGroupVersion is group version used to register these objects +var SchemeGroupVersion = schema.GroupVersion{Group: caelus.GroupName, Version: "v1"} + +// Kind takes an unqualified kind and returns back a Group qualified GroupKind +func Kind(kind string) schema.GroupKind { + return SchemeGroupVersion.WithKind(kind).GroupKind() +} + +// Resource takes an unqualified resource and returns a Group qualified GroupResource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +var ( + // SchemeBuilder initializes a scheme builder + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + // AddToScheme is a global function that registers this API group & version to a scheme + AddToScheme = SchemeBuilder.AddToScheme +) + +// Adds the list of known types to Scheme. +func addKnownTypes(scheme *runtime.Scheme) error { + scheme.AddKnownTypes(SchemeGroupVersion, + &RuleCheck{}, + &RuleCheckList{}, + &CgroupNotify{}, + &CgroupNotifyList{}, + ) + metav1.AddToGroupVersion(scheme, SchemeGroupVersion) + return nil +} diff --git a/pkg/apis/caelus/v1/rulecheck_types.go b/pkg/apis/caelus/v1/rulecheck_types.go new file mode 100644 index 00000000..c775c17a --- /dev/null +++ b/pkg/apis/caelus/v1/rulecheck_types.go @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2021 THL A29 Limited, a Tencent company. + * + * 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 v1 + +import ( + "github.com/tencent/caelus/pkg/util/times" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type RuleCheckType string + +const ( + AppType RuleCheckType = "app" + NodeType RuleCheckType = "node" + ContainerType RuleCheckType = "container" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// RuleCheck is a specification for a RuleCheck resource +type RuleCheck struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec RuleCheckSpec `json:"spec"` + Status RuleCheckStatus `json:"status,omitempty"` +} + +// RuleCheckSpec is the spec for a RuleCheck resource +type RuleCheckSpec struct { + Name string `json:"name"` + NodeSelector map[string]string `json:"nodeSelector,omitempty"` + Priority int32 `json:"priority,omitempty"` + Type RuleCheckType `json:"type"` + Metrics []string `json:"metrics"` + + // CheckInterval describes the interval to trigger detection + CheckInterval *times.Duration `json:"checkInterval"` + // HandleInterval describes the interval to handle conflicts after detecting abnormal result + HandleInterval *times.Duration `json:"handleInterval"` + // RecoverInterval describes the interval to recover conflicts after detecting normal result + RecoverInterval *times.Duration `json:"recoverInterval"` + + Rules []*DetectActionRules `json:"rules"` + RecoverRules []*DetectActionRules `json:"recoverRules"` +} + +// DetectActionRules define detectors and actions +type DetectActionRules struct { + Detects []*DetectAction `json:"detects"` + Actions []*DetectAction `json:"actions"` +} + +// DetectAction define detector config +type DetectAction struct { + Name string `json:"name"` + Args string `json:"args"` +} + +// RuleCheckStatus is the status for a RuleCheck resource +type RuleCheckStatus struct { +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// RuleCheckList is a list of RuleCheck resources +type RuleCheckList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + + Items []RuleCheck `json:"items"` +} diff --git a/pkg/apis/caelus/v1/zz_generated.deepcopy.go b/pkg/apis/caelus/v1/zz_generated.deepcopy.go new file mode 100644 index 00000000..5bf4169d --- /dev/null +++ b/pkg/apis/caelus/v1/zz_generated.deepcopy.go @@ -0,0 +1,396 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1 + +import ( + times "github.com/tencent/caelus/pkg/util/times" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CgroupNotify) DeepCopyInto(out *CgroupNotify) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CgroupNotify. +func (in *CgroupNotify) DeepCopy() *CgroupNotify { + if in == nil { + return nil + } + out := new(CgroupNotify) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CgroupNotify) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CgroupNotifyList) DeepCopyInto(out *CgroupNotifyList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]CgroupNotify, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CgroupNotifyList. +func (in *CgroupNotifyList) DeepCopy() *CgroupNotifyList { + if in == nil { + return nil + } + out := new(CgroupNotifyList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *CgroupNotifyList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CgroupNotifySpec) DeepCopyInto(out *CgroupNotifySpec) { + *out = *in + in.MemoryCgroup.DeepCopyInto(&out.MemoryCgroup) + if in.NodeSelector != nil { + in, out := &in.NodeSelector, &out.NodeSelector + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CgroupNotifySpec. +func (in *CgroupNotifySpec) DeepCopy() *CgroupNotifySpec { + if in == nil { + return nil + } + out := new(CgroupNotifySpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CgroupNotifyStatus) DeepCopyInto(out *CgroupNotifyStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CgroupNotifyStatus. +func (in *CgroupNotifyStatus) DeepCopy() *CgroupNotifyStatus { + if in == nil { + return nil + } + out := new(CgroupNotifyStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DetectAction) DeepCopyInto(out *DetectAction) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DetectAction. +func (in *DetectAction) DeepCopy() *DetectAction { + if in == nil { + return nil + } + out := new(DetectAction) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DetectActionRules) DeepCopyInto(out *DetectActionRules) { + *out = *in + if in.Detects != nil { + in, out := &in.Detects, &out.Detects + *out = make([]*DetectAction, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(DetectAction) + **out = **in + } + } + } + if in.Actions != nil { + in, out := &in.Actions, &out.Actions + *out = make([]*DetectAction, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(DetectAction) + **out = **in + } + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DetectActionRules. +func (in *DetectActionRules) DeepCopy() *DetectActionRules { + if in == nil { + return nil + } + out := new(DetectActionRules) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MemoryNotifyConfig) DeepCopyInto(out *MemoryNotifyConfig) { + *out = *in + if in.Pressures != nil { + in, out := &in.Pressures, &out.Pressures + *out = make([]MemoryPressureNotifyConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Usages != nil { + in, out := &in.Usages, &out.Usages + *out = make([]MemoryUsageNotifyConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MemoryNotifyConfig. +func (in *MemoryNotifyConfig) DeepCopy() *MemoryNotifyConfig { + if in == nil { + return nil + } + out := new(MemoryNotifyConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MemoryPressureNotifyConfig) DeepCopyInto(out *MemoryPressureNotifyConfig) { + *out = *in + if in.Cgroups != nil { + in, out := &in.Cgroups, &out.Cgroups + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MemoryPressureNotifyConfig. +func (in *MemoryPressureNotifyConfig) DeepCopy() *MemoryPressureNotifyConfig { + if in == nil { + return nil + } + out := new(MemoryPressureNotifyConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MemoryUsageNotifyConfig) DeepCopyInto(out *MemoryUsageNotifyConfig) { + *out = *in + if in.Cgroups != nil { + in, out := &in.Cgroups, &out.Cgroups + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MemoryUsageNotifyConfig. +func (in *MemoryUsageNotifyConfig) DeepCopy() *MemoryUsageNotifyConfig { + if in == nil { + return nil + } + out := new(MemoryUsageNotifyConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RuleCheck) DeepCopyInto(out *RuleCheck) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RuleCheck. +func (in *RuleCheck) DeepCopy() *RuleCheck { + if in == nil { + return nil + } + out := new(RuleCheck) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RuleCheck) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RuleCheckList) DeepCopyInto(out *RuleCheckList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]RuleCheck, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RuleCheckList. +func (in *RuleCheckList) DeepCopy() *RuleCheckList { + if in == nil { + return nil + } + out := new(RuleCheckList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RuleCheckList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RuleCheckSpec) DeepCopyInto(out *RuleCheckSpec) { + *out = *in + if in.NodeSelector != nil { + in, out := &in.NodeSelector, &out.NodeSelector + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Metrics != nil { + in, out := &in.Metrics, &out.Metrics + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.CheckInterval != nil { + in, out := &in.CheckInterval, &out.CheckInterval + *out = new(times.Duration) + **out = **in + } + if in.HandleInterval != nil { + in, out := &in.HandleInterval, &out.HandleInterval + *out = new(times.Duration) + **out = **in + } + if in.RecoverInterval != nil { + in, out := &in.RecoverInterval, &out.RecoverInterval + *out = new(times.Duration) + **out = **in + } + if in.Rules != nil { + in, out := &in.Rules, &out.Rules + *out = make([]*DetectActionRules, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(DetectActionRules) + (*in).DeepCopyInto(*out) + } + } + } + if in.RecoverRules != nil { + in, out := &in.RecoverRules, &out.RecoverRules + *out = make([]*DetectActionRules, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(DetectActionRules) + (*in).DeepCopyInto(*out) + } + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RuleCheckSpec. +func (in *RuleCheckSpec) DeepCopy() *RuleCheckSpec { + if in == nil { + return nil + } + out := new(RuleCheckSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RuleCheckStatus) DeepCopyInto(out *RuleCheckStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RuleCheckStatus. +func (in *RuleCheckStatus) DeepCopy() *RuleCheckStatus { + if in == nil { + return nil + } + out := new(RuleCheckStatus) + in.DeepCopyInto(out) + return out +} diff --git a/pkg/caelus/healthcheck/health_check.go b/pkg/caelus/healthcheck/health_check.go index a1dd08c0..f67f083c 100644 --- a/pkg/caelus/healthcheck/health_check.go +++ b/pkg/caelus/healthcheck/health_check.go @@ -16,14 +16,12 @@ package health import ( - "crypto/md5" - "encoding/hex" - "io" - "os" - "path/filepath" - - "github.com/fsnotify/fsnotify" - "github.com/tencent/caelus/pkg/caelus/healthcheck/cgroupnotify" + "reflect" + "sort" + "time" + + v1 "github.com/tencent/caelus/pkg/apis/caelus/v1" + notify "github.com/tencent/caelus/pkg/caelus/healthcheck/cgroupnotify" "github.com/tencent/caelus/pkg/caelus/healthcheck/conflict" "github.com/tencent/caelus/pkg/caelus/healthcheck/rulecheck" "github.com/tencent/caelus/pkg/caelus/qos" @@ -31,12 +29,21 @@ import ( "github.com/tencent/caelus/pkg/caelus/statestore" "github.com/tencent/caelus/pkg/caelus/types" "github.com/tencent/caelus/pkg/caelus/util" + caelusv1 "github.com/tencent/caelus/pkg/generated/informers/externalversions/caelus/v1" + "github.com/tencent/caelus/pkg/util/times" + + corev1 "k8s.io/api/core/v1" + labels2 "k8s.io/apimachinery/pkg/labels" + informerv1 "k8s.io/client-go/informers/core/v1" "k8s.io/client-go/tools/cache" - "k8s.io/klog/v2" + "k8s.io/client-go/util/workqueue" + "k8s.io/klog" ) const ( checkConfigFile = "/etc/caelus/rules.json" + ruleCheck = "RuleCheck" + cgroupNotify = "CgroupNotify" ) // Manager is the interface for handling health check @@ -50,41 +57,95 @@ type manager struct { config *types.HealthCheckConfig ruleChecker *rulecheck.Manager // support linux kernel PSI, now just memory event - cgroupNotifier notify.ResourceNotify - stStore statestore.StateStore - resource resource.Interface - qosManager qos.Manager - conflictMn conflict.Manager - podInformer cache.SharedIndexInformer - configUpdateFunc func(string) (*types.HealthCheckConfig, error) - configHash string - globalStopCh <-chan struct{} + cgroupNotifier notify.ResourceNotify + stStore statestore.StateStore + resource resource.Interface + qosManager qos.Manager + conflictMn conflict.Manager + podInformer cache.SharedIndexInformer + nodeInformer informerv1.NodeInformer + ruleCheckInformer caelusv1.RuleCheckInformer + cgroupInformer caelusv1.CgroupNotifyInformer + workqueue workqueue.RateLimitingInterface + globalStopCh <-chan struct{} + ruleCheckAvailableFunc func(ruleCheck *types.RuleCheckConfig) } // NewHealthManager create a new health check manager -func NewHealthManager(configFunc func(string) (*types.HealthCheckConfig, error), stStore statestore.StateStore, +func NewHealthManager(stStore statestore.StateStore, resource resource.Interface, qosManager qos.Manager, conflictMn conflict.Manager, - podInformer cache.SharedIndexInformer) Manager { - config, err := configFunc(checkConfigFile) + podInformer cache.SharedIndexInformer, nodeInformer informerv1.NodeInformer, + ruleCheckInformer caelusv1.RuleCheckInformer, cgroupInformer caelusv1.CgroupNotifyInformer, + resourceType *types.Resource, ruleCheckAvailableFunc func(ruleCheck *types.RuleCheckConfig)) Manager { + + config := &types.HealthCheckConfig{ + RuleCheck: types.RuleCheck{ + ContainerRules: []*types.RuleCheckConfig{}, + NodeRules: []*types.RuleCheckConfig{}, + AppRules: []*types.RuleCheckConfig{}, + }, + PredictReserved: resourceType, + } + + hm := &manager{ + config: config, + ruleChecker: rulecheck.NewManager(config.RuleCheck, stStore, resource, qosManager, conflictMn, podInformer, config.PredictReserved), + cgroupNotifier: notify.NewNotifyManager(&config.CgroupNotify, resource), + stStore: stStore, + resource: resource, + qosManager: qosManager, + conflictMn: conflictMn, + podInformer: podInformer, + nodeInformer: nodeInformer, + workqueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "health-check-queue"), + ruleCheckInformer: ruleCheckInformer, + cgroupInformer: cgroupInformer, + ruleCheckAvailableFunc: ruleCheckAvailableFunc, + } + + _, err := hm.ruleCheckInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) { + hm.eventFunc([]interface{}{obj}, ruleCheck) + }, + UpdateFunc: func(oldObj, newObj interface{}) { + hm.eventFunc([]interface{}{oldObj, newObj}, ruleCheck) + }, + DeleteFunc: func(obj interface{}) { + hm.eventFunc([]interface{}{obj}, ruleCheck) + }, + }) if err != nil { - klog.Fatalf("failed init health check config: %v", err) + klog.Error("Failed to add RuleCheck event func", err) + return nil } - hash, err := hashFile(checkConfigFile) + + _, err = hm.nodeInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + UpdateFunc: func(oldObj, newObj interface{}) { + if isLocalNodeEventAndLabelChanged(oldObj, newObj) { + hm.workqueue.Add(cgroupNotify) + hm.workqueue.Add(ruleCheck) + } + }, + }) if err != nil { - klog.Fatal(err) + klog.Error("Failed to add Node event func", err) + return nil } - hm := &manager{ - config: config, - configUpdateFunc: configFunc, - stStore: stStore, - resource: resource, - qosManager: qosManager, - conflictMn: conflictMn, - podInformer: podInformer, - ruleChecker: rulecheck.NewManager(config.RuleCheck, stStore, resource, qosManager, conflictMn, - podInformer, config.PredictReserved), - cgroupNotifier: notify.NewNotifyManager(&config.CgroupNotify, resource), - configHash: hash, + + _, err = hm.cgroupInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) { + hm.eventFunc([]interface{}{obj}, cgroupNotify) + }, + UpdateFunc: func(oldObj, newObj interface{}) { + hm.eventFunc([]interface{}{oldObj, newObj}, cgroupNotify) + }, + DeleteFunc: func(obj interface{}) { + hm.eventFunc([]interface{}{obj}, cgroupNotify) + }, + }) + if err != nil { + klog.Error("Failed to add CgroupNotify event func", err) + return nil } return hm @@ -95,102 +156,311 @@ func (h *manager) Name() string { return "ModuleHealthCheck" } -// reload rule check config dynamically without restarting the agent -func (h *manager) reload() { - reload, hash, config := h.checkNeedReload(checkConfigFile) - if !reload { - return +// filter the event affects local node and add cr type to the queue +func (h *manager) eventFunc(crs []interface{}, crd string) { + if h.isAffectingLocalNode(crs) { + h.workqueue.Add(crd) } - h.configHash = hash - h.ruleChecker.Stop() - h.cgroupNotifier.Stop() - h.config = config - h.ruleChecker = rulecheck.NewManager(config.RuleCheck, h.stStore, h.resource, h.qosManager, h.conflictMn, - h.podInformer, config.PredictReserved) - h.cgroupNotifier = notify.NewNotifyManager(&config.CgroupNotify, h.resource) - go h.ruleChecker.Run(h.globalStopCh) - go h.cgroupNotifier.Run(h.globalStopCh) } -// checkNeedReload checks if the config file is changed -func (h *manager) checkNeedReload(configFile string) (bool, string, *types.HealthCheckConfig) { - hash, err := hashFile(configFile) - if err != nil { - klog.Errorf("failed hash config file: %v", err) - return false, "", nil +// Run start checking health +func (h *manager) Run(stop <-chan struct{}) { + // the function is running in the informer evnet func + h.globalStopCh = stop + + // init the ruleCheck and cgroupNotify for new node + h.workqueue.Add(cgroupNotify) + h.workqueue.Add(ruleCheck) + + go h.runWorker() +} + +func (h *manager) runWorker() { + for h.processNextWorkItem() { } - if hash == h.configHash { - return false, "", nil +} + +func (h *manager) processNextWorkItem() bool { + select { + case <-h.globalStopCh: + h.workqueue.ShutDown() + return false + default: } - config, err := h.configUpdateFunc(configFile) - if err != nil { - klog.Fatalf("failed init health check config: %v", err) - } - if len(config.RuleNodes) != 0 { - found := false - for _, no := range config.RuleNodes { - if no == util.NodeIP() { - found = true - break - } + obj, shutdown := h.workqueue.Get() + + if shutdown { + return false + } + + key, ok := obj.(string) + if !ok { + h.workqueue.Forget(obj) + h.workqueue.Done(obj) + klog.Errorf("Health check queue item expects string but got %#v", obj) + return true + } + + if err := h.syncHandler(key); err != nil { + klog.Error("Health check module failed to handle ", key, err) + h.workqueue.Add(key) + } + + h.workqueue.Done(obj) + return true +} + +func (h *manager) syncHandler(key string) error { + klog.Infof("Start syncHandler %v", key) + if key == ruleCheck { + err := h.updateRuleCheckConfig() + if err != nil { + return err } - if !found { - return false, "", nil + h.reRunRuleCheck() + } else if key == cgroupNotify { + err := h.updateCgroupNotifyConfig() + if err != nil { + return err } + h.reRunCgroupNotifier() } - return true, hash, config + klog.Infof("After syncHandler %v: %v") + return nil } -// Run start checking health -func (h *manager) Run(stop <-chan struct{}) { - if h.config.Disable { - klog.Warningf("health check is disabled") - return +// reRunRuleCheck update and rerun the ruleChecker by the config +func (h *manager) reRunRuleCheck() { + if h.ruleChecker != nil { + h.ruleChecker.Stop() } - h.globalStopCh = stop - klog.V(2).Infof("health manager running") - go h.ruleChecker.Run(stop) - go h.cgroupNotifier.Run(stop) - go h.configWatcher(stop) + h.ruleChecker = rulecheck.NewManager(h.config.RuleCheck, h.stStore, h.resource, h.qosManager, h.conflictMn, h.podInformer, h.config.PredictReserved) + + if h.ruleChecker != nil { + go h.ruleChecker.Run(h.globalStopCh) + } +} + +// reRunCgroupNotifier update and rerun the cgroupNotifier by the config +func (h *manager) reRunCgroupNotifier() { + if h.cgroupNotifier != nil { + h.cgroupNotifier.Stop() + } + + h.cgroupNotifier = notify.NewNotifyManager(&h.config.CgroupNotify, h.resource) + + if h.cgroupNotifier != nil { + go h.cgroupNotifier.Run(h.globalStopCh) + } } -// configWatcher support reload rule check config dynamically, no need to restart the agent -func (h *manager) configWatcher(stop <-chan struct{}) { - w, err := fsnotify.NewWatcher() +func (h *manager) convertK8sCgroupNotify(k8sCgroupNotify *v1.CgroupNotify, cgroupNotify *types.NotifyConfig) { + pressures := make([]types.MemoryPressureNotifyConfig, 0) + for _, p := range k8sCgroupNotify.Spec.MemoryCgroup.Pressures { + newP := types.MemoryPressureNotifyConfig{} + newP.Cgroups = p.Cgroups + newP.Count = p.Count + newP.Duration = p.Duration * times.Duration(time.Millisecond) + newP.PressureLevel = p.PressureLevel + pressures = append(pressures, newP) + } + usages := make([]types.MemoryUsageNotifyConfig, 0) + for _, u := range k8sCgroupNotify.Spec.MemoryCgroup.Usages { + newU := types.MemoryUsageNotifyConfig{} + newU.Cgroups = u.Cgroups + newU.Duration = u.Duration * times.Duration(time.Millisecond) + newU.MarginMb = u.MarginMb + usages = append(usages, newU) + } + cgroupNotify.MemoryCgroup.Pressures = pressures + cgroupNotify.MemoryCgroup.Usages = usages +} + +func (h *manager) mergeCgroupNotify(baseCgNotify, nextCgNotify *types.NotifyConfig) { + if baseCgNotify.MemoryCgroup == nil { + baseCgNotify.MemoryCgroup = nextCgNotify.MemoryCgroup + } else { + if len(baseCgNotify.MemoryCgroup.Pressures) == 0 { + baseCgNotify.MemoryCgroup.Pressures = nextCgNotify.MemoryCgroup.Pressures + } + if len(baseCgNotify.MemoryCgroup.Usages) == 0 { + baseCgNotify.MemoryCgroup.Usages = nextCgNotify.MemoryCgroup.Usages + } + } +} + +func newMemoryNotifyConfig() *types.NotifyConfig { + memoryconfig := &types.MemoryNotifyConfig{ + Pressures: make([]types.MemoryPressureNotifyConfig, 0), + Usages: make([]types.MemoryUsageNotifyConfig, 0), + } + cgroupNotify := &types.NotifyConfig{ + MemoryCgroup: memoryconfig, + } + return cgroupNotify +} + +func (h *manager) updateCgroupNotifyConfig() error { + cgroupNotifiers, err := h.cgroupInformer.Lister().CgroupNotifies(corev1.NamespaceAll).List(labels2.Everything()) if err != nil { - klog.Fatalf("failed init fsnotify watcher: %v", err) + return err + } + sort.Slice(cgroupNotifiers, func(i, j int) bool { + if cgroupNotifiers[i].Spec.Priority == cgroupNotifiers[j].Spec.Priority { + return cgroupNotifiers[i].CreationTimestamp.After(cgroupNotifiers[j].CreationTimestamp.Time) + } else { + return cgroupNotifiers[i].Spec.Priority > cgroupNotifiers[j].Spec.Priority + } + }) + + baseCgroupNotify := newMemoryNotifyConfig() + for _, k8sCgroupNotify := range cgroupNotifiers { + if ok, err := h.isLabelMatchedLocalNode(k8sCgroupNotify.Spec.NodeSelector); err != nil || !ok { + continue + } + cgroupNotify := newMemoryNotifyConfig() + h.convertK8sCgroupNotify(k8sCgroupNotify, cgroupNotify) + h.mergeCgroupNotify(baseCgroupNotify, cgroupNotify) } - defer w.Close() - err = w.Add(filepath.Dir(checkConfigFile)) + h.config.CgroupNotify = *baseCgroupNotify + return nil +} + +// update local RuleCheck +func (h *manager) updateRuleCheckConfig() error { + ruleChecks, err := h.ruleCheckInformer.Lister().RuleChecks(corev1.NamespaceAll).List(labels2.Everything()) if err != nil { - klog.Fatalf("failed add dir watcher(%s): %v", filepath.Dir(checkConfigFile), err) - } - for { - select { - case <-w.Events: - h.reload() - case err := <-w.Errors: - klog.Errorf("fsnotify error: %v", err) - case <-stop: - return + return err + } + sort.Slice(ruleChecks, func(i, j int) bool { + if ruleChecks[i].Spec.Priority == ruleChecks[j].Spec.Priority { + return ruleChecks[i].CreationTimestamp.Time.After(ruleChecks[j].CreationTimestamp.Time) + } else { + return ruleChecks[i].Spec.Priority > ruleChecks[j].Spec.Priority + } + }) + + m := map[string]struct{}{} + appRuleChecks := []*types.RuleCheckConfig{} + nodeRuleChecks := []*types.RuleCheckConfig{} + containerRuleChecks := []*types.RuleCheckConfig{} + for _, k8sRuleCheck := range ruleChecks { + if ok, err := h.isLabelMatchedLocalNode(k8sRuleCheck.Spec.NodeSelector); err != nil || !ok { + continue + } + name := string(k8sRuleCheck.Spec.Type) + ":" + k8sRuleCheck.Spec.Name + if _, ok := m[name]; ok { + continue + } + m[name] = struct{}{} + ruleCheck := &types.RuleCheckConfig{} + h.convertK8sRuleCheck(k8sRuleCheck, ruleCheck) + switch k8sRuleCheck.Spec.Type { + case v1.AppType: + appRuleChecks = append(appRuleChecks, ruleCheck) + case v1.NodeType: + nodeRuleChecks = append(nodeRuleChecks, ruleCheck) + case v1.ContainerType: + containerRuleChecks = append(containerRuleChecks, ruleCheck) } } + h.config.RuleCheck.AppRules = appRuleChecks + h.config.RuleCheck.NodeRules = nodeRuleChecks + h.config.RuleCheck.ContainerRules = containerRuleChecks + return nil } -// hashFile generate hash code for the file -func hashFile(filePath string) (string, error) { - file, err := os.Open(filePath) +// convert v1.RuleCheck struct to types.RuleCheckConfig struct +func (h *manager) convertK8sRuleCheck(k8sRuleCheck *v1.RuleCheck, ruleCheck *types.RuleCheckConfig) { + convertRules := func(k8sRules []*v1.DetectActionRules) []*types.DetectActionConfig { + rules := make([]*types.DetectActionConfig, 0, len(k8sRuleCheck.Spec.Rules)) + for _, k8sRule := range k8sRules { + rule := &types.DetectActionConfig{ + Detects: make([]*types.DetectConfig, 0, len(k8sRule.Detects)), + Actions: make([]*types.ActionConfig, 0, len(k8sRule.Actions)), + } + for _, detect := range k8sRule.Detects { + rule.Detects = append(rule.Detects, &types.DetectConfig{ + Name: detect.Name, + ArgsStr: []byte(detect.Args), + Args: nil, + }) + } + for _, action := range k8sRule.Actions { + rule.Actions = append(rule.Actions, &types.ActionConfig{ + Name: action.Name, + ArgsStr: []byte(action.Args), + Args: nil, + }) + } + rules = append(rules, rule) + } + return rules + } + + ruleCheck.Rules = convertRules(k8sRuleCheck.Spec.Rules) + ruleCheck.RecoverRules = convertRules(k8sRuleCheck.Spec.RecoverRules) + + ruleCheck.Name = k8sRuleCheck.Name + ruleCheck.Metrics = k8sRuleCheck.Spec.Metrics + + ruleCheck.CheckInterval = *k8sRuleCheck.Spec.CheckInterval * times.Duration(time.Second) + ruleCheck.RecoverInterval = *k8sRuleCheck.Spec.RecoverInterval * times.Duration(time.Second) + ruleCheck.HandleInterval = *k8sRuleCheck.Spec.HandleInterval * times.Duration(time.Second) + ruleCheck.NodeSelector = k8sRuleCheck.Spec.NodeSelector + h.ruleCheckAvailableFunc(ruleCheck) +} + +// determine whether this cr event impacts this node +func (h *manager) isAffectingLocalNode(objs []interface{}) bool { + for _, obj := range objs { + if cgroupCr, ok := obj.(*v1.CgroupNotify); ok { + if matched, err := h.isLabelMatchedLocalNode(cgroupCr.Spec.NodeSelector); matched || err != nil { + return true + } + } else if ruleCheckCr, ok := obj.(*v1.RuleCheck); ok { + if matched, err := h.isLabelMatchedLocalNode(ruleCheckCr.Spec.NodeSelector); matched || err != nil { + return true + } + } + } + return false +} + +// isLabelMatched determines whether the labels match this node +func (h *manager) isLabelMatchedLocalNode(labels map[string]string) (bool, error) { + if len(labels) == 0 { + return true, nil + } + + node, err := h.nodeInformer.Lister().Get(util.NodeName()) if err != nil { - return "", err + return false, err } - defer file.Close() - hash := md5.New() - if _, err = io.Copy(hash, file); err != nil { - return "", err + for key, val := range labels { + if val != node.Labels[key] { + return false, nil + } } - h := hash.Sum(nil)[:16] - hs := hex.EncodeToString(h) - return hs, nil + return true, nil +} + +// determine whether this node event happened in local node and label changed +func isLocalNodeEventAndLabelChanged(oldObj, newObj interface{}) bool { + oldCr, ok := oldObj.(*corev1.Node) + if !ok { + return false + } + newCr, ok := newObj.(*corev1.Node) + if !ok { + return false + } + + if newCr.Name != util.NodeName() { + return false + } + + return !reflect.DeepEqual(oldCr.Labels, newCr.Labels) } diff --git a/pkg/caelus/healthcheck/health_check_test.go b/pkg/caelus/healthcheck/health_check_test.go deleted file mode 100644 index c53411dc..00000000 --- a/pkg/caelus/healthcheck/health_check_test.go +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2021 THL A29 Limited, a Tencent company. - * - * 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 health - -import ( - "io/ioutil" - "os" - "testing" - - "github.com/tencent/caelus/pkg/caelus/types" - "github.com/tencent/caelus/pkg/caelus/util" -) - -var ( - testNodeName = "testNode" - testHash = "9589f334c6f4987fc5ddb8e0ac1c096b" -) - -// TestNeedReload test if the rule config need to reload -func TestNeedReload(t *testing.T) { - configFile := "/tmp/testing" - err := ioutil.WriteFile(configFile, []byte("just testing"), 0644) - if err != nil { - t.Skipf("creating testing file %s err: %v", configFile, err) - } - defer os.Remove(configFile) - - healthManager := &manager{ - configHash: "123", - configUpdateFunc: func(string) (*types.HealthCheckConfig, error) { - return &types.HealthCheckConfig{ - Disable: false, - RuleNodes: []string{testNodeName}, - }, nil - }, - } - - util.SetNodeIP(testNodeName) - reload, hash, _ := healthManager.checkNeedReload(configFile) - if !reload || hash != testHash { - t.Fatalf("health check manager reload not expected, got reload:%v, hash:%s, expect reload:true, hash:%s", - reload, hash, testHash) - } -} diff --git a/pkg/caelus/healthcheck/rulecheck/rule_check.go b/pkg/caelus/healthcheck/rulecheck/rule_check.go index 38ee51c3..94fed44d 100644 --- a/pkg/caelus/healthcheck/rulecheck/rule_check.go +++ b/pkg/caelus/healthcheck/rulecheck/rule_check.go @@ -27,7 +27,7 @@ import ( "github.com/tencent/caelus/pkg/caelus/statestore" "github.com/tencent/caelus/pkg/caelus/types" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/client-go/tools/cache" "k8s.io/klog/v2" ) @@ -53,9 +53,15 @@ func NewManager(config types.RuleCheck, stStore statestore.StateStore, resource qosManager qos.Manager, conflictMn conflict.Manager, podInformer cache.SharedIndexInformer, predictReserved *types.Resource) *Manager { var checkers []ruleChecker - checkers = append(checkers, newContainerHealthChecker(stStore, podInformer, config.ContainerRules)) - checkers = append(checkers, newNodeHealthChecker(stStore, predictReserved, config.NodeRules)) - checkers = append(checkers, newAppHealthChecker(stStore, config.AppRules)) + if len(config.ContainerRules) > 0 { + checkers = append(checkers, newContainerHealthChecker(stStore, podInformer, config.ContainerRules)) + } + if len(config.NodeRules) > 0 { + checkers = append(checkers, newNodeHealthChecker(stStore, predictReserved, config.NodeRules)) + } + if len(config.AppRules) > 0 { + checkers = append(checkers, newAppHealthChecker(stStore, config.AppRules)) + } return &Manager{ // default global loop check interval diff --git a/pkg/caelus/types/health_check.go b/pkg/caelus/types/health_check.go index e889f9d0..82fba6bd 100644 --- a/pkg/caelus/types/health_check.go +++ b/pkg/caelus/types/health_check.go @@ -91,7 +91,6 @@ type EWMAArgs struct { // HealthCheckConfig is the config for checking health, such as node load or online job interference type HealthCheckConfig struct { Disable bool `json:"disable"` - RuleNodes []string `json:"rule_nodes"` RuleCheck RuleCheck `json:"rule_check"` CgroupNotify NotifyConfig `json:"cgroup_notify"` // assign the value when initialize @@ -107,8 +106,10 @@ type RuleCheck struct { // RuleCheckConfig define the rule config type RuleCheckConfig struct { - Name string `json:"name"` - Metrics []string `json:"metrics"` + Name string `json:"name"` + NodeSelector map[string]string `json:"node_selector"` + Metrics []string `json:"metrics"` + // CheckInterval describes the interval to trigger detection CheckInterval times.Duration `json:"check_interval"` // HandleInterval describes the interval to handle conflicts after detecting abnormal result @@ -198,6 +199,12 @@ func InitHealthCheckConfigFunc(nodeMetrics *MetricsNodeConfig, } } +func RuleCheckAvailableFunc(nodeMetrics *MetricsNodeConfig, predictReserve *Resource) func(ruleCheck *RuleCheckConfig) { + return func(ruleCheck *RuleCheckConfig) { + ruleCheckAvailable(ruleCheck, nodeMetrics, predictReserve) + } +} + func ruleCheckAvailable(ruleCheck *RuleCheckConfig, nodeMetrics *MetricsNodeConfig, predictReserve *Resource) { if ruleCheck == nil { return diff --git a/pkg/caelus/types/types.go b/pkg/caelus/types/types.go index 3cd4a89a..d0c0d4c0 100644 --- a/pkg/caelus/types/types.go +++ b/pkg/caelus/types/types.go @@ -31,7 +31,7 @@ import ( "github.com/tencent/caelus/pkg/caelus/util/cgroup" "github.com/tencent/caelus/pkg/util/times" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/klog/v2" ) @@ -40,6 +40,8 @@ import ( type MetricKind string const ( + // Namespace + CaelusNamespace = "caelus-system" // TaskType OnlineTypeOnK8s = "k8s" OnlineTypeOnLocal = "local" diff --git a/pkg/generated/clientset/versioned/clientset.go b/pkg/generated/clientset/versioned/clientset.go new file mode 100644 index 00000000..82ad164f --- /dev/null +++ b/pkg/generated/clientset/versioned/clientset.go @@ -0,0 +1,117 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package versioned + +import ( + "fmt" + "net/http" + + caelusv1 "github.com/tencent/caelus/pkg/generated/clientset/versioned/typed/caelus/v1" + discovery "k8s.io/client-go/discovery" + rest "k8s.io/client-go/rest" + flowcontrol "k8s.io/client-go/util/flowcontrol" +) + +type Interface interface { + Discovery() discovery.DiscoveryInterface + CaelusV1() caelusv1.CaelusV1Interface +} + +// Clientset contains the clients for groups. Each group has exactly one +// version included in a Clientset. +type Clientset struct { + *discovery.DiscoveryClient + caelusV1 *caelusv1.CaelusV1Client +} + +// CaelusV1 retrieves the CaelusV1Client +func (c *Clientset) CaelusV1() caelusv1.CaelusV1Interface { + return c.caelusV1 +} + +// Discovery retrieves the DiscoveryClient +func (c *Clientset) Discovery() discovery.DiscoveryInterface { + if c == nil { + return nil + } + return c.DiscoveryClient +} + +// NewForConfig creates a new Clientset for the given config. +// If config's RateLimiter is not set and QPS and Burst are acceptable, +// NewForConfig will generate a rate-limiter in configShallowCopy. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*Clientset, error) { + configShallowCopy := *c + + // share the transport between all clients + httpClient, err := rest.HTTPClientFor(&configShallowCopy) + if err != nil { + return nil, err + } + + return NewForConfigAndClient(&configShallowCopy, httpClient) +} + +// NewForConfigAndClient creates a new Clientset for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +// If config's RateLimiter is not set and QPS and Burst are acceptable, +// NewForConfigAndClient will generate a rate-limiter in configShallowCopy. +func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, error) { + configShallowCopy := *c + if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 { + if configShallowCopy.Burst <= 0 { + return nil, fmt.Errorf("burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0") + } + configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst) + } + + var cs Clientset + var err error + cs.caelusV1, err = caelusv1.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } + + cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } + return &cs, nil +} + +// NewForConfigOrDie creates a new Clientset for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *Clientset { + cs, err := NewForConfig(c) + if err != nil { + panic(err) + } + return cs +} + +// New creates a new Clientset for the given RESTClient. +func New(c rest.Interface) *Clientset { + var cs Clientset + cs.caelusV1 = caelusv1.New(c) + + cs.DiscoveryClient = discovery.NewDiscoveryClient(c) + return &cs +} diff --git a/pkg/generated/clientset/versioned/doc.go b/pkg/generated/clientset/versioned/doc.go new file mode 100644 index 00000000..41721ca5 --- /dev/null +++ b/pkg/generated/clientset/versioned/doc.go @@ -0,0 +1,20 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated clientset. +package versioned diff --git a/pkg/generated/clientset/versioned/fake/clientset_generated.go b/pkg/generated/clientset/versioned/fake/clientset_generated.go new file mode 100644 index 00000000..8467e949 --- /dev/null +++ b/pkg/generated/clientset/versioned/fake/clientset_generated.go @@ -0,0 +1,85 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + clientset "github.com/tencent/caelus/pkg/generated/clientset/versioned" + caelusv1 "github.com/tencent/caelus/pkg/generated/clientset/versioned/typed/caelus/v1" + fakecaelusv1 "github.com/tencent/caelus/pkg/generated/clientset/versioned/typed/caelus/v1/fake" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/watch" + "k8s.io/client-go/discovery" + fakediscovery "k8s.io/client-go/discovery/fake" + "k8s.io/client-go/testing" +) + +// NewSimpleClientset returns a clientset that will respond with the provided objects. +// It's backed by a very simple object tracker that processes creates, updates and deletions as-is, +// without applying any validations and/or defaults. It shouldn't be considered a replacement +// for a real clientset and is mostly useful in simple unit tests. +func NewSimpleClientset(objects ...runtime.Object) *Clientset { + o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder()) + for _, obj := range objects { + if err := o.Add(obj); err != nil { + panic(err) + } + } + + cs := &Clientset{tracker: o} + cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake} + cs.AddReactor("*", "*", testing.ObjectReaction(o)) + cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) { + gvr := action.GetResource() + ns := action.GetNamespace() + watch, err := o.Watch(gvr, ns) + if err != nil { + return false, nil, err + } + return true, watch, nil + }) + + return cs +} + +// Clientset implements clientset.Interface. Meant to be embedded into a +// struct to get a default implementation. This makes faking out just the method +// you want to test easier. +type Clientset struct { + testing.Fake + discovery *fakediscovery.FakeDiscovery + tracker testing.ObjectTracker +} + +func (c *Clientset) Discovery() discovery.DiscoveryInterface { + return c.discovery +} + +func (c *Clientset) Tracker() testing.ObjectTracker { + return c.tracker +} + +var ( + _ clientset.Interface = &Clientset{} + _ testing.FakeClient = &Clientset{} +) + +// CaelusV1 retrieves the CaelusV1Client +func (c *Clientset) CaelusV1() caelusv1.CaelusV1Interface { + return &fakecaelusv1.FakeCaelusV1{Fake: &c.Fake} +} diff --git a/pkg/generated/clientset/versioned/fake/doc.go b/pkg/generated/clientset/versioned/fake/doc.go new file mode 100644 index 00000000..9b99e716 --- /dev/null +++ b/pkg/generated/clientset/versioned/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated fake clientset. +package fake diff --git a/pkg/generated/clientset/versioned/fake/register.go b/pkg/generated/clientset/versioned/fake/register.go new file mode 100644 index 00000000..4aa0c1e7 --- /dev/null +++ b/pkg/generated/clientset/versioned/fake/register.go @@ -0,0 +1,56 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + caelusv1 "github.com/tencent/caelus/pkg/apis/caelus/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" + serializer "k8s.io/apimachinery/pkg/runtime/serializer" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" +) + +var scheme = runtime.NewScheme() +var codecs = serializer.NewCodecFactory(scheme) + +var localSchemeBuilder = runtime.SchemeBuilder{ + caelusv1.AddToScheme, +} + +// AddToScheme adds all types of this clientset into the given scheme. This allows composition +// of clientsets, like in: +// +// import ( +// "k8s.io/client-go/kubernetes" +// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" +// ) +// +// kclientset, _ := kubernetes.NewForConfig(c) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// +// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types +// correctly. +var AddToScheme = localSchemeBuilder.AddToScheme + +func init() { + v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"}) + utilruntime.Must(AddToScheme(scheme)) +} diff --git a/pkg/generated/clientset/versioned/scheme/doc.go b/pkg/generated/clientset/versioned/scheme/doc.go new file mode 100644 index 00000000..7dc37561 --- /dev/null +++ b/pkg/generated/clientset/versioned/scheme/doc.go @@ -0,0 +1,20 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package contains the scheme of the automatically generated clientset. +package scheme diff --git a/pkg/generated/clientset/versioned/scheme/register.go b/pkg/generated/clientset/versioned/scheme/register.go new file mode 100644 index 00000000..7b98c39d --- /dev/null +++ b/pkg/generated/clientset/versioned/scheme/register.go @@ -0,0 +1,56 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package scheme + +import ( + caelusv1 "github.com/tencent/caelus/pkg/apis/caelus/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" + serializer "k8s.io/apimachinery/pkg/runtime/serializer" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" +) + +var Scheme = runtime.NewScheme() +var Codecs = serializer.NewCodecFactory(Scheme) +var ParameterCodec = runtime.NewParameterCodec(Scheme) +var localSchemeBuilder = runtime.SchemeBuilder{ + caelusv1.AddToScheme, +} + +// AddToScheme adds all types of this clientset into the given scheme. This allows composition +// of clientsets, like in: +// +// import ( +// "k8s.io/client-go/kubernetes" +// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" +// ) +// +// kclientset, _ := kubernetes.NewForConfig(c) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// +// After this, RawExtensions in Kubernetes types will serialize kube-aggregator types +// correctly. +var AddToScheme = localSchemeBuilder.AddToScheme + +func init() { + v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) + utilruntime.Must(AddToScheme(Scheme)) +} diff --git a/pkg/generated/clientset/versioned/typed/caelus/v1/caelus_client.go b/pkg/generated/clientset/versioned/typed/caelus/v1/caelus_client.go new file mode 100644 index 00000000..0b7d000c --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/caelus/v1/caelus_client.go @@ -0,0 +1,112 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "net/http" + + v1 "github.com/tencent/caelus/pkg/apis/caelus/v1" + "github.com/tencent/caelus/pkg/generated/clientset/versioned/scheme" + rest "k8s.io/client-go/rest" +) + +type CaelusV1Interface interface { + RESTClient() rest.Interface + CgroupNotifiesGetter + RuleChecksGetter +} + +// CaelusV1Client is used to interact with features provided by the caelus group. +type CaelusV1Client struct { + restClient rest.Interface +} + +func (c *CaelusV1Client) CgroupNotifies(namespace string) CgroupNotifyInterface { + return newCgroupNotifies(c, namespace) +} + +func (c *CaelusV1Client) RuleChecks(namespace string) RuleCheckInterface { + return newRuleChecks(c, namespace) +} + +// NewForConfig creates a new CaelusV1Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*CaelusV1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new CaelusV1Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*CaelusV1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientForConfigAndClient(&config, h) + if err != nil { + return nil, err + } + return &CaelusV1Client{client}, nil +} + +// NewForConfigOrDie creates a new CaelusV1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *CaelusV1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new CaelusV1Client for the given RESTClient. +func New(c rest.Interface) *CaelusV1Client { + return &CaelusV1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *CaelusV1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/pkg/generated/clientset/versioned/typed/caelus/v1/cgroupnotify.go b/pkg/generated/clientset/versioned/typed/caelus/v1/cgroupnotify.go new file mode 100644 index 00000000..c40084ee --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/caelus/v1/cgroupnotify.go @@ -0,0 +1,195 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/tencent/caelus/pkg/apis/caelus/v1" + scheme "github.com/tencent/caelus/pkg/generated/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// CgroupNotifiesGetter has a method to return a CgroupNotifyInterface. +// A group's client should implement this interface. +type CgroupNotifiesGetter interface { + CgroupNotifies(namespace string) CgroupNotifyInterface +} + +// CgroupNotifyInterface has methods to work with CgroupNotify resources. +type CgroupNotifyInterface interface { + Create(ctx context.Context, cgroupNotify *v1.CgroupNotify, opts metav1.CreateOptions) (*v1.CgroupNotify, error) + Update(ctx context.Context, cgroupNotify *v1.CgroupNotify, opts metav1.UpdateOptions) (*v1.CgroupNotify, error) + UpdateStatus(ctx context.Context, cgroupNotify *v1.CgroupNotify, opts metav1.UpdateOptions) (*v1.CgroupNotify, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.CgroupNotify, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.CgroupNotifyList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CgroupNotify, err error) + CgroupNotifyExpansion +} + +// cgroupNotifies implements CgroupNotifyInterface +type cgroupNotifies struct { + client rest.Interface + ns string +} + +// newCgroupNotifies returns a CgroupNotifies +func newCgroupNotifies(c *CaelusV1Client, namespace string) *cgroupNotifies { + return &cgroupNotifies{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the cgroupNotify, and returns the corresponding cgroupNotify object, and an error if there is any. +func (c *cgroupNotifies) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.CgroupNotify, err error) { + result = &v1.CgroupNotify{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cgroupnotifies"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of CgroupNotifies that match those selectors. +func (c *cgroupNotifies) List(ctx context.Context, opts metav1.ListOptions) (result *v1.CgroupNotifyList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.CgroupNotifyList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("cgroupnotifies"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested cgroupNotifies. +func (c *cgroupNotifies) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("cgroupnotifies"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a cgroupNotify and creates it. Returns the server's representation of the cgroupNotify, and an error, if there is any. +func (c *cgroupNotifies) Create(ctx context.Context, cgroupNotify *v1.CgroupNotify, opts metav1.CreateOptions) (result *v1.CgroupNotify, err error) { + result = &v1.CgroupNotify{} + err = c.client.Post(). + Namespace(c.ns). + Resource("cgroupnotifies"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cgroupNotify). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a cgroupNotify and updates it. Returns the server's representation of the cgroupNotify, and an error, if there is any. +func (c *cgroupNotifies) Update(ctx context.Context, cgroupNotify *v1.CgroupNotify, opts metav1.UpdateOptions) (result *v1.CgroupNotify, err error) { + result = &v1.CgroupNotify{} + err = c.client.Put(). + Namespace(c.ns). + Resource("cgroupnotifies"). + Name(cgroupNotify.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cgroupNotify). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *cgroupNotifies) UpdateStatus(ctx context.Context, cgroupNotify *v1.CgroupNotify, opts metav1.UpdateOptions) (result *v1.CgroupNotify, err error) { + result = &v1.CgroupNotify{} + err = c.client.Put(). + Namespace(c.ns). + Resource("cgroupnotifies"). + Name(cgroupNotify.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(cgroupNotify). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the cgroupNotify and deletes it. Returns an error if one occurs. +func (c *cgroupNotifies) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("cgroupnotifies"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *cgroupNotifies) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("cgroupnotifies"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched cgroupNotify. +func (c *cgroupNotifies) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.CgroupNotify, err error) { + result = &v1.CgroupNotify{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("cgroupnotifies"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/generated/clientset/versioned/typed/caelus/v1/doc.go b/pkg/generated/clientset/versioned/typed/caelus/v1/doc.go new file mode 100644 index 00000000..3af5d054 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/caelus/v1/doc.go @@ -0,0 +1,20 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1 diff --git a/pkg/generated/clientset/versioned/typed/caelus/v1/fake/doc.go b/pkg/generated/clientset/versioned/typed/caelus/v1/fake/doc.go new file mode 100644 index 00000000..16f44399 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/caelus/v1/fake/doc.go @@ -0,0 +1,20 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/pkg/generated/clientset/versioned/typed/caelus/v1/fake/fake_caelus_client.go b/pkg/generated/clientset/versioned/typed/caelus/v1/fake/fake_caelus_client.go new file mode 100644 index 00000000..b3a2a5f5 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/caelus/v1/fake/fake_caelus_client.go @@ -0,0 +1,44 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1 "github.com/tencent/caelus/pkg/generated/clientset/versioned/typed/caelus/v1" + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" +) + +type FakeCaelusV1 struct { + *testing.Fake +} + +func (c *FakeCaelusV1) CgroupNotifies(namespace string) v1.CgroupNotifyInterface { + return &FakeCgroupNotifies{c, namespace} +} + +func (c *FakeCaelusV1) RuleChecks(namespace string) v1.RuleCheckInterface { + return &FakeRuleChecks{c, namespace} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeCaelusV1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/pkg/generated/clientset/versioned/typed/caelus/v1/fake/fake_cgroupnotify.go b/pkg/generated/clientset/versioned/typed/caelus/v1/fake/fake_cgroupnotify.go new file mode 100644 index 00000000..572b051a --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/caelus/v1/fake/fake_cgroupnotify.go @@ -0,0 +1,142 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + caelusv1 "github.com/tencent/caelus/pkg/apis/caelus/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeCgroupNotifies implements CgroupNotifyInterface +type FakeCgroupNotifies struct { + Fake *FakeCaelusV1 + ns string +} + +var cgroupnotifiesResource = schema.GroupVersionResource{Group: "caelus", Version: "v1", Resource: "cgroupnotifies"} + +var cgroupnotifiesKind = schema.GroupVersionKind{Group: "caelus", Version: "v1", Kind: "CgroupNotify"} + +// Get takes name of the cgroupNotify, and returns the corresponding cgroupNotify object, and an error if there is any. +func (c *FakeCgroupNotifies) Get(ctx context.Context, name string, options v1.GetOptions) (result *caelusv1.CgroupNotify, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(cgroupnotifiesResource, c.ns, name), &caelusv1.CgroupNotify{}) + + if obj == nil { + return nil, err + } + return obj.(*caelusv1.CgroupNotify), err +} + +// List takes label and field selectors, and returns the list of CgroupNotifies that match those selectors. +func (c *FakeCgroupNotifies) List(ctx context.Context, opts v1.ListOptions) (result *caelusv1.CgroupNotifyList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(cgroupnotifiesResource, cgroupnotifiesKind, c.ns, opts), &caelusv1.CgroupNotifyList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &caelusv1.CgroupNotifyList{ListMeta: obj.(*caelusv1.CgroupNotifyList).ListMeta} + for _, item := range obj.(*caelusv1.CgroupNotifyList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested cgroupNotifies. +func (c *FakeCgroupNotifies) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(cgroupnotifiesResource, c.ns, opts)) + +} + +// Create takes the representation of a cgroupNotify and creates it. Returns the server's representation of the cgroupNotify, and an error, if there is any. +func (c *FakeCgroupNotifies) Create(ctx context.Context, cgroupNotify *caelusv1.CgroupNotify, opts v1.CreateOptions) (result *caelusv1.CgroupNotify, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(cgroupnotifiesResource, c.ns, cgroupNotify), &caelusv1.CgroupNotify{}) + + if obj == nil { + return nil, err + } + return obj.(*caelusv1.CgroupNotify), err +} + +// Update takes the representation of a cgroupNotify and updates it. Returns the server's representation of the cgroupNotify, and an error, if there is any. +func (c *FakeCgroupNotifies) Update(ctx context.Context, cgroupNotify *caelusv1.CgroupNotify, opts v1.UpdateOptions) (result *caelusv1.CgroupNotify, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(cgroupnotifiesResource, c.ns, cgroupNotify), &caelusv1.CgroupNotify{}) + + if obj == nil { + return nil, err + } + return obj.(*caelusv1.CgroupNotify), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeCgroupNotifies) UpdateStatus(ctx context.Context, cgroupNotify *caelusv1.CgroupNotify, opts v1.UpdateOptions) (*caelusv1.CgroupNotify, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(cgroupnotifiesResource, "status", c.ns, cgroupNotify), &caelusv1.CgroupNotify{}) + + if obj == nil { + return nil, err + } + return obj.(*caelusv1.CgroupNotify), err +} + +// Delete takes name of the cgroupNotify and deletes it. Returns an error if one occurs. +func (c *FakeCgroupNotifies) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(cgroupnotifiesResource, c.ns, name, opts), &caelusv1.CgroupNotify{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeCgroupNotifies) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(cgroupnotifiesResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &caelusv1.CgroupNotifyList{}) + return err +} + +// Patch applies the patch and returns the patched cgroupNotify. +func (c *FakeCgroupNotifies) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *caelusv1.CgroupNotify, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(cgroupnotifiesResource, c.ns, name, pt, data, subresources...), &caelusv1.CgroupNotify{}) + + if obj == nil { + return nil, err + } + return obj.(*caelusv1.CgroupNotify), err +} diff --git a/pkg/generated/clientset/versioned/typed/caelus/v1/fake/fake_rulecheck.go b/pkg/generated/clientset/versioned/typed/caelus/v1/fake/fake_rulecheck.go new file mode 100644 index 00000000..9cff02f5 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/caelus/v1/fake/fake_rulecheck.go @@ -0,0 +1,142 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + caelusv1 "github.com/tencent/caelus/pkg/apis/caelus/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeRuleChecks implements RuleCheckInterface +type FakeRuleChecks struct { + Fake *FakeCaelusV1 + ns string +} + +var rulechecksResource = schema.GroupVersionResource{Group: "caelus", Version: "v1", Resource: "rulechecks"} + +var rulechecksKind = schema.GroupVersionKind{Group: "caelus", Version: "v1", Kind: "RuleCheck"} + +// Get takes name of the ruleCheck, and returns the corresponding ruleCheck object, and an error if there is any. +func (c *FakeRuleChecks) Get(ctx context.Context, name string, options v1.GetOptions) (result *caelusv1.RuleCheck, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(rulechecksResource, c.ns, name), &caelusv1.RuleCheck{}) + + if obj == nil { + return nil, err + } + return obj.(*caelusv1.RuleCheck), err +} + +// List takes label and field selectors, and returns the list of RuleChecks that match those selectors. +func (c *FakeRuleChecks) List(ctx context.Context, opts v1.ListOptions) (result *caelusv1.RuleCheckList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(rulechecksResource, rulechecksKind, c.ns, opts), &caelusv1.RuleCheckList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &caelusv1.RuleCheckList{ListMeta: obj.(*caelusv1.RuleCheckList).ListMeta} + for _, item := range obj.(*caelusv1.RuleCheckList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested ruleChecks. +func (c *FakeRuleChecks) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(rulechecksResource, c.ns, opts)) + +} + +// Create takes the representation of a ruleCheck and creates it. Returns the server's representation of the ruleCheck, and an error, if there is any. +func (c *FakeRuleChecks) Create(ctx context.Context, ruleCheck *caelusv1.RuleCheck, opts v1.CreateOptions) (result *caelusv1.RuleCheck, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(rulechecksResource, c.ns, ruleCheck), &caelusv1.RuleCheck{}) + + if obj == nil { + return nil, err + } + return obj.(*caelusv1.RuleCheck), err +} + +// Update takes the representation of a ruleCheck and updates it. Returns the server's representation of the ruleCheck, and an error, if there is any. +func (c *FakeRuleChecks) Update(ctx context.Context, ruleCheck *caelusv1.RuleCheck, opts v1.UpdateOptions) (result *caelusv1.RuleCheck, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(rulechecksResource, c.ns, ruleCheck), &caelusv1.RuleCheck{}) + + if obj == nil { + return nil, err + } + return obj.(*caelusv1.RuleCheck), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeRuleChecks) UpdateStatus(ctx context.Context, ruleCheck *caelusv1.RuleCheck, opts v1.UpdateOptions) (*caelusv1.RuleCheck, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(rulechecksResource, "status", c.ns, ruleCheck), &caelusv1.RuleCheck{}) + + if obj == nil { + return nil, err + } + return obj.(*caelusv1.RuleCheck), err +} + +// Delete takes name of the ruleCheck and deletes it. Returns an error if one occurs. +func (c *FakeRuleChecks) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(rulechecksResource, c.ns, name, opts), &caelusv1.RuleCheck{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeRuleChecks) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(rulechecksResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &caelusv1.RuleCheckList{}) + return err +} + +// Patch applies the patch and returns the patched ruleCheck. +func (c *FakeRuleChecks) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *caelusv1.RuleCheck, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(rulechecksResource, c.ns, name, pt, data, subresources...), &caelusv1.RuleCheck{}) + + if obj == nil { + return nil, err + } + return obj.(*caelusv1.RuleCheck), err +} diff --git a/pkg/generated/clientset/versioned/typed/caelus/v1/generated_expansion.go b/pkg/generated/clientset/versioned/typed/caelus/v1/generated_expansion.go new file mode 100644 index 00000000..8736e9d5 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/caelus/v1/generated_expansion.go @@ -0,0 +1,23 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +type CgroupNotifyExpansion interface{} + +type RuleCheckExpansion interface{} diff --git a/pkg/generated/clientset/versioned/typed/caelus/v1/rulecheck.go b/pkg/generated/clientset/versioned/typed/caelus/v1/rulecheck.go new file mode 100644 index 00000000..d5b3f785 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/caelus/v1/rulecheck.go @@ -0,0 +1,195 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + "time" + + v1 "github.com/tencent/caelus/pkg/apis/caelus/v1" + scheme "github.com/tencent/caelus/pkg/generated/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// RuleChecksGetter has a method to return a RuleCheckInterface. +// A group's client should implement this interface. +type RuleChecksGetter interface { + RuleChecks(namespace string) RuleCheckInterface +} + +// RuleCheckInterface has methods to work with RuleCheck resources. +type RuleCheckInterface interface { + Create(ctx context.Context, ruleCheck *v1.RuleCheck, opts metav1.CreateOptions) (*v1.RuleCheck, error) + Update(ctx context.Context, ruleCheck *v1.RuleCheck, opts metav1.UpdateOptions) (*v1.RuleCheck, error) + UpdateStatus(ctx context.Context, ruleCheck *v1.RuleCheck, opts metav1.UpdateOptions) (*v1.RuleCheck, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.RuleCheck, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.RuleCheckList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.RuleCheck, err error) + RuleCheckExpansion +} + +// ruleChecks implements RuleCheckInterface +type ruleChecks struct { + client rest.Interface + ns string +} + +// newRuleChecks returns a RuleChecks +func newRuleChecks(c *CaelusV1Client, namespace string) *ruleChecks { + return &ruleChecks{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the ruleCheck, and returns the corresponding ruleCheck object, and an error if there is any. +func (c *ruleChecks) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.RuleCheck, err error) { + result = &v1.RuleCheck{} + err = c.client.Get(). + Namespace(c.ns). + Resource("rulechecks"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of RuleChecks that match those selectors. +func (c *ruleChecks) List(ctx context.Context, opts metav1.ListOptions) (result *v1.RuleCheckList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.RuleCheckList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("rulechecks"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested ruleChecks. +func (c *ruleChecks) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("rulechecks"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a ruleCheck and creates it. Returns the server's representation of the ruleCheck, and an error, if there is any. +func (c *ruleChecks) Create(ctx context.Context, ruleCheck *v1.RuleCheck, opts metav1.CreateOptions) (result *v1.RuleCheck, err error) { + result = &v1.RuleCheck{} + err = c.client.Post(). + Namespace(c.ns). + Resource("rulechecks"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(ruleCheck). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a ruleCheck and updates it. Returns the server's representation of the ruleCheck, and an error, if there is any. +func (c *ruleChecks) Update(ctx context.Context, ruleCheck *v1.RuleCheck, opts metav1.UpdateOptions) (result *v1.RuleCheck, err error) { + result = &v1.RuleCheck{} + err = c.client.Put(). + Namespace(c.ns). + Resource("rulechecks"). + Name(ruleCheck.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(ruleCheck). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *ruleChecks) UpdateStatus(ctx context.Context, ruleCheck *v1.RuleCheck, opts metav1.UpdateOptions) (result *v1.RuleCheck, err error) { + result = &v1.RuleCheck{} + err = c.client.Put(). + Namespace(c.ns). + Resource("rulechecks"). + Name(ruleCheck.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(ruleCheck). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the ruleCheck and deletes it. Returns an error if one occurs. +func (c *ruleChecks) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("rulechecks"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *ruleChecks) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("rulechecks"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched ruleCheck. +func (c *ruleChecks) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.RuleCheck, err error) { + result = &v1.RuleCheck{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("rulechecks"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/generated/informers/externalversions/caelus/interface.go b/pkg/generated/informers/externalversions/caelus/interface.go new file mode 100644 index 00000000..a19e58f5 --- /dev/null +++ b/pkg/generated/informers/externalversions/caelus/interface.go @@ -0,0 +1,46 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package caelus + +import ( + v1 "github.com/tencent/caelus/pkg/generated/informers/externalversions/caelus/v1" + internalinterfaces "github.com/tencent/caelus/pkg/generated/informers/externalversions/internalinterfaces" +) + +// Interface provides access to each of this group's versions. +type Interface interface { + // V1 provides access to shared informers for resources in V1. + V1() v1.Interface +} + +type group struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// V1 returns a new v1.Interface. +func (g *group) V1() v1.Interface { + return v1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/pkg/generated/informers/externalversions/caelus/v1/cgroupnotify.go b/pkg/generated/informers/externalversions/caelus/v1/cgroupnotify.go new file mode 100644 index 00000000..1d48b431 --- /dev/null +++ b/pkg/generated/informers/externalversions/caelus/v1/cgroupnotify.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + caelusv1 "github.com/tencent/caelus/pkg/apis/caelus/v1" + versioned "github.com/tencent/caelus/pkg/generated/clientset/versioned" + internalinterfaces "github.com/tencent/caelus/pkg/generated/informers/externalversions/internalinterfaces" + v1 "github.com/tencent/caelus/pkg/generated/listers/caelus/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// CgroupNotifyInformer provides access to a shared informer and lister for +// CgroupNotifies. +type CgroupNotifyInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.CgroupNotifyLister +} + +type cgroupNotifyInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewCgroupNotifyInformer constructs a new informer for CgroupNotify type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewCgroupNotifyInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredCgroupNotifyInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredCgroupNotifyInformer constructs a new informer for CgroupNotify type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredCgroupNotifyInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CaelusV1().CgroupNotifies(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CaelusV1().CgroupNotifies(namespace).Watch(context.TODO(), options) + }, + }, + &caelusv1.CgroupNotify{}, + resyncPeriod, + indexers, + ) +} + +func (f *cgroupNotifyInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredCgroupNotifyInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *cgroupNotifyInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&caelusv1.CgroupNotify{}, f.defaultInformer) +} + +func (f *cgroupNotifyInformer) Lister() v1.CgroupNotifyLister { + return v1.NewCgroupNotifyLister(f.Informer().GetIndexer()) +} diff --git a/pkg/generated/informers/externalversions/caelus/v1/interface.go b/pkg/generated/informers/externalversions/caelus/v1/interface.go new file mode 100644 index 00000000..83c91454 --- /dev/null +++ b/pkg/generated/informers/externalversions/caelus/v1/interface.go @@ -0,0 +1,52 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + internalinterfaces "github.com/tencent/caelus/pkg/generated/informers/externalversions/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // CgroupNotifies returns a CgroupNotifyInformer. + CgroupNotifies() CgroupNotifyInformer + // RuleChecks returns a RuleCheckInformer. + RuleChecks() RuleCheckInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// CgroupNotifies returns a CgroupNotifyInformer. +func (v *version) CgroupNotifies() CgroupNotifyInformer { + return &cgroupNotifyInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// RuleChecks returns a RuleCheckInformer. +func (v *version) RuleChecks() RuleCheckInformer { + return &ruleCheckInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/pkg/generated/informers/externalversions/caelus/v1/rulecheck.go b/pkg/generated/informers/externalversions/caelus/v1/rulecheck.go new file mode 100644 index 00000000..32e85f5d --- /dev/null +++ b/pkg/generated/informers/externalversions/caelus/v1/rulecheck.go @@ -0,0 +1,90 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + caelusv1 "github.com/tencent/caelus/pkg/apis/caelus/v1" + versioned "github.com/tencent/caelus/pkg/generated/clientset/versioned" + internalinterfaces "github.com/tencent/caelus/pkg/generated/informers/externalversions/internalinterfaces" + v1 "github.com/tencent/caelus/pkg/generated/listers/caelus/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// RuleCheckInformer provides access to a shared informer and lister for +// RuleChecks. +type RuleCheckInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.RuleCheckLister +} + +type ruleCheckInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewRuleCheckInformer constructs a new informer for RuleCheck type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewRuleCheckInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredRuleCheckInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredRuleCheckInformer constructs a new informer for RuleCheck type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredRuleCheckInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CaelusV1().RuleChecks(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CaelusV1().RuleChecks(namespace).Watch(context.TODO(), options) + }, + }, + &caelusv1.RuleCheck{}, + resyncPeriod, + indexers, + ) +} + +func (f *ruleCheckInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredRuleCheckInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *ruleCheckInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&caelusv1.RuleCheck{}, f.defaultInformer) +} + +func (f *ruleCheckInformer) Lister() v1.RuleCheckLister { + return v1.NewRuleCheckLister(f.Informer().GetIndexer()) +} diff --git a/pkg/generated/informers/externalversions/factory.go b/pkg/generated/informers/externalversions/factory.go new file mode 100644 index 00000000..abbc9085 --- /dev/null +++ b/pkg/generated/informers/externalversions/factory.go @@ -0,0 +1,180 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package externalversions + +import ( + reflect "reflect" + sync "sync" + time "time" + + versioned "github.com/tencent/caelus/pkg/generated/clientset/versioned" + caelus "github.com/tencent/caelus/pkg/generated/informers/externalversions/caelus" + internalinterfaces "github.com/tencent/caelus/pkg/generated/informers/externalversions/internalinterfaces" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + schema "k8s.io/apimachinery/pkg/runtime/schema" + cache "k8s.io/client-go/tools/cache" +) + +// SharedInformerOption defines the functional option type for SharedInformerFactory. +type SharedInformerOption func(*sharedInformerFactory) *sharedInformerFactory + +type sharedInformerFactory struct { + client versioned.Interface + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc + lock sync.Mutex + defaultResync time.Duration + customResync map[reflect.Type]time.Duration + + informers map[reflect.Type]cache.SharedIndexInformer + // startedInformers is used for tracking which informers have been started. + // This allows Start() to be called multiple times safely. + startedInformers map[reflect.Type]bool +} + +// WithCustomResyncConfig sets a custom resync period for the specified informer types. +func WithCustomResyncConfig(resyncConfig map[v1.Object]time.Duration) SharedInformerOption { + return func(factory *sharedInformerFactory) *sharedInformerFactory { + for k, v := range resyncConfig { + factory.customResync[reflect.TypeOf(k)] = v + } + return factory + } +} + +// WithTweakListOptions sets a custom filter on all listers of the configured SharedInformerFactory. +func WithTweakListOptions(tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerOption { + return func(factory *sharedInformerFactory) *sharedInformerFactory { + factory.tweakListOptions = tweakListOptions + return factory + } +} + +// WithNamespace limits the SharedInformerFactory to the specified namespace. +func WithNamespace(namespace string) SharedInformerOption { + return func(factory *sharedInformerFactory) *sharedInformerFactory { + factory.namespace = namespace + return factory + } +} + +// NewSharedInformerFactory constructs a new instance of sharedInformerFactory for all namespaces. +func NewSharedInformerFactory(client versioned.Interface, defaultResync time.Duration) SharedInformerFactory { + return NewSharedInformerFactoryWithOptions(client, defaultResync) +} + +// NewFilteredSharedInformerFactory constructs a new instance of sharedInformerFactory. +// Listers obtained via this SharedInformerFactory will be subject to the same filters +// as specified here. +// Deprecated: Please use NewSharedInformerFactoryWithOptions instead +func NewFilteredSharedInformerFactory(client versioned.Interface, defaultResync time.Duration, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) SharedInformerFactory { + return NewSharedInformerFactoryWithOptions(client, defaultResync, WithNamespace(namespace), WithTweakListOptions(tweakListOptions)) +} + +// NewSharedInformerFactoryWithOptions constructs a new instance of a SharedInformerFactory with additional options. +func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResync time.Duration, options ...SharedInformerOption) SharedInformerFactory { + factory := &sharedInformerFactory{ + client: client, + namespace: v1.NamespaceAll, + defaultResync: defaultResync, + informers: make(map[reflect.Type]cache.SharedIndexInformer), + startedInformers: make(map[reflect.Type]bool), + customResync: make(map[reflect.Type]time.Duration), + } + + // Apply all options + for _, opt := range options { + factory = opt(factory) + } + + return factory +} + +// Start initializes all requested informers. +func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { + f.lock.Lock() + defer f.lock.Unlock() + + for informerType, informer := range f.informers { + if !f.startedInformers[informerType] { + go informer.Run(stopCh) + f.startedInformers[informerType] = true + } + } +} + +// WaitForCacheSync waits for all started informers' cache were synced. +func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool { + informers := func() map[reflect.Type]cache.SharedIndexInformer { + f.lock.Lock() + defer f.lock.Unlock() + + informers := map[reflect.Type]cache.SharedIndexInformer{} + for informerType, informer := range f.informers { + if f.startedInformers[informerType] { + informers[informerType] = informer + } + } + return informers + }() + + res := map[reflect.Type]bool{} + for informType, informer := range informers { + res[informType] = cache.WaitForCacheSync(stopCh, informer.HasSynced) + } + return res +} + +// InternalInformerFor returns the SharedIndexInformer for obj using an internal +// client. +func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer { + f.lock.Lock() + defer f.lock.Unlock() + + informerType := reflect.TypeOf(obj) + informer, exists := f.informers[informerType] + if exists { + return informer + } + + resyncPeriod, exists := f.customResync[informerType] + if !exists { + resyncPeriod = f.defaultResync + } + + informer = newFunc(f.client, resyncPeriod) + f.informers[informerType] = informer + + return informer +} + +// SharedInformerFactory provides shared informers for resources in all known +// API group versions. +type SharedInformerFactory interface { + internalinterfaces.SharedInformerFactory + ForResource(resource schema.GroupVersionResource) (GenericInformer, error) + WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool + + Caelus() caelus.Interface +} + +func (f *sharedInformerFactory) Caelus() caelus.Interface { + return caelus.New(f, f.namespace, f.tweakListOptions) +} diff --git a/pkg/generated/informers/externalversions/generic.go b/pkg/generated/informers/externalversions/generic.go new file mode 100644 index 00000000..4fc257f9 --- /dev/null +++ b/pkg/generated/informers/externalversions/generic.go @@ -0,0 +1,64 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package externalversions + +import ( + "fmt" + + v1 "github.com/tencent/caelus/pkg/apis/caelus/v1" + schema "k8s.io/apimachinery/pkg/runtime/schema" + cache "k8s.io/client-go/tools/cache" +) + +// GenericInformer is type of SharedIndexInformer which will locate and delegate to other +// sharedInformers based on type +type GenericInformer interface { + Informer() cache.SharedIndexInformer + Lister() cache.GenericLister +} + +type genericInformer struct { + informer cache.SharedIndexInformer + resource schema.GroupResource +} + +// Informer returns the SharedIndexInformer. +func (f *genericInformer) Informer() cache.SharedIndexInformer { + return f.informer +} + +// Lister returns the GenericLister. +func (f *genericInformer) Lister() cache.GenericLister { + return cache.NewGenericLister(f.Informer().GetIndexer(), f.resource) +} + +// ForResource gives generic access to a shared informer of the matching type +// TODO extend this to unknown resources with a client pool +func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { + switch resource { + // Group=caelus, Version=v1 + case v1.SchemeGroupVersion.WithResource("cgroupnotifies"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Caelus().V1().CgroupNotifies().Informer()}, nil + case v1.SchemeGroupVersion.WithResource("rulechecks"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Caelus().V1().RuleChecks().Informer()}, nil + + } + + return nil, fmt.Errorf("no informer found for %v", resource) +} diff --git a/pkg/generated/informers/externalversions/internalinterfaces/factory_interfaces.go b/pkg/generated/informers/externalversions/internalinterfaces/factory_interfaces.go new file mode 100644 index 00000000..5060968a --- /dev/null +++ b/pkg/generated/informers/externalversions/internalinterfaces/factory_interfaces.go @@ -0,0 +1,40 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package internalinterfaces + +import ( + time "time" + + versioned "github.com/tencent/caelus/pkg/generated/clientset/versioned" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + cache "k8s.io/client-go/tools/cache" +) + +// NewInformerFunc takes versioned.Interface and time.Duration to return a SharedIndexInformer. +type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexInformer + +// SharedInformerFactory a small interface to allow for adding an informer without an import cycle +type SharedInformerFactory interface { + Start(stopCh <-chan struct{}) + InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer +} + +// TweakListOptionsFunc is a function that transforms a v1.ListOptions. +type TweakListOptionsFunc func(*v1.ListOptions) diff --git a/pkg/generated/listers/caelus/v1/cgroupnotify.go b/pkg/generated/listers/caelus/v1/cgroupnotify.go new file mode 100644 index 00000000..decf1337 --- /dev/null +++ b/pkg/generated/listers/caelus/v1/cgroupnotify.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "github.com/tencent/caelus/pkg/apis/caelus/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// CgroupNotifyLister helps list CgroupNotifies. +// All objects returned here must be treated as read-only. +type CgroupNotifyLister interface { + // List lists all CgroupNotifies in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.CgroupNotify, err error) + // CgroupNotifies returns an object that can list and get CgroupNotifies. + CgroupNotifies(namespace string) CgroupNotifyNamespaceLister + CgroupNotifyListerExpansion +} + +// cgroupNotifyLister implements the CgroupNotifyLister interface. +type cgroupNotifyLister struct { + indexer cache.Indexer +} + +// NewCgroupNotifyLister returns a new CgroupNotifyLister. +func NewCgroupNotifyLister(indexer cache.Indexer) CgroupNotifyLister { + return &cgroupNotifyLister{indexer: indexer} +} + +// List lists all CgroupNotifies in the indexer. +func (s *cgroupNotifyLister) List(selector labels.Selector) (ret []*v1.CgroupNotify, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.CgroupNotify)) + }) + return ret, err +} + +// CgroupNotifies returns an object that can list and get CgroupNotifies. +func (s *cgroupNotifyLister) CgroupNotifies(namespace string) CgroupNotifyNamespaceLister { + return cgroupNotifyNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// CgroupNotifyNamespaceLister helps list and get CgroupNotifies. +// All objects returned here must be treated as read-only. +type CgroupNotifyNamespaceLister interface { + // List lists all CgroupNotifies in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.CgroupNotify, err error) + // Get retrieves the CgroupNotify from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.CgroupNotify, error) + CgroupNotifyNamespaceListerExpansion +} + +// cgroupNotifyNamespaceLister implements the CgroupNotifyNamespaceLister +// interface. +type cgroupNotifyNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all CgroupNotifies in the indexer for a given namespace. +func (s cgroupNotifyNamespaceLister) List(selector labels.Selector) (ret []*v1.CgroupNotify, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.CgroupNotify)) + }) + return ret, err +} + +// Get retrieves the CgroupNotify from the indexer for a given namespace and name. +func (s cgroupNotifyNamespaceLister) Get(name string) (*v1.CgroupNotify, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("cgroupnotify"), name) + } + return obj.(*v1.CgroupNotify), nil +} diff --git a/pkg/generated/listers/caelus/v1/expansion_generated.go b/pkg/generated/listers/caelus/v1/expansion_generated.go new file mode 100644 index 00000000..bfca4459 --- /dev/null +++ b/pkg/generated/listers/caelus/v1/expansion_generated.go @@ -0,0 +1,35 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +// CgroupNotifyListerExpansion allows custom methods to be added to +// CgroupNotifyLister. +type CgroupNotifyListerExpansion interface{} + +// CgroupNotifyNamespaceListerExpansion allows custom methods to be added to +// CgroupNotifyNamespaceLister. +type CgroupNotifyNamespaceListerExpansion interface{} + +// RuleCheckListerExpansion allows custom methods to be added to +// RuleCheckLister. +type RuleCheckListerExpansion interface{} + +// RuleCheckNamespaceListerExpansion allows custom methods to be added to +// RuleCheckNamespaceLister. +type RuleCheckNamespaceListerExpansion interface{} diff --git a/pkg/generated/listers/caelus/v1/rulecheck.go b/pkg/generated/listers/caelus/v1/rulecheck.go new file mode 100644 index 00000000..298ee12c --- /dev/null +++ b/pkg/generated/listers/caelus/v1/rulecheck.go @@ -0,0 +1,99 @@ +/* +Copyright The Kubernetes Authors. + +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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "github.com/tencent/caelus/pkg/apis/caelus/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// RuleCheckLister helps list RuleChecks. +// All objects returned here must be treated as read-only. +type RuleCheckLister interface { + // List lists all RuleChecks in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.RuleCheck, err error) + // RuleChecks returns an object that can list and get RuleChecks. + RuleChecks(namespace string) RuleCheckNamespaceLister + RuleCheckListerExpansion +} + +// ruleCheckLister implements the RuleCheckLister interface. +type ruleCheckLister struct { + indexer cache.Indexer +} + +// NewRuleCheckLister returns a new RuleCheckLister. +func NewRuleCheckLister(indexer cache.Indexer) RuleCheckLister { + return &ruleCheckLister{indexer: indexer} +} + +// List lists all RuleChecks in the indexer. +func (s *ruleCheckLister) List(selector labels.Selector) (ret []*v1.RuleCheck, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.RuleCheck)) + }) + return ret, err +} + +// RuleChecks returns an object that can list and get RuleChecks. +func (s *ruleCheckLister) RuleChecks(namespace string) RuleCheckNamespaceLister { + return ruleCheckNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// RuleCheckNamespaceLister helps list and get RuleChecks. +// All objects returned here must be treated as read-only. +type RuleCheckNamespaceLister interface { + // List lists all RuleChecks in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.RuleCheck, err error) + // Get retrieves the RuleCheck from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.RuleCheck, error) + RuleCheckNamespaceListerExpansion +} + +// ruleCheckNamespaceLister implements the RuleCheckNamespaceLister +// interface. +type ruleCheckNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all RuleChecks in the indexer for a given namespace. +func (s ruleCheckNamespaceLister) List(selector labels.Selector) (ret []*v1.RuleCheck, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.RuleCheck)) + }) + return ret, err +} + +// Get retrieves the RuleCheck from the indexer for a given namespace and name. +func (s ruleCheckNamespaceLister) Get(name string) (*v1.RuleCheck, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("rulecheck"), name) + } + return obj.(*v1.RuleCheck), nil +}