github.com/kubewharf/katalyst-core@v0.5.3/cmd/katalyst-controller/app/options/controllerbase.go (about) 1 /* 2 Copyright 2022 The Katalyst Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package options 18 19 import ( 20 "fmt" 21 "time" 22 23 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 24 "k8s.io/apimachinery/pkg/labels" 25 "k8s.io/apimachinery/pkg/util/sets" 26 cliflag "k8s.io/component-base/cli/flag" 27 election "k8s.io/component-base/config" 28 29 controllerconfig "github.com/kubewharf/katalyst-core/pkg/config/controller" 30 "github.com/kubewharf/katalyst-core/pkg/util" 31 ) 32 33 // WorkloadProfilingOptions holds the configurations for spd lifecycle 34 type WorkloadProfilingOptions struct { 35 ExplicitChecking bool 36 37 // the requirements below work as 'and' rather than 'or' 38 AnnoSelector string 39 LabelSelector string 40 Namespaces []string 41 AntiNamespaces []string 42 } 43 44 func (w WorkloadProfilingOptions) getWorkloadEnableFunc() (util.WorkloadSPDEnabledFunc, bool, error) { 45 if !w.ExplicitChecking { 46 return nil, false, nil 47 } 48 49 var rules []util.WorkloadSPDEnabledFunc 50 51 if len(w.Namespaces) > 0 { 52 ns := sets.NewString(w.Namespaces...) 53 rules = append(rules, func(workload metav1.Object) bool { 54 return ns.Has(workload.GetNamespace()) 55 }) 56 57 } 58 59 if len(w.AntiNamespaces) > 0 { 60 ns := sets.NewString(w.AntiNamespaces...) 61 rules = append(rules, func(workload metav1.Object) bool { 62 return !ns.Has(workload.GetNamespace()) 63 }) 64 65 } 66 67 if w.AnnoSelector != "" { 68 if selector, err := labels.Parse(w.AnnoSelector); err != nil { 69 return nil, false, err 70 } else { 71 rules = append(rules, func(workload metav1.Object) bool { 72 return selector.Matches(labels.Set(workload.GetAnnotations())) 73 }) 74 } 75 } 76 77 if w.LabelSelector != "" { 78 if selector, err := labels.Parse(w.LabelSelector); err != nil { 79 return nil, false, err 80 } else { 81 rules = append(rules, func(workload metav1.Object) bool { 82 return selector.Matches(labels.Set(workload.GetLabels())) 83 }) 84 } 85 } 86 87 return func(workload metav1.Object) bool { 88 for _, f := range rules { 89 if !f(workload) { 90 return false 91 } 92 } 93 return true 94 }, true, nil 95 } 96 97 // GenericControllerOptions holds the configurations for controller based configurations. 98 type GenericControllerOptions struct { 99 Controllers []string 100 LabelSelector string 101 DynamicGVResources []string 102 103 election.LeaderElectionConfiguration 104 105 WorkloadProfilingOptions 106 } 107 108 // NewGenericControllerOptions creates a new Options with a default config. 109 func NewGenericControllerOptions() *GenericControllerOptions { 110 return &GenericControllerOptions{ 111 LeaderElectionConfiguration: election.LeaderElectionConfiguration{ 112 LeaderElect: true, 113 LeaseDuration: metav1.Duration{Duration: 15 * time.Second}, 114 RenewDeadline: metav1.Duration{Duration: 10 * time.Second}, 115 RetryPeriod: metav1.Duration{Duration: 2 * time.Second}, 116 ResourceLock: "leases", 117 ResourceName: "katalyst-controller", 118 ResourceNamespace: "kube-system", 119 }, 120 WorkloadProfilingOptions: WorkloadProfilingOptions{ 121 ExplicitChecking: false, 122 }, 123 } 124 } 125 126 // AddFlags adds flags to the specified FlagSet. 127 func (o *GenericControllerOptions) AddFlags(fss *cliflag.NamedFlagSets) { 128 fs := fss.FlagSet("generic-controller") 129 130 fs.BoolVar(&o.LeaderElect, "leader-elect", o.LeaderElect, ""+ 131 "Start a leader election client and gain leadership before "+ 132 "executing the main loop. Enable this when running replicated "+ 133 "components for high availability.") 134 fs.DurationVar(&o.LeaseDuration.Duration, "leader-elect-lease-duration", o.LeaseDuration.Duration, ""+ 135 "The duration that non-leader candidates will wait after observing a leadership "+ 136 "renewal until attempting to acquire leadership of a led but unrenewed leader "+ 137 "slot. This is effectively the maximum duration that a leader can be stopped "+ 138 "before it is replaced by another candidate. This is only applicable if leader "+ 139 "election is enabled.") 140 fs.DurationVar(&o.RenewDeadline.Duration, "leader-elect-renew-deadline", o.RenewDeadline.Duration, ""+ 141 "The interval between attempts by the acting master to renew a leadership slot "+ 142 "before it stops leading. This must be less than or equal to the lease duration. "+ 143 "This is only applicable if leader election is enabled.") 144 fs.DurationVar(&o.RetryPeriod.Duration, "leader-elect-retry-period", o.RetryPeriod.Duration, ""+ 145 "The duration the clients should wait between attempting acquisition and renewal "+ 146 "of a leadership. This is only applicable if leader election is enabled.") 147 fs.StringVar(&o.ResourceLock, "leader-elect-resource-lock", o.ResourceLock, ""+ 148 "The type of resource object that is used for locking during "+ 149 "leader election. Supported options are `endpoints` (default) and `configmaps`.") 150 fs.StringVar(&o.ResourceName, "leader-elect-resource-name", o.ResourceName, ""+ 151 "The name of resource object that is used for locking during leader election.") 152 fs.StringVar(&o.ResourceNamespace, "leader-elect-resource-namespace", o.ResourceNamespace, ""+ 153 "The namespace of resource object that is used for locking during leader election. ") 154 155 fs.StringSliceVar(&o.Controllers, "controllers", o.Controllers, fmt.Sprintf(""+ 156 "A list of controllers to enable. '*' enables all on-by-default controllers, 'foo' enables the controller "+ 157 "named 'foo', '-foo' disables the controller named 'foo'")) 158 159 fs.StringVar(&o.LabelSelector, "label-selector", o.LabelSelector, fmt.Sprintf(""+ 160 "A selector to restrict the list of returned objects by their labels. this selector is used in informer factory.")) 161 162 fs.StringSliceVar(&o.DynamicGVResources, "dynamic-resources", o.DynamicGVResources, fmt.Sprintf(""+ 163 "A list of resources to be list and watched. "+ 164 "DynamicGVResources should be in the format of `resource.version.group.com` like 'deployments.v1.apps'.")) 165 166 fs.BoolVar(&o.ExplicitChecking, "spd-workload-explicit-checking", o.ExplicitChecking, fmt.Sprintf(""+ 167 "If set as true, we will use default judgements to check whether workload need auto-profiing; "+ 168 "otherwise we will switch to check by the given checking requirements.")) 169 fs.StringSliceVar(&o.Namespaces, "spd-workload-namespaces", o.Namespaces, fmt.Sprintf(""+ 170 "Workload should be in the given namespaces if it wants service-profiling")) 171 fs.StringSliceVar(&o.AntiNamespaces, "spd-workload-anti-namespaces", o.AntiNamespaces, fmt.Sprintf(""+ 172 "Workload should [not] be in the given namespaces if it wants service-profiling")) 173 fs.StringVar(&o.AnnoSelector, "spd-workload-anno-selector", o.AnnoSelector, fmt.Sprintf(""+ 174 "Workload should match with the selector for annotations if it wants service-profiling")) 175 fs.StringVar(&o.LabelSelector, "spd-workload-label-selector", o.LabelSelector, fmt.Sprintf(""+ 176 "Workload should match with the selector for labels if it wants service-profiling")) 177 } 178 179 // ApplyTo fills up config with options 180 func (o *GenericControllerOptions) ApplyTo(c *controllerconfig.GenericControllerConfiguration) error { 181 c.LeaderElection.LeaderElect = o.LeaderElect 182 c.LeaderElection.LeaseDuration = o.LeaseDuration 183 c.LeaderElection.RenewDeadline = o.RenewDeadline 184 c.LeaderElection.RetryPeriod = o.RetryPeriod 185 c.LeaderElection.ResourceLock = o.ResourceLock 186 c.LeaderElection.ResourceName = o.ResourceName 187 c.LeaderElection.ResourceNamespace = o.ResourceNamespace 188 189 c.Controllers = o.Controllers 190 c.LabelSelector = o.LabelSelector 191 c.DynamicGVResources = o.DynamicGVResources 192 193 if f, ok, err := o.getWorkloadEnableFunc(); err != nil { 194 return fmt.Errorf("failed to construct workload-enable func: %v", err) 195 } else if ok { 196 util.SetWorkloadEnableFunc(f) 197 } 198 199 return nil 200 } 201 202 func (o *GenericControllerOptions) Config() (*controllerconfig.GenericControllerConfiguration, error) { 203 c := controllerconfig.NewGenericControllerConfiguration() 204 if err := o.ApplyTo(c); err != nil { 205 return nil, err 206 } 207 return c, nil 208 }