From da174cf08ef25ba091f6600989f4e68e60292915 Mon Sep 17 00:00:00 2001 From: Milica Cvrkota Date: Tue, 14 Jan 2025 12:11:08 +0100 Subject: [PATCH 1/2] add zones to the example instanaagent.yaml --- .../samples/instana_v1_extended_instanaagent.yaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/config/samples/instana_v1_extended_instanaagent.yaml b/config/samples/instana_v1_extended_instanaagent.yaml index dee15849..4ee589bb 100644 --- a/config/samples/instana_v1_extended_instanaagent.yaml +++ b/config/samples/instana_v1_extended_instanaagent.yaml @@ -227,3 +227,18 @@ spec: memory: 3072Mi # kubernetes.deployment.pod.limits.cpu sets the CPU units allocation limits for the agent pods. cpu: 4 + + zones: + # Configure use of zones to use tolerations as the basis to associate a specific daemonset per tainted node pool + - name: pool-01 + tolerations: + - key: "pool" + operator: "Equal" + value: "pool-01" + effect: "NoExecute" + - name: pool-02 + tolerations: + - key: "pool" + operator: "Equal" + value: "pool-02" + effect: "NoExecute" \ No newline at end of file From 2709a598684a0b9eec3598e3aecb9f0f8ff59fea Mon Sep 17 00:00:00 2001 From: Milica Cvrkota Date: Tue, 30 Jul 2024 15:52:24 +0200 Subject: [PATCH 2/2] add ServiceEntries when REGISTRY_ONLY enabled Signed-off-by: Milica Cvrkota --- api/v1/inline_types.go | 4 + api/v1/instanaagent_types.go | 2 + api/v1/instanaagent_types_test.go | 25 +++++++ config/rbac/role.yaml | 7 ++ .../instana_v1_extended_instanaagent.yaml | 4 + controllers/apply.go | 12 +++ controllers/controllers_test.go | 16 ++++ controllers/instanaagent_controller.go | 8 ++ controllers/util.go | 73 ++++++++++++++++++ go.mod | 11 ++- go.sum | 22 ++++-- main.go | 3 + pkg/k8s/client/client.go | 8 ++ .../agent/serviceentry/serviceentry.go | 75 +++++++++++++++++++ .../builders/common/constants/constants.go | 4 + .../builders/k8s-sensor/rbac/clusterrole.go | 5 ++ 16 files changed, 267 insertions(+), 12 deletions(-) create mode 100644 pkg/k8s/object/builders/agent/serviceentry/serviceentry.go diff --git a/api/v1/inline_types.go b/api/v1/inline_types.go index 5cf65f01..a43c52d8 100644 --- a/api/v1/inline_types.go +++ b/api/v1/inline_types.go @@ -295,6 +295,10 @@ type HostSpec struct { type ServiceMeshSpec struct { // +kubebuilder:validation:Optional Enabled bool `json:"enabled,omitempty"` + // +kubebuilder:validation:Optional + Namespace string `json:"namespace,omitempty"` + // +kubebuilder:validation:Optional + Configmap string `json:"configmap,omitempty"` } type Prometheus struct { diff --git a/api/v1/instanaagent_types.go b/api/v1/instanaagent_types.go index efd2502f..86d04f7d 100644 --- a/api/v1/instanaagent_types.go +++ b/api/v1/instanaagent_types.go @@ -173,6 +173,8 @@ func (in *InstanaAgent) Default() { optional.ValueOrDefault(&in.Spec.K8sSensor.ImageSpec.Tag, "latest") optional.ValueOrDefault(&in.Spec.K8sSensor.ImageSpec.PullPolicy, corev1.PullAlways) optional.ValueOrDefault(&in.Spec.K8sSensor.DeploymentSpec.Replicas, 3) + optional.ValueOrDefault(&in.Spec.Agent.ServiceMesh.Namespace, "istio-system") + optional.ValueOrDefault(&in.Spec.Agent.ServiceMesh.Configmap, "istio") } // +kubebuilder:object:root=true diff --git a/api/v1/instanaagent_types_test.go b/api/v1/instanaagent_types_test.go index 7b5c4740..96dc3a99 100644 --- a/api/v1/instanaagent_types_test.go +++ b/api/v1/instanaagent_types_test.go @@ -1,3 +1,20 @@ +/* +(c) Copyright IBM Corp. 2024 +(c) Copyright Instana Inc. + +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 ( @@ -51,6 +68,10 @@ func TestInstanaAgent_Default(t *testing.T) { Replicas: 2, }, }, + ServiceMesh: ServiceMeshSpec{ + Namespace: "istio-system", + Configmap: "istio", + }, } tests := []struct { @@ -100,6 +121,10 @@ func TestInstanaAgent_Default(t *testing.T) { Replicas: 3, }, }, + ServiceMesh: ServiceMeshSpec{ + Namespace: "istio-system", + Configmap: "istio", + }, }, }, { diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index fcf15c49..fb79da1c 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -138,6 +138,13 @@ rules: - get - patch - update +- apiGroups: + - networking.istio.io + resources: + - serviceentries + verbs: + - create + - patch - apiGroups: - networking.k8s.io resources: diff --git a/config/samples/instana_v1_extended_instanaagent.yaml b/config/samples/instana_v1_extended_instanaagent.yaml index 4ee589bb..befc6c5f 100644 --- a/config/samples/instana_v1_extended_instanaagent.yaml +++ b/config/samples/instana_v1_extended_instanaagent.yaml @@ -117,6 +117,10 @@ spec: # agent.serviceMesh.enabled sets the Instana agent's communication direction with JVMs. # To allow communication to be directed to the agent, set this variable to true. enabled: true + # Namespace where istio is installed. Defaults to istio-system. This may have to be changed for OpenShift ServiceMesh + namespace: istio-system + # ConfigMap for mesh. Defaults to istio. This may have to be changed for OpenShift ServiceMesh + configmap: istio # agent.host.repository sets a host path to be mounted as the agent maven repository (for debugging or development purposes) # host: diff --git a/controllers/apply.go b/controllers/apply.go index 5682458b..25631724 100644 --- a/controllers/apply.go +++ b/controllers/apply.go @@ -29,6 +29,7 @@ import ( "github.com/instana/instana-agent-operator/pkg/k8s/object/builders/agent/service" agentserviceaccount "github.com/instana/instana-agent-operator/pkg/k8s/object/builders/agent/serviceaccount" backends "github.com/instana/instana-agent-operator/pkg/k8s/object/builders/common/backends" + "github.com/instana/instana-agent-operator/pkg/k8s/object/builders/agent/serviceentry" "github.com/instana/instana-agent-operator/pkg/k8s/object/builders/common/builder" k8ssensorconfigmap "github.com/instana/instana-agent-operator/pkg/k8s/object/builders/k8s-sensor/configmap" k8ssensordeployment "github.com/instana/instana-agent-operator/pkg/k8s/object/builders/k8s-sensor/deployment" @@ -83,6 +84,8 @@ func (r *InstanaAgentReconciler) applyResources( ctx context.Context, agent *instanav1.InstanaAgent, isOpenShift bool, + isIstioRegistryOnlyEnabled bool, + nodeIPs []string, operatorUtils operator_utils.OperatorUtils, statusManager status.AgentStatusManager, keysSecret *corev1.Secret, @@ -91,6 +94,14 @@ func (r *InstanaAgentReconciler) applyResources( log := r.loggerFor(ctx, agent) log.V(1).Info("applying Kubernetes resources for agent") + var serviceEntriesBuilders []builder.ObjectBuilder + + if isIstioRegistryOnlyEnabled { + for _, nodeIP := range nodeIPs { + serviceEntriesBuilders = append(serviceEntriesBuilders, serviceentry.NewServiceEntriesBuilder(agent, nodeIP)) + } + } + builders := append( getDaemonSetBuilders(agent, isOpenShift, statusManager), headlessservice.NewHeadlessServiceBuilder(agent), @@ -108,6 +119,7 @@ func (r *InstanaAgentReconciler) applyResources( ) builders = append(builders, getK8sSensorDeployments(agent, isOpenShift, statusManager, k8SensorBackends)...) + builders = append(builders, serviceEntriesBuilders...) if err := operatorUtils.ApplyAll(builders...); err != nil { log.Error(err, "failed to apply kubernetes resources for agent") diff --git a/controllers/controllers_test.go b/controllers/controllers_test.go index e80f657d..507b10d2 100644 --- a/controllers/controllers_test.go +++ b/controllers/controllers_test.go @@ -136,6 +136,12 @@ var ( }, key: agentNamespace, } + agentServiceEntries = object{ + gvk: schema.GroupVersionKind{ + Version: "networking.istio.io/v1alpha3", + Kind: "ServiceEntry", + }, + } ) // number of k8sensor resources used for diffing whether the controller functions properly @@ -316,6 +322,16 @@ func (suite *InstanaAgentControllerTestSuite) TestInstanaAgentCR() { "Should contain all objects in the schema", ) + require.Eventually(suite.T(), + suite.all( + suite.notExist, + agentServiceEntries, + ), + 10*time.Second, + time.Second, + "Should not contain ServiceEntries by default", + ) + agentNew := agent.DeepCopy() agentNew.Spec.K8sSensor.PodDisruptionBudget.Enabled = pointer.To(false) agentNew.Spec.Agent.KeysSecret = "test" diff --git a/controllers/instanaagent_controller.go b/controllers/instanaagent_controller.go index f6139c2c..cd225c18 100644 --- a/controllers/instanaagent_controller.go +++ b/controllers/instanaagent_controller.go @@ -132,10 +132,17 @@ func (r *InstanaAgentReconciler) reconcile( k8SensorBackends := r.getK8SensorBackends(agent) + isIstioRegistryOnlyEnabled, nodeIPs, isIstioRegistryOnlyEnabledRes := r.getIstioOutboundConfigAndNodeIps(ctx, agent.Spec.ServiceMesh.Namespace, agent.Spec.ServiceMesh.Configmap) + if isIstioRegistryOnlyEnabledRes.suppliesReconcileResult() { + return isIstioRegistryOnlyEnabledRes + } + if applyResourcesRes := r.applyResources( ctx, agent, isOpenShift, + isIstioRegistryOnlyEnabled, + nodeIPs, operatorUtils, statusManager, keysSecret, @@ -168,6 +175,7 @@ func (r *InstanaAgentReconciler) reconcile( // +kubebuilder:rbac:groups=apps.openshift.io,resources=deploymentconfigs,verbs=get;list;watch // +kubebuilder:rbac:groups=security.openshift.io,resourceNames=privileged,resources=securitycontextconstraints,verbs=use // +kubebuilder:rbac:groups=policy,resourceNames=instana-agent-k8sensor,resources=podsecuritypolicies,verbs=use +// +kubebuilder:rbac:groups=networking.istio.io,resources=serviceentries,verbs=create;patch func (r *InstanaAgentReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( res ctrl.Result, diff --git a/controllers/util.go b/controllers/util.go index e60489b2..8d10123d 100644 --- a/controllers/util.go +++ b/controllers/util.go @@ -20,8 +20,13 @@ package controllers import ( "context" "strconv" + "fmt" + "strings" "github.com/go-logr/logr" + "gopkg.in/yaml.v3" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" logf "sigs.k8s.io/controller-runtime/pkg/log" instanav1 "github.com/instana/instana-agent-operator/api/v1" @@ -29,6 +34,12 @@ import ( "github.com/instana/instana-agent-operator/pkg/k8s/operator/operator_utils" ) +type IstioMeshConfig struct { + OutboundTrafficPolicy struct { + Mode string `yaml:"mode"` + } `yaml:"outboundTrafficPolicy"` +} + func (r *InstanaAgentReconciler) isOpenShift(ctx context.Context, operatorUtils operator_utils.OperatorUtils) ( bool, reconcileReturn, @@ -62,6 +73,68 @@ func (r *InstanaAgentReconciler) getK8SensorBackends(agent *instanav1.InstanaAge ) } return k8SensorBackends +func (r *InstanaAgentReconciler) getIstioOutboundConfigAndNodeIps(ctx context.Context, namespace string, configmap string) ( + bool, + []string, + reconcileReturn, +) { + log := logf.FromContext(ctx) + var nodeIPs []string + + log.Info("Check if REGISTRY_ONLY is enabled") + isIstioRegistryOnlyEnabled := r.checkRegistryOnlyMode(ctx, namespace, configmap) + + if isIstioRegistryOnlyEnabled { + nodes, err := r.client.ListNodes(ctx) + if err != nil { + log.Error(err, "could not list nodes for generating ServiceEntries") + } + nodeIPs = getNodeIPs(nodes) + } + + return isIstioRegistryOnlyEnabled, nodeIPs, reconcileContinue() +} + +func (r *InstanaAgentReconciler) checkRegistryOnlyMode(ctx context.Context, namespace string, configmap string) bool { + istioConfigMap := &corev1.ConfigMap{} + log := logf.FromContext(ctx) + log.Info(fmt.Sprintf("Checking Istio ConfigMap %s in namespace %s for outbound traffic policy", configmap, namespace)) + err := r.client.Get(ctx, types.NamespacedName{Name: configmap, Namespace: namespace}, istioConfigMap) + if err != nil { + log.Error(err, "Failed fetching istio ConfigMap") + return false + } + if istioConfigMap.Data == nil { + log.Info(fmt.Sprintf("Istio configmap %s in namespace %s data in nil", configmap, namespace)) + return false + } + meshConfigData, ok := istioConfigMap.Data["mesh"] + if !ok { + return false + } + + var meshConfig IstioMeshConfig + log.Info("Unmarshalling config data") + err = yaml.Unmarshal([]byte(meshConfigData), &meshConfig) + if err != nil { + log.Error(err, "Unmarshalling config data ERROR") + return false + } + log.Info("Checking if policy is REGISTRY_ONLY") + + return strings.EqualFold(meshConfig.OutboundTrafficPolicy.Mode, "REGISTRY_ONLY") +} + +func getNodeIPs(nodes *corev1.NodeList) []string { + var nodeIPs []string + for _, node := range nodes.Items { + for _, address := range node.Status.Addresses { + if address.Type == corev1.NodeInternalIP { + nodeIPs = append(nodeIPs, address.Address) + } + } + } + return nodeIPs } func (r *InstanaAgentReconciler) loggerFor(ctx context.Context, agent *instanav1.InstanaAgent) logr.Logger { diff --git a/go.mod b/go.mod index ccde08fb..adeb904b 100644 --- a/go.mod +++ b/go.mod @@ -17,6 +17,8 @@ require ( golang.org/x/net v0.34.0 gopkg.in/yaml.v3 v3.0.1 helm.sh/helm/v3 v3.15.4 + istio.io/api v1.24.2-0.20241206152109-43afb8563706 + istio.io/client-go v1.24.2 k8s.io/api v0.30.3 k8s.io/apimachinery v0.30.3 k8s.io/client-go v0.30.3 @@ -135,7 +137,7 @@ require ( go.uber.org/zap v1.26.0 // indirect golang.org/x/crypto v0.32.0 // indirect golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect - golang.org/x/oauth2 v0.17.0 // indirect + golang.org/x/oauth2 v0.18.0 // indirect golang.org/x/sync v0.10.0 // indirect golang.org/x/sys v0.29.0 // indirect golang.org/x/term v0.28.0 // indirect @@ -143,9 +145,10 @@ require ( golang.org/x/time v0.5.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect - google.golang.org/grpc v1.58.3 // indirect - google.golang.org/protobuf v1.33.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240513163218-0867130af1f8 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240513163218-0867130af1f8 // indirect + google.golang.org/grpc v1.64.1 // indirect + google.golang.org/protobuf v1.34.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect k8s.io/apiextensions-apiserver v0.30.3 // indirect diff --git a/go.sum b/go.sum index dd523a6b..7f7f9e9a 100644 --- a/go.sum +++ b/go.sum @@ -447,8 +447,8 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= -golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= +golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= +golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -517,13 +517,15 @@ google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/genproto/googleapis/api v0.0.0-20240513163218-0867130af1f8 h1:W5Xj/70xIA4x60O/IFyXivR5MGqblAb8R3w26pnD6No= +google.golang.org/genproto/googleapis/api v0.0.0-20240513163218-0867130af1f8/go.mod h1:vPrPUTsDCYxXWjP7clS81mZ6/803D8K4iM9Ma27VKas= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240513163218-0867130af1f8 h1:mxSlqyb8ZAHsYDCfiXN1EDdNTdvjUJSLY+OnAUtYNYA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240513163218-0867130af1f8/go.mod h1:I7Y+G38R2bu5j1aLzfFmQfTcU/WnFuqDwLZAbvKTKpM= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= -google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA= +google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -534,8 +536,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= @@ -557,6 +559,10 @@ helm.sh/helm/v3 v3.15.4 h1:UFHd6oZ1IN3FsUZ7XNhOQDyQ2QYknBNWRHH57e9cbHY= helm.sh/helm/v3 v3.15.4/go.mod h1:phOwlxqGSgppCY/ysWBNRhG3MtnpsttOzxaTK+Mt40E= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +istio.io/api v1.24.2-0.20241206152109-43afb8563706 h1:ozWjpvlfA1qFPPOolmqPtus+WwI0rX8uSLqoD+M6C0g= +istio.io/api v1.24.2-0.20241206152109-43afb8563706/go.mod h1:MQnRok7RZ20/PE56v0LxmoWH0xVxnCQPNuf9O7PAN1I= +istio.io/client-go v1.24.2 h1:JTTfBV6dv+AAW+AfccyrdX4T1f9CpsXd1Yzo1s/IYAI= +istio.io/client-go v1.24.2/go.mod h1:dgZ9EmJzh1EECzf6nQhwNL4R6RvlyeH/RXeNeNp/MRg= k8s.io/api v0.30.3 h1:ImHwK9DCsPA9uoU3rVh4QHAHHK5dTSv1nxJUapx8hoQ= k8s.io/api v0.30.3/go.mod h1:GPc8jlzoe5JG3pb0KJCSLX5oAFIW3/qNJITlDj8BH04= k8s.io/apiextensions-apiserver v0.30.3 h1:oChu5li2vsZHx2IvnGP3ah8Nj3KyqG3kRSaKmijhB9U= diff --git a/main.go b/main.go index 1389601c..df4c03de 100644 --- a/main.go +++ b/main.go @@ -12,6 +12,7 @@ import ( "runtime" "strconv" + istionetworking "istio.io/client-go/pkg/apis/networking/v1alpha3" k8sruntime "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" @@ -37,6 +38,8 @@ func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) utilruntime.Must(agentoperatorv1.AddToScheme(scheme)) + + utilruntime.Must(istionetworking.AddToScheme(scheme)) // +kubebuilder:scaffold:scheme } diff --git a/pkg/k8s/client/client.go b/pkg/k8s/client/client.go index 25bd4f6c..8db47fb4 100644 --- a/pkg/k8s/client/client.go +++ b/pkg/k8s/client/client.go @@ -31,6 +31,7 @@ import ( "github.com/instana/instana-agent-operator/pkg/multierror" "github.com/instana/instana-agent-operator/pkg/result" + corev1 "k8s.io/api/core/v1" k8sClient "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -52,6 +53,7 @@ type InstanaAgentClient interface { GetAsResult(ctx context.Context, key k8sClient.ObjectKey, obj k8sClient.Object, opts ...k8sClient.GetOption) result.Result[k8sClient.Object] Status() k8sClient.SubResourceWriter Patch(ctx context.Context, obj k8sClient.Object, patch k8sClient.Patch, opts ...k8sClient.PatchOption) error + ListNodes(ctx context.Context) (*corev1.NodeList, error) } type instanaAgentClient struct { @@ -216,3 +218,9 @@ func (c *instanaAgentClient) deleteAllInTimeLimit( return err } } + +func (c *instanaAgentClient) ListNodes(ctx context.Context) (*corev1.NodeList, error) { + nodeList := &corev1.NodeList{} + err := c.k8sClient.List(ctx, nodeList) + return nodeList, err +} diff --git a/pkg/k8s/object/builders/agent/serviceentry/serviceentry.go b/pkg/k8s/object/builders/agent/serviceentry/serviceentry.go new file mode 100644 index 00000000..4466d17e --- /dev/null +++ b/pkg/k8s/object/builders/agent/serviceentry/serviceentry.go @@ -0,0 +1,75 @@ +/* + * (c) Copyright IBM Corp. 2024 + * (c) Copyright Instana Inc. 2024 + */ + +package serviceentry + +import ( + "fmt" + "strings" + + instanav1 "github.com/instana/instana-agent-operator/api/v1" + "github.com/instana/instana-agent-operator/pkg/k8s/object/builders/common/builder" + "github.com/instana/instana-agent-operator/pkg/k8s/object/builders/common/constants" + "github.com/instana/instana-agent-operator/pkg/k8s/object/builders/common/helpers" + "github.com/instana/instana-agent-operator/pkg/optional" + networkingv1alpha3api "istio.io/api/networking/v1alpha3" + networkingv1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +const ( + componentName = constants.ComponentInstanaAgent + agentPort = constants.AgentPort +) + +type serviceEntryListBuilder struct { + *instanav1.InstanaAgent + helpers.Helpers + nodeIP string +} + +func (s *serviceEntryListBuilder) Build() builder.OptionalObject { + return optional.Of[client.Object]( + &networkingv1alpha3.ServiceEntry{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "networking.istio.io/v1alpha3", + Kind: "ServiceEntry", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("%s-worker-%s", componentName, s.nodeIP), + Namespace: s.Namespace, + }, + Spec: networkingv1alpha3api.ServiceEntry{ + Hosts: []string{fmt.Sprintf("%s.%s.%s.svc", s.nodeIP, s.HeadlessServiceName(), s.Namespace)}, + Ports: []*networkingv1alpha3api.ServicePort{ + { + Number: agentPort, + Protocol: "TCP", + Name: "agent", + }, + }, + Resolution: networkingv1alpha3api.ServiceEntry_DNS, + Location: networkingv1alpha3api.ServiceEntry_MESH_EXTERNAL, + }, + }, + ) +} + +func (s *serviceEntryListBuilder) ComponentName() string { + return componentName +} + +func (s *serviceEntryListBuilder) IsNamespaced() bool { + return true +} + +func NewServiceEntriesBuilder(agent *instanav1.InstanaAgent, nodeIP string) builder.ObjectBuilder { + return &serviceEntryListBuilder{ + InstanaAgent: agent, + Helpers: helpers.NewHelpers(agent), + nodeIP: strings.ReplaceAll(nodeIP, ".", "-"), + } +} diff --git a/pkg/k8s/object/builders/common/constants/constants.go b/pkg/k8s/object/builders/common/constants/constants.go index 03f69e65..40c64744 100644 --- a/pkg/k8s/object/builders/common/constants/constants.go +++ b/pkg/k8s/object/builders/common/constants/constants.go @@ -34,3 +34,7 @@ const ( DownloadKey = "downloadKey" BackendKey = "backend" ) + +const ( + AgentPort = 42699 +) diff --git a/pkg/k8s/object/builders/k8s-sensor/rbac/clusterrole.go b/pkg/k8s/object/builders/k8s-sensor/rbac/clusterrole.go index eaf1c42c..0febbf8e 100644 --- a/pkg/k8s/object/builders/k8s-sensor/rbac/clusterrole.go +++ b/pkg/k8s/object/builders/k8s-sensor/rbac/clusterrole.go @@ -1,3 +1,8 @@ +/* + * (c) Copyright IBM Corp. 2024 + * (c) Copyright Instana Inc. 2024 + */ + package rbac import (