From 30ab3011d569d319d386c7f14f4661007f227bc2 Mon Sep 17 00:00:00 2001 From: Krisztian Litkey Date: Fri, 29 Nov 2024 12:36:46 +0200 Subject: [PATCH] agent,config,helm: make agent runtime configurable. Add configuration for the agent itself. Currently the only control enables access to Node Resource Topology Custom Resources and it is on by default. Update the agent to honor its configuration. Signed-off-by: Krisztian Litkey --- .../bases/config.nri_balloonspolicies.yaml | 12 +++ .../bases/config.nri_templatepolicies.yaml | 12 +++ .../config.nri_topologyawarepolicies.yaml | 12 +++ .../crds/config.nri_balloonspolicies.yaml | 12 +++ .../crds/config.nri_templatepolicies.yaml | 12 +++ .../config.nri_topologyawarepolicies.yaml | 12 +++ pkg/agent/agent.go | 94 ++++++++++++++----- pkg/apis/config/v1alpha1/agent.go | 31 ++++++ pkg/apis/config/v1alpha1/balloons-policy.go | 10 ++ pkg/apis/config/v1alpha1/resmgr.go | 1 + pkg/apis/config/v1alpha1/template-policy.go | 10 ++ .../config/v1alpha1/topology-aware-policy.go | 10 ++ pkg/apis/config/v1alpha1/types.go | 9 ++ .../config/v1alpha1/zz_generated.deepcopy.go | 18 ++++ 14 files changed, 232 insertions(+), 23 deletions(-) create mode 100644 pkg/apis/config/v1alpha1/agent.go diff --git a/config/crd/bases/config.nri_balloonspolicies.yaml b/config/crd/bases/config.nri_balloonspolicies.yaml index a49c020aa..c0601b9f0 100644 --- a/config/crd/bases/config.nri_balloonspolicies.yaml +++ b/config/crd/bases/config.nri_balloonspolicies.yaml @@ -40,6 +40,18 @@ spec: spec: description: BalloonsPolicySpec describes a balloons policy. properties: + agent: + default: + nodeResourceTopology: true + description: AgentConfig provides access to configuration data for + the agent. + properties: + nodeResourceTopology: + description: |- + NodeResourceTopology enables support for exporting resource usage using + NodeResourceTopology Custom Resources. + type: boolean + type: object allocatorTopologyBalancing: description: |- If AllocatorTopologyBalancing is true, balloons are diff --git a/config/crd/bases/config.nri_templatepolicies.yaml b/config/crd/bases/config.nri_templatepolicies.yaml index cea85dc1d..125e5ccb7 100644 --- a/config/crd/bases/config.nri_templatepolicies.yaml +++ b/config/crd/bases/config.nri_templatepolicies.yaml @@ -40,6 +40,18 @@ spec: spec: description: TemplatePolicySpec describes a template policy. properties: + agent: + default: + nodeResourceTopology: true + description: AgentConfig provides access to configuration data for + the agent. + properties: + nodeResourceTopology: + description: |- + NodeResourceTopology enables support for exporting resource usage using + NodeResourceTopology Custom Resources. + type: boolean + type: object availableResources: additionalProperties: type: string diff --git a/config/crd/bases/config.nri_topologyawarepolicies.yaml b/config/crd/bases/config.nri_topologyawarepolicies.yaml index a7c215f1d..5d2e6e100 100644 --- a/config/crd/bases/config.nri_topologyawarepolicies.yaml +++ b/config/crd/bases/config.nri_topologyawarepolicies.yaml @@ -40,6 +40,18 @@ spec: spec: description: TopologyAwarePolicySpec describes a topology-aware policy. properties: + agent: + default: + nodeResourceTopology: true + description: AgentConfig provides access to configuration data for + the agent. + properties: + nodeResourceTopology: + description: |- + NodeResourceTopology enables support for exporting resource usage using + NodeResourceTopology Custom Resources. + type: boolean + type: object availableResources: additionalProperties: type: string diff --git a/deployment/helm/balloons/crds/config.nri_balloonspolicies.yaml b/deployment/helm/balloons/crds/config.nri_balloonspolicies.yaml index a49c020aa..c0601b9f0 100644 --- a/deployment/helm/balloons/crds/config.nri_balloonspolicies.yaml +++ b/deployment/helm/balloons/crds/config.nri_balloonspolicies.yaml @@ -40,6 +40,18 @@ spec: spec: description: BalloonsPolicySpec describes a balloons policy. properties: + agent: + default: + nodeResourceTopology: true + description: AgentConfig provides access to configuration data for + the agent. + properties: + nodeResourceTopology: + description: |- + NodeResourceTopology enables support for exporting resource usage using + NodeResourceTopology Custom Resources. + type: boolean + type: object allocatorTopologyBalancing: description: |- If AllocatorTopologyBalancing is true, balloons are diff --git a/deployment/helm/template/crds/config.nri_templatepolicies.yaml b/deployment/helm/template/crds/config.nri_templatepolicies.yaml index cea85dc1d..125e5ccb7 100644 --- a/deployment/helm/template/crds/config.nri_templatepolicies.yaml +++ b/deployment/helm/template/crds/config.nri_templatepolicies.yaml @@ -40,6 +40,18 @@ spec: spec: description: TemplatePolicySpec describes a template policy. properties: + agent: + default: + nodeResourceTopology: true + description: AgentConfig provides access to configuration data for + the agent. + properties: + nodeResourceTopology: + description: |- + NodeResourceTopology enables support for exporting resource usage using + NodeResourceTopology Custom Resources. + type: boolean + type: object availableResources: additionalProperties: type: string diff --git a/deployment/helm/topology-aware/crds/config.nri_topologyawarepolicies.yaml b/deployment/helm/topology-aware/crds/config.nri_topologyawarepolicies.yaml index a7c215f1d..5d2e6e100 100644 --- a/deployment/helm/topology-aware/crds/config.nri_topologyawarepolicies.yaml +++ b/deployment/helm/topology-aware/crds/config.nri_topologyawarepolicies.yaml @@ -40,6 +40,18 @@ spec: spec: description: TopologyAwarePolicySpec describes a topology-aware policy. properties: + agent: + default: + nodeResourceTopology: true + description: AgentConfig provides access to configuration data for + the agent. + properties: + nodeResourceTopology: + description: |- + NodeResourceTopology enables support for exporting resource usage using + NodeResourceTopology Custom Resources. + type: boolean + type: object availableResources: additionalProperties: type: string diff --git a/pkg/agent/agent.go b/pkg/agent/agent.go index 334b298b2..f0f6b9cd5 100644 --- a/pkg/agent/agent.go +++ b/pkg/agent/agent.go @@ -268,37 +268,39 @@ func (a *Agent) hasLocalConfig() bool { func (a *Agent) setupClients() error { if a.hasLocalConfig() { + log.Warn("running with local configuration, skipping cluster access client setup...") return nil } - cfg, err := a.getRESTConfig() - if err != nil { - return err - } + // Create HTTP/REST client and K8s client on initial startup. Any failure + // to create these is a failure start up. + if a.httpCli == nil { + log.Info("setting up HTTP/REST client...") + restCfg, err := a.getRESTConfig() + if err != nil { + return err + } - a.httpCli, err = rest.HTTPClientFor(cfg) - if err != nil { - return fmt.Errorf("failed to setup kubernetes HTTP client: %w", err) - } + a.httpCli, err = rest.HTTPClientFor(restCfg) + if err != nil { + return fmt.Errorf("failed to setup kubernetes HTTP client: %w", err) + } - a.k8sCli, err = k8sclient.NewForConfigAndClient(cfg, a.httpCli) - if err != nil { - a.cleanupClients() - return fmt.Errorf("failed to setup kubernetes client: %w", err) - } + log.Info("setting up K8s client...") + a.k8sCli, err = k8sclient.NewForConfigAndClient(restCfg, a.httpCli) + if err != nil { + a.cleanupClients() + return fmt.Errorf("failed to setup kubernetes client: %w", err) + } - restCfg := *cfg - a.nrtCli, err = nrtapi.NewForConfigAndClient(&restCfg, a.httpCli) - if err != nil { - a.cleanupClients() - return fmt.Errorf("failed to setup NRT client: %w", err) + kubeCfg := *restCfg + err = a.cfgIf.SetKubeClient(a.httpCli, &kubeCfg) + if err != nil { + return fmt.Errorf("failed to setup kubernetes config resource client: %w", err) + } } - restCfg = *cfg - err = a.cfgIf.SetKubeClient(a.httpCli, &restCfg) - if err != nil { - return fmt.Errorf("failed to setup kubernetes config resource client: %w", err) - } + a.configure(a.currentCfg) return nil } @@ -312,6 +314,51 @@ func (a *Agent) cleanupClients() { a.nrtCli = nil } +var ( + defaultConfig = &cfgapi.AgentConfig{ + NodeResourceTopology: true, + } +) + +func getAgentConfig(newConfig metav1.Object) *cfgapi.AgentConfig { + cfg := cfgapi.GetAgentConfig(newConfig) + if cfg == nil { + return defaultConfig + } + return cfg +} + +func (a *Agent) configure(newConfig metav1.Object) { + if a.hasLocalConfig() { + log.Warn("running with local configuration, skipping client setup...") + return + } + + cfg := getAgentConfig(newConfig) + + // Reconfigure NRT client, both on initial startup and reconfiguration. + // Failure to create a client is not a fatal error. + switch { + case cfg.NodeResourceTopology && a.nrtCli == nil: + log.Info("enabling NRT client") + cfg, err := a.getRESTConfig() + if err != nil { + log.Error("failed to setup NRT client: %w", err) + break + } + cli, err := nrtapi.NewForConfigAndClient(cfg, a.httpCli) + if err != nil { + log.Error("failed to setup NRT client: %w", err) + break + } + a.nrtCli = cli + + case !cfg.NodeResourceTopology && a.nrtCli != nil: + log.Info("disabling NRT client") + a.nrtCli = nil + } +} + func (a *Agent) getRESTConfig() (*rest.Config, error) { var ( cfg *rest.Config @@ -556,6 +603,7 @@ func (a *Agent) updateConfig(cfg metav1.Object) { } a.currentCfg = cfg + a.configure(cfg) } func (a *Agent) patchConfigStatus(prev, curr metav1.Object, errors error) { diff --git a/pkg/apis/config/v1alpha1/agent.go b/pkg/apis/config/v1alpha1/agent.go new file mode 100644 index 000000000..c01b9305a --- /dev/null +++ b/pkg/apis/config/v1alpha1/agent.go @@ -0,0 +1,31 @@ +// Copyright The NRI Plugins Authors. All Rights Reserved. +// +// 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 v1alpha1 + +// AgentConfig provides access to configuration data for the agent. +type AgentConfig struct { + // NodeResourceTopology enables support for exporting resource usage using + // NodeResourceTopology Custom Resources. + // +optional + NodeResourceTopology bool `json:"nodeResourceTopology,omitempty"` +} + +// GetAgentConfig returns the agent-specific configuration if we have one. +func GetAgentConfig(cfg interface{}) *AgentConfig { + if ac, ok := cfg.(interface{ AgentConfig() *AgentConfig }); ok { + return ac.AgentConfig() + } + return nil +} diff --git a/pkg/apis/config/v1alpha1/balloons-policy.go b/pkg/apis/config/v1alpha1/balloons-policy.go index 9622b6b43..70fcb1423 100644 --- a/pkg/apis/config/v1alpha1/balloons-policy.go +++ b/pkg/apis/config/v1alpha1/balloons-policy.go @@ -18,6 +18,16 @@ var ( _ ResmgrConfig = &BalloonsPolicy{} ) +func (c *BalloonsPolicy) AgentConfig() *AgentConfig { + if c == nil { + return nil + } + + a := c.Spec.Agent + + return &a +} + func (c *BalloonsPolicy) CommonConfig() *CommonConfig { if c == nil { return nil diff --git a/pkg/apis/config/v1alpha1/resmgr.go b/pkg/apis/config/v1alpha1/resmgr.go index e89d4d2c9..d026f3a0c 100644 --- a/pkg/apis/config/v1alpha1/resmgr.go +++ b/pkg/apis/config/v1alpha1/resmgr.go @@ -29,6 +29,7 @@ import ( // +kubebuilder:object:generate=false type ResmgrConfig interface { metav1.ObjectMetaAccessor + AgentConfig() *AgentConfig CommonConfig() *CommonConfig PolicyConfig() interface{} } diff --git a/pkg/apis/config/v1alpha1/template-policy.go b/pkg/apis/config/v1alpha1/template-policy.go index 97258c947..3a598a742 100644 --- a/pkg/apis/config/v1alpha1/template-policy.go +++ b/pkg/apis/config/v1alpha1/template-policy.go @@ -18,6 +18,16 @@ var ( _ ResmgrConfig = &TemplatePolicy{} ) +func (c *TemplatePolicy) AgentConfig() *AgentConfig { + if c == nil { + return nil + } + + a := c.Spec.Agent + + return &a +} + func (c *TemplatePolicy) CommonConfig() *CommonConfig { if c == nil { return nil diff --git a/pkg/apis/config/v1alpha1/topology-aware-policy.go b/pkg/apis/config/v1alpha1/topology-aware-policy.go index 75df70498..2d4984649 100644 --- a/pkg/apis/config/v1alpha1/topology-aware-policy.go +++ b/pkg/apis/config/v1alpha1/topology-aware-policy.go @@ -18,6 +18,16 @@ var ( _ ResmgrConfig = &TopologyAwarePolicy{} ) +func (c *TopologyAwarePolicy) AgentConfig() *AgentConfig { + if c == nil { + return nil + } + + a := c.Spec.Agent + + return &a +} + func (c *TopologyAwarePolicy) CommonConfig() *CommonConfig { if c == nil { return nil diff --git a/pkg/apis/config/v1alpha1/types.go b/pkg/apis/config/v1alpha1/types.go index 07730aea2..5acc9ba70 100644 --- a/pkg/apis/config/v1alpha1/types.go +++ b/pkg/apis/config/v1alpha1/types.go @@ -46,6 +46,9 @@ type TopologyAwarePolicySpec struct { Log log.Config `json:"log,omitempty"` // +optional Instrumentation instrumentation.Config `json:"instrumentation,omitempty"` + // +optional + // +kubebuilder:default={"nodeResourceTopology": true } + Agent AgentConfig `json:"agent,omitempty"` } // TopologyAwarePolicyList represents a list of TopologyAwarePolicies. @@ -78,6 +81,9 @@ type BalloonsPolicySpec struct { Log log.Config `json:"log,omitempty"` // +optional Instrumentation instrumentation.Config `json:"instrumentation,omitempty"` + // +optional + // +kubebuilder:default={"nodeResourceTopology": true } + Agent AgentConfig `json:"agent,omitempty"` } // BalloonsPolicyList represents a list of BalloonsPolicies. @@ -110,6 +116,9 @@ type TemplatePolicySpec struct { Log log.Config `json:"log,omitempty"` // +optional Instrumentation instrumentation.Config `json:"instrumentation,omitempty"` + // +optional + // +kubebuilder:default={"nodeResourceTopology": true } + Agent AgentConfig `json:"agent,omitempty"` } // TemplatePolicyList represents a list of TemplatePolicies. diff --git a/pkg/apis/config/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/config/v1alpha1/zz_generated.deepcopy.go index 2ca084794..21f01a9e6 100644 --- a/pkg/apis/config/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/config/v1alpha1/zz_generated.deepcopy.go @@ -22,6 +22,21 @@ import ( 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 *AgentConfig) DeepCopyInto(out *AgentConfig) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AgentConfig. +func (in *AgentConfig) DeepCopy() *AgentConfig { + if in == nil { + return nil + } + out := new(AgentConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BalloonsPolicy) DeepCopyInto(out *BalloonsPolicy) { *out = *in @@ -88,6 +103,7 @@ func (in *BalloonsPolicySpec) DeepCopyInto(out *BalloonsPolicySpec) { in.Control.DeepCopyInto(&out.Control) in.Log.DeepCopyInto(&out.Log) in.Instrumentation.DeepCopyInto(&out.Instrumentation) + out.Agent = in.Agent } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BalloonsPolicySpec. @@ -227,6 +243,7 @@ func (in *TemplatePolicySpec) DeepCopyInto(out *TemplatePolicySpec) { in.Control.DeepCopyInto(&out.Control) in.Log.DeepCopyInto(&out.Log) in.Instrumentation.DeepCopyInto(&out.Instrumentation) + out.Agent = in.Agent } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TemplatePolicySpec. @@ -305,6 +322,7 @@ func (in *TopologyAwarePolicySpec) DeepCopyInto(out *TopologyAwarePolicySpec) { in.Control.DeepCopyInto(&out.Control) in.Log.DeepCopyInto(&out.Log) in.Instrumentation.DeepCopyInto(&out.Instrumentation) + out.Agent = in.Agent } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TopologyAwarePolicySpec.