diff --git a/api/v1/ytsaurus_types.go b/api/v1/ytsaurus_types.go index 402bdaac..ef61aa64 100644 --- a/api/v1/ytsaurus_types.go +++ b/api/v1/ytsaurus_types.go @@ -635,12 +635,11 @@ type YtsaurusSpec struct { ControllerAgents *ControllerAgentsSpec `json:"controllerAgents,omitempty"` TabletNodes []TabletNodesSpec `json:"tabletNodes,omitempty"` - StrawberryController *StrawberryControllerSpec `json:"strawberry,omitempty"` - DeprecatedChytController *StrawberryControllerSpec `json:"chyt,omitempty"` - QueryTrackers *QueryTrackerSpec `json:"queryTrackers,omitempty"` - Spyt *DeprecatedSpytSpec `json:"spyt,omitempty"` - YQLAgents *YQLAgentSpec `json:"yqlAgents,omitempty"` - QueueAgents *QueueAgentSpec `json:"queueAgents,omitempty"` + StrawberryController *StrawberryControllerSpec `json:"strawberry,omitempty"` + QueryTrackers *QueryTrackerSpec `json:"queryTrackers,omitempty"` + Spyt *DeprecatedSpytSpec `json:"spyt,omitempty"` + YQLAgents *YQLAgentSpec `json:"yqlAgents,omitempty"` + QueueAgents *QueueAgentSpec `json:"queueAgents,omitempty"` UI *UISpec `json:"ui,omitempty"` } diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index b62b75b1..00e8e1c2 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -1750,11 +1750,6 @@ func (in *YtsaurusSpec) DeepCopyInto(out *YtsaurusSpec) { *out = new(StrawberryControllerSpec) (*in).DeepCopyInto(*out) } - if in.DeprecatedChytController != nil { - in, out := &in.DeprecatedChytController, &out.DeprecatedChytController - *out = new(StrawberryControllerSpec) - (*in).DeepCopyInto(*out) - } if in.QueryTrackers != nil { in, out := &in.QueryTrackers, &out.QueryTrackers *out = new(QueryTrackerSpec) diff --git a/config/crd/bases/cluster.ytsaurus.tech_ytsaurus.yaml b/config/crd/bases/cluster.ytsaurus.tech_ytsaurus.yaml index a208558e..f149e426 100644 --- a/config/crd/bases/cluster.ytsaurus.tech_ytsaurus.yaml +++ b/config/crd/bases/cluster.ytsaurus.tech_ytsaurus.yaml @@ -98,83 +98,6 @@ spec: type: string type: object x-kubernetes-map-type: atomic - chyt: - properties: - image: - type: string - resources: - description: ResourceRequirements describes the compute resource - requirements. - properties: - claims: - description: Claims lists the names of resources, defined - in spec. - items: - description: ResourceClaim references one entry in PodSpec.ResourceClaims. - properties: - name: - description: Name must match the name of one entry in - pod.spec. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: Limits describes the maximum amount of compute - resources allowed. - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: Requests describes the minimum amount of compute - resources required. - type: object - type: object - tolerations: - items: - description: |- - The pod this Toleration is attached to tolerates any taint that matches - the trip - properties: - effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. - type: string - key: - description: Key is the taint key that the toleration applies - to. - type: string - operator: - description: Operator represents a key's relationship to - the value. - type: string - tolerationSeconds: - description: |- - TolerationSeconds represents the period of time the toleration (which must be - of - format: int64 - type: integer - value: - description: Value is the taint value the toleration matches - to. - type: string - type: object - type: array - type: object configOverrides: description: |- LocalObjectReference contains enough information to let you locate the diff --git a/controllers/component_manager.go b/controllers/component_manager.go index ef7dccb4..5f565fb4 100644 --- a/controllers/component_manager.go +++ b/controllers/component_manager.go @@ -126,7 +126,7 @@ func NewComponentManager( allComponents = append(allComponents, yqla) } - if (resource.Spec.DeprecatedChytController != nil || resource.Spec.StrawberryController != nil) && resource.Spec.Schedulers != nil { + if resource.Spec.StrawberryController != nil && resource.Spec.Schedulers != nil { strawberry := components.NewStrawberryController(cfgen, ytsaurus, m, s, dnds) allComponents = append(allComponents, strawberry) } diff --git a/controllers/remoteexecnodes_test.go b/controllers/remoteexecnodes_test.go index bfd7b3de..8b714c57 100644 --- a/controllers/remoteexecnodes_test.go +++ b/controllers/remoteexecnodes_test.go @@ -282,7 +282,7 @@ func buildExecNodePod(h *testutil.TestHelper) corev1.Pod { consts.YTComponentLabelName: strings.Join( []string{ remoteExecNodesName, - consts.YTComponentLabelExecNode, + consts.ComponentLabel(consts.ExecNodeType), }, "-", ), diff --git a/docs/api.md b/docs/api.md index b132869d..38a52acb 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1726,7 +1726,6 @@ _Appears in:_ | `controllerAgents` _[ControllerAgentsSpec](#controlleragentsspec)_ | | | | | `tabletNodes` _[TabletNodesSpec](#tabletnodesspec) array_ | | | | | `strawberry` _[StrawberryControllerSpec](#strawberrycontrollerspec)_ | | | | -| `chyt` _[StrawberryControllerSpec](#strawberrycontrollerspec)_ | | | | | `queryTrackers` _[QueryTrackerSpec](#querytrackerspec)_ | | | | | `spyt` _[DeprecatedSpytSpec](#deprecatedspytspec)_ | | | | | `yqlAgents` _[YQLAgentSpec](#yqlagentspec)_ | | | | diff --git a/pkg/components/chyt.go b/pkg/components/chyt.go index a75faa39..f527cd3e 100644 --- a/pkg/components/chyt.go +++ b/pkg/components/chyt.go @@ -34,11 +34,11 @@ func NewChyt( chyt *apiproxy.Chyt, ytsaurus *ytv1.Ytsaurus) *Chyt { l := labeller.Labeller{ - ObjectMeta: &chyt.GetResource().ObjectMeta, - APIProxy: chyt.APIProxy(), - ComponentLabel: fmt.Sprintf("ytsaurus-chyt-%s", chyt.GetResource().Name), - ComponentName: fmt.Sprintf("CHYT-%s", chyt.GetResource().Name), - Annotations: ytsaurus.Spec.ExtraPodAnnotations, + ObjectMeta: &chyt.GetResource().ObjectMeta, + APIProxy: chyt.APIProxy(), + ComponentType: consts.ChytType, + ComponentNamePart: chyt.GetResource().Name, + Annotations: ytsaurus.Spec.ExtraPodAnnotations, } return &Chyt{ diff --git a/pkg/components/component.go b/pkg/components/component.go index d6cecb48..c8dca94d 100644 --- a/pkg/components/component.go +++ b/pkg/components/component.go @@ -66,7 +66,7 @@ type baseComponent struct { // For example for master component name is "Master", // For data node name looks like "DataNode". func (c *baseComponent) GetName() string { - return c.labeller.ComponentName + return c.labeller.GetFullComponentName() } // localComponent is a base structs for components which have access to ytsaurus resource, @@ -99,7 +99,7 @@ func (c *localComponent) SetReadyCondition(status ComponentStatus) { ready = metav1.ConditionTrue } c.ytsaurus.SetStatusCondition(metav1.Condition{ - Type: fmt.Sprintf("%sReady", c.labeller.ComponentName), + Type: fmt.Sprintf("%sReady", c.labeller.GetFullComponentName()), Status: ready, Reason: string(status.SyncStatus), Message: status.Message, diff --git a/pkg/components/controller_agent.go b/pkg/components/controller_agent.go index ba102254..20216b84 100644 --- a/pkg/components/controller_agent.go +++ b/pkg/components/controller_agent.go @@ -23,10 +23,9 @@ type ControllerAgent struct { func NewControllerAgent(cfgen *ytconfig.Generator, ytsaurus *apiproxy.Ytsaurus, master Component) *ControllerAgent { resource := ytsaurus.GetResource() l := labeller.Labeller{ - ObjectMeta: &resource.ObjectMeta, - APIProxy: ytsaurus.APIProxy(), - ComponentLabel: consts.YTComponentLabelControllerAgent, - ComponentName: string(consts.ControllerAgentType), + ObjectMeta: &resource.ObjectMeta, + APIProxy: ytsaurus.APIProxy(), + ComponentType: consts.ControllerAgentType, } if resource.Spec.ControllerAgents.InstanceSpec.MonitoringPort == nil { diff --git a/pkg/components/data_node.go b/pkg/components/data_node.go index bd9a0245..8eb3046f 100644 --- a/pkg/components/data_node.go +++ b/pkg/components/data_node.go @@ -28,10 +28,10 @@ func NewDataNode( ) *DataNode { resource := ytsaurus.GetResource() l := labeller.Labeller{ - ObjectMeta: &resource.ObjectMeta, - APIProxy: ytsaurus.APIProxy(), - ComponentLabel: cfgen.FormatComponentStringWithDefault(consts.YTComponentLabelDataNode, spec.Name), - ComponentName: cfgen.FormatComponentStringWithDefault(string(consts.DataNodeType), spec.Name), + ObjectMeta: &resource.ObjectMeta, + APIProxy: ytsaurus.APIProxy(), + ComponentType: consts.DataNodeType, + ComponentNamePart: spec.Name, } if spec.InstanceSpec.MonitoringPort == nil { diff --git a/pkg/components/discovery.go b/pkg/components/discovery.go index e4415e2a..4b113105 100644 --- a/pkg/components/discovery.go +++ b/pkg/components/discovery.go @@ -22,10 +22,9 @@ type Discovery struct { func NewDiscovery(cfgen *ytconfig.Generator, ytsaurus *apiproxy.Ytsaurus) *Discovery { resource := ytsaurus.GetResource() l := labeller.Labeller{ - ObjectMeta: &resource.ObjectMeta, - APIProxy: ytsaurus.APIProxy(), - ComponentLabel: consts.YTComponentLabelDiscovery, - ComponentName: string(consts.DiscoveryType), + ObjectMeta: &resource.ObjectMeta, + APIProxy: ytsaurus.APIProxy(), + ComponentType: consts.DiscoveryType, } if resource.Spec.Discovery.InstanceSpec.MonitoringPort == nil { diff --git a/pkg/components/exec_node.go b/pkg/components/exec_node.go index e9be9b89..df7baf1a 100644 --- a/pkg/components/exec_node.go +++ b/pkg/components/exec_node.go @@ -27,10 +27,10 @@ func NewExecNode( ) *ExecNode { resource := ytsaurus.GetResource() l := labeller.Labeller{ - ObjectMeta: &resource.ObjectMeta, - APIProxy: ytsaurus.APIProxy(), - ComponentLabel: cfgen.FormatComponentStringWithDefault(consts.YTComponentLabelExecNode, spec.Name), - ComponentName: cfgen.FormatComponentStringWithDefault(string(consts.ExecNodeType), spec.Name), + ObjectMeta: &resource.ObjectMeta, + APIProxy: ytsaurus.APIProxy(), + ComponentType: consts.ExecNodeType, + ComponentNamePart: spec.Name, } if spec.InstanceSpec.MonitoringPort == nil { diff --git a/pkg/components/exec_node_remote.go b/pkg/components/exec_node_remote.go index 98583cbe..9611cd3e 100644 --- a/pkg/components/exec_node_remote.go +++ b/pkg/components/exec_node_remote.go @@ -26,10 +26,10 @@ func NewRemoteExecNodes( commonSpec ytv1.CommonSpec, ) *RemoteExecNode { l := labeller.Labeller{ - ObjectMeta: &nodes.ObjectMeta, - APIProxy: proxy, - ComponentLabel: cfgen.FormatComponentStringWithDefault(consts.YTComponentLabelExecNode, spec.Name), - ComponentName: cfgen.FormatComponentStringWithDefault(string(consts.ExecNodeType), spec.Name), + ObjectMeta: &nodes.ObjectMeta, + APIProxy: proxy, + ComponentType: consts.ExecNodeType, + ComponentNamePart: spec.Name, } if spec.InstanceSpec.MonitoringPort == nil { diff --git a/pkg/components/httpproxy.go b/pkg/components/httpproxy.go index 7ecb9027..8e9e1dff 100644 --- a/pkg/components/httpproxy.go +++ b/pkg/components/httpproxy.go @@ -34,10 +34,10 @@ func NewHTTPProxy( spec ytv1.HTTPProxiesSpec) *HttpProxy { resource := ytsaurus.GetResource() l := labeller.Labeller{ - ObjectMeta: &resource.ObjectMeta, - APIProxy: ytsaurus.APIProxy(), - ComponentLabel: cfgen.FormatComponentStringWithDefault(consts.YTComponentLabelHTTPProxy, spec.Role), - ComponentName: cfgen.FormatComponentStringWithDefault(string(consts.HttpProxyType), spec.Role), + ObjectMeta: &resource.ObjectMeta, + APIProxy: ytsaurus.APIProxy(), + ComponentType: consts.HttpProxyType, + ComponentNamePart: spec.Role, } if spec.InstanceSpec.MonitoringPort == nil { diff --git a/pkg/components/init_job.go b/pkg/components/init_job.go index 7f26cd0e..46d82176 100644 --- a/pkg/components/init_job.go +++ b/pkg/components/init_job.go @@ -64,7 +64,7 @@ func NewInitJob( apiProxy: apiProxy, conditionsManager: conditionsManager, imagePullSecrets: imagePullSecrets, - initCompletedCondition: fmt.Sprintf("%s%sInitJobCompleted", name, labeller.ComponentName), + initCompletedCondition: fmt.Sprintf("%s%sInitJobCompleted", name, labeller.GetFullComponentName()), image: image, initJob: resources.NewJob( labeller.GetInitJobName(name), @@ -76,7 +76,7 @@ func NewInitJob( fmt.Sprintf( "%s-%s-init-job-config", strings.ToLower(name), - labeller.ComponentLabel), + labeller.GetFullComponentLabel()), nil, map[string]ytconfig.GeneratorDescriptor{ configFileName: { @@ -158,7 +158,7 @@ func (j *InitJob) Sync(ctx context.Context, dry bool) (ComponentStatus, error) { } if !j.initJob.Completed() { - logger.Info("Init job is not completed for " + j.labeller.ComponentName) + logger.Info("Init job is not completed for " + j.labeller.GetFullComponentName()) return WaitingStatus(SyncStatusBlocked, fmt.Sprintf("%s completion", j.initJob.Name())), err } diff --git a/pkg/components/init_job_test.go b/pkg/components/init_job_test.go index f6ff99e2..aaa5aa07 100644 --- a/pkg/components/init_job_test.go +++ b/pkg/components/init_job_test.go @@ -80,8 +80,7 @@ func newTestJob(ytsaurus *apiproxy.Ytsaurus) *InitJob { Name: k8sName, Namespace: ytsaurus.GetResource().Namespace, }, - ComponentLabel: "ms", - ComponentName: k8sName, + ComponentType: consts.MasterType, }, ytsaurus.APIProxy(), ytsaurus, @@ -170,7 +169,7 @@ func TestJobScriptUpdateOnJobRestart(t *testing.T) { cmData := testutil.FetchConfigMapData( h, - "dummy-ms-init-job-config", + "dummy-yt-master-init-job-config", consts.InitClusterScriptFileName, ) require.Equal(t, scriptAfter, cmData) diff --git a/pkg/components/master.go b/pkg/components/master.go index acbba0ac..a4ebea4e 100644 --- a/pkg/components/master.go +++ b/pkg/components/master.go @@ -36,11 +36,10 @@ type Master struct { func NewMaster(cfgen *ytconfig.Generator, ytsaurus *apiproxy.Ytsaurus) *Master { resource := ytsaurus.GetResource() l := labeller.Labeller{ - ObjectMeta: &resource.ObjectMeta, - APIProxy: ytsaurus.APIProxy(), - ComponentLabel: consts.YTComponentLabelMaster, - ComponentName: string(consts.MasterType), - Annotations: resource.Spec.ExtraPodAnnotations, + ObjectMeta: &resource.ObjectMeta, + APIProxy: ytsaurus.APIProxy(), + ComponentType: consts.MasterType, + Annotations: resource.Spec.ExtraPodAnnotations, } if resource.Spec.PrimaryMasters.InstanceSpec.MonitoringPort == nil { diff --git a/pkg/components/master_caches.go b/pkg/components/master_caches.go index 2e041589..48101b25 100644 --- a/pkg/components/master_caches.go +++ b/pkg/components/master_caches.go @@ -23,11 +23,10 @@ type MasterCache struct { func NewMasterCache(cfgen *ytconfig.Generator, ytsaurus *apiproxy.Ytsaurus) *MasterCache { resource := ytsaurus.GetResource() l := labeller.Labeller{ - ObjectMeta: &resource.ObjectMeta, - APIProxy: ytsaurus.APIProxy(), - ComponentLabel: consts.YTComponentLabelMasterCache, - ComponentName: string(consts.MasterCacheType), - Annotations: resource.Spec.ExtraPodAnnotations, + ObjectMeta: &resource.ObjectMeta, + APIProxy: ytsaurus.APIProxy(), + ComponentType: consts.MasterCacheType, + Annotations: resource.Spec.ExtraPodAnnotations, } if resource.Spec.MasterCaches.InstanceSpec.MonitoringPort == nil { diff --git a/pkg/components/query_tracker.go b/pkg/components/query_tracker.go index 6884c6e1..7b5247fe 100644 --- a/pkg/components/query_tracker.go +++ b/pkg/components/query_tracker.go @@ -40,11 +40,10 @@ func NewQueryTracker( ) *QueryTracker { resource := ytsaurus.GetResource() l := labeller.Labeller{ - ObjectMeta: &resource.ObjectMeta, - APIProxy: ytsaurus.APIProxy(), - ComponentLabel: "yt-query-tracker", - ComponentName: string(consts.QueryTrackerType), - Annotations: resource.Spec.ExtraPodAnnotations, + ObjectMeta: &resource.ObjectMeta, + APIProxy: ytsaurus.APIProxy(), + ComponentType: consts.QueryTrackerType, + Annotations: resource.Spec.ExtraPodAnnotations, } if resource.Spec.QueryTrackers.InstanceSpec.MonitoringPort == nil { diff --git a/pkg/components/queue_agent.go b/pkg/components/queue_agent.go index f2cb36ef..9fffe130 100644 --- a/pkg/components/queue_agent.go +++ b/pkg/components/queue_agent.go @@ -42,11 +42,10 @@ func NewQueueAgent( ) *QueueAgent { resource := ytsaurus.GetResource() l := labeller.Labeller{ - ObjectMeta: &resource.ObjectMeta, - APIProxy: ytsaurus.APIProxy(), - ComponentLabel: "yt-queue-agent", - ComponentName: string(consts.QueueAgentType), - Annotations: resource.Spec.ExtraPodAnnotations, + ObjectMeta: &resource.ObjectMeta, + APIProxy: ytsaurus.APIProxy(), + ComponentType: consts.QueueAgentType, + Annotations: resource.Spec.ExtraPodAnnotations, } if resource.Spec.QueueAgents.InstanceSpec.MonitoringPort == nil { diff --git a/pkg/components/rpcproxy.go b/pkg/components/rpcproxy.go index 9959258c..b2b35aaf 100644 --- a/pkg/components/rpcproxy.go +++ b/pkg/components/rpcproxy.go @@ -33,10 +33,10 @@ func NewRPCProxy( spec ytv1.RPCProxiesSpec) *RpcProxy { resource := ytsaurus.GetResource() l := labeller.Labeller{ - ObjectMeta: &resource.ObjectMeta, - APIProxy: ytsaurus.APIProxy(), - ComponentLabel: cfgen.FormatComponentStringWithDefault(consts.YTComponentLabelRPCProxy, spec.Role), - ComponentName: cfgen.FormatComponentStringWithDefault(string(consts.RpcProxyType), spec.Role), + ObjectMeta: &resource.ObjectMeta, + APIProxy: ytsaurus.APIProxy(), + ComponentType: consts.RpcProxyType, + ComponentNamePart: spec.Role, } if spec.InstanceSpec.MonitoringPort == nil { diff --git a/pkg/components/scheduler.go b/pkg/components/scheduler.go index 55d9c9a1..18f0f092 100644 --- a/pkg/components/scheduler.go +++ b/pkg/components/scheduler.go @@ -38,11 +38,10 @@ func NewScheduler( execNodes, tabletNodes []Component) *Scheduler { resource := ytsaurus.GetResource() l := labeller.Labeller{ - ObjectMeta: &resource.ObjectMeta, - APIProxy: ytsaurus.APIProxy(), - ComponentLabel: consts.YTComponentLabelScheduler, - ComponentName: string(consts.SchedulerType), - Annotations: resource.Spec.ExtraPodAnnotations, + ObjectMeta: &resource.ObjectMeta, + APIProxy: ytsaurus.APIProxy(), + ComponentType: consts.SchedulerType, + Annotations: resource.Spec.ExtraPodAnnotations, } if resource.Spec.Schedulers.InstanceSpec.MonitoringPort == nil { diff --git a/pkg/components/spyt.go b/pkg/components/spyt.go index eb7cedcf..ebcbecf9 100644 --- a/pkg/components/spyt.go +++ b/pkg/components/spyt.go @@ -2,7 +2,6 @@ package components import ( "context" - "fmt" "strings" corev1 "k8s.io/api/core/v1" @@ -33,11 +32,11 @@ func NewSpyt( spyt *apiproxy.Spyt, ytsaurus *ytv1.Ytsaurus) *Spyt { l := labeller.Labeller{ - ObjectMeta: &spyt.GetResource().ObjectMeta, - APIProxy: spyt.APIProxy(), - ComponentLabel: fmt.Sprintf("ytsaurus-spyt-%s", spyt.GetResource().Name), - ComponentName: fmt.Sprintf("SPYT-%s", spyt.GetResource().Name), - Annotations: ytsaurus.Spec.ExtraPodAnnotations, + ObjectMeta: &spyt.GetResource().ObjectMeta, + APIProxy: spyt.APIProxy(), + ComponentType: consts.SpytType, + ComponentNamePart: spyt.GetResource().Name, + Annotations: ytsaurus.Spec.ExtraPodAnnotations, } return &Spyt{ diff --git a/pkg/components/strawberry_controller.go b/pkg/components/strawberry_controller.go index c7a29fc1..df5cdf88 100644 --- a/pkg/components/strawberry_controller.go +++ b/pkg/components/strawberry_controller.go @@ -32,14 +32,7 @@ type StrawberryController struct { name string } -func getControllerConfigFileName(name string) string { - if name == "chyt" { - return "chyt-controller.yson" - } else { - return "strawberry-controller.yson" - } -} - +const ControllerConfigFileName = "strawberry-controller.yson" const ChytInitClusterJobConfigFileName = "chyt-init-cluster.yson" func NewStrawberryController( @@ -51,27 +44,15 @@ func NewStrawberryController( resource := ytsaurus.GetResource() image := resource.Spec.CoreImage - name := "chyt" - componentName := "ChytController" - if resource.Spec.DeprecatedChytController != nil { - if resource.Spec.DeprecatedChytController.Image != nil { - image = *resource.Spec.DeprecatedChytController.Image - } - } - if resource.Spec.StrawberryController != nil { - name = "strawberry" - componentName = string(consts.StrawberryControllerType) - if resource.Spec.StrawberryController.Image != nil { - image = *resource.Spec.StrawberryController.Image - } + if resource.Spec.StrawberryController.Image != nil { + image = *resource.Spec.StrawberryController.Image } l := labeller.Labeller{ - ObjectMeta: &resource.ObjectMeta, - APIProxy: ytsaurus.APIProxy(), - ComponentLabel: fmt.Sprintf("yt-%s-controller", name), - ComponentName: componentName, - Annotations: resource.Spec.ExtraPodAnnotations, + ObjectMeta: &resource.ObjectMeta, + APIProxy: ytsaurus.APIProxy(), + ComponentType: consts.StrawberryControllerType, + Annotations: resource.Spec.ExtraPodAnnotations, } microservice := newMicroservice( @@ -80,13 +61,13 @@ func NewStrawberryController( image, 1, map[string]ytconfig.GeneratorDescriptor{ - getControllerConfigFileName(name): { + ControllerConfigFileName: { F: cfgen.GetStrawberryControllerConfig, Fmt: ytconfig.ConfigFormatYson, }, }, - fmt.Sprintf("%s-controller", name), - name, + "strawberry-controller", + "strawberry", resource.Spec.StrawberryController.Tolerations) return &StrawberryController{ @@ -115,7 +96,7 @@ func NewStrawberryController( l.GetSecretName(), &l, ytsaurus.APIProxy()), - name: name, + name: "strawberry", master: master, scheduler: scheduler, dataNodes: dataNodes, @@ -202,7 +183,7 @@ func (c *StrawberryController) syncComponents(ctx context.Context) (err error) { Command: []string{ "/usr/bin/chyt-controller", "--config-path", - path.Join(consts.ConfigMountPoint, getControllerConfigFileName(c.name)), + path.Join(consts.ConfigMountPoint, ControllerConfigFileName), "run", }, Ports: []corev1.ContainerPort{ diff --git a/pkg/components/tablet_node.go b/pkg/components/tablet_node.go index 5408e365..f0931f68 100644 --- a/pkg/components/tablet_node.go +++ b/pkg/components/tablet_node.go @@ -43,10 +43,10 @@ func NewTabletNode( ) *TabletNode { resource := ytsaurus.GetResource() l := labeller.Labeller{ - ObjectMeta: &resource.ObjectMeta, - APIProxy: ytsaurus.APIProxy(), - ComponentLabel: cfgen.FormatComponentStringWithDefault(consts.YTComponentLabelTabletNode, spec.Name), - ComponentName: cfgen.FormatComponentStringWithDefault(string(consts.TabletNodeType), spec.Name), + ObjectMeta: &resource.ObjectMeta, + APIProxy: ytsaurus.APIProxy(), + ComponentType: consts.TabletNodeType, + ComponentNamePart: spec.Name, } if spec.InstanceSpec.MonitoringPort == nil { diff --git a/pkg/components/tcpproxy.go b/pkg/components/tcpproxy.go index 462126ac..32640a92 100644 --- a/pkg/components/tcpproxy.go +++ b/pkg/components/tcpproxy.go @@ -32,10 +32,10 @@ func NewTCPProxy( spec ytv1.TCPProxiesSpec) *TcpProxy { resource := ytsaurus.GetResource() l := labeller.Labeller{ - ObjectMeta: &resource.ObjectMeta, - APIProxy: ytsaurus.APIProxy(), - ComponentLabel: cfgen.FormatComponentStringWithDefault(consts.YTComponentLabelTCPProxy, spec.Role), - ComponentName: cfgen.FormatComponentStringWithDefault(string(consts.TcpProxyType), spec.Role), + ObjectMeta: &resource.ObjectMeta, + APIProxy: ytsaurus.APIProxy(), + ComponentType: consts.TcpProxyType, + ComponentNamePart: spec.Role, } if spec.InstanceSpec.MonitoringPort == nil { diff --git a/pkg/components/ui.go b/pkg/components/ui.go index 0784f02c..d3809070 100644 --- a/pkg/components/ui.go +++ b/pkg/components/ui.go @@ -34,11 +34,10 @@ const UICustomConfigFileName = "common.js" func NewUI(cfgen *ytconfig.Generator, ytsaurus *apiproxy.Ytsaurus, master Component) *UI { resource := ytsaurus.GetResource() l := labeller.Labeller{ - ObjectMeta: &resource.ObjectMeta, - APIProxy: ytsaurus.APIProxy(), - ComponentLabel: consts.YTComponentLabelUI, - ComponentName: string(consts.UIType), - Annotations: resource.Spec.ExtraPodAnnotations, + ObjectMeta: &resource.ObjectMeta, + APIProxy: ytsaurus.APIProxy(), + ComponentType: consts.UIType, + Annotations: resource.Spec.ExtraPodAnnotations, } image := resource.Spec.UIImage if resource.Spec.UI.Image != nil { diff --git a/pkg/components/yql_agent.go b/pkg/components/yql_agent.go index 6b96653b..e88d65fd 100644 --- a/pkg/components/yql_agent.go +++ b/pkg/components/yql_agent.go @@ -29,11 +29,10 @@ type YqlAgent struct { func NewYQLAgent(cfgen *ytconfig.Generator, ytsaurus *apiproxy.Ytsaurus, master Component) *YqlAgent { resource := ytsaurus.GetResource() l := labeller.Labeller{ - ObjectMeta: &resource.ObjectMeta, - APIProxy: ytsaurus.APIProxy(), - ComponentLabel: consts.YTComponentLabelYqlAgent, - ComponentName: string(consts.YqlAgentType), - Annotations: resource.Spec.ExtraPodAnnotations, + ObjectMeta: &resource.ObjectMeta, + APIProxy: ytsaurus.APIProxy(), + ComponentType: consts.YqlAgentType, + Annotations: resource.Spec.ExtraPodAnnotations, } if resource.Spec.YQLAgents.InstanceSpec.MonitoringPort == nil { @@ -85,7 +84,7 @@ func (yqla *YqlAgent) IsUpdatable() bool { func (yqla *YqlAgent) GetType() consts.ComponentType { return consts.YqlAgentType } func (yqla *YqlAgent) GetName() string { - return yqla.labeller.ComponentName + return yqla.labeller.GetFullComponentName() } func (yqla *YqlAgent) Fetch(ctx context.Context) error { diff --git a/pkg/components/ytsaurus_client.go b/pkg/components/ytsaurus_client.go index 30f8c5b3..ebc7309a 100644 --- a/pkg/components/ytsaurus_client.go +++ b/pkg/components/ytsaurus_client.go @@ -45,11 +45,10 @@ func NewYtsaurusClient( ) *YtsaurusClient { resource := ytsaurus.GetResource() l := labeller.Labeller{ - ObjectMeta: &resource.ObjectMeta, - APIProxy: ytsaurus.APIProxy(), - ComponentLabel: consts.YTComponentLabelClient, - ComponentName: string(consts.YtsaurusClientType), - Annotations: resource.Spec.ExtraPodAnnotations, + ObjectMeta: &resource.ObjectMeta, + APIProxy: ytsaurus.APIProxy(), + ComponentType: consts.YtsaurusClientType, + Annotations: resource.Spec.ExtraPodAnnotations, } return &YtsaurusClient{ diff --git a/pkg/consts/labels.go b/pkg/consts/labels.go index f3f03689..578eb439 100644 --- a/pkg/consts/labels.go +++ b/pkg/consts/labels.go @@ -1,21 +1,63 @@ package consts +import ( + "fmt" +) + +const YTClusterLabelName = "ytsaurus.tech/cluster-name" const YTComponentLabelName = "yt_component" const YTMetricsLabelName = "yt_metrics" -const ( - YTComponentLabelDiscovery string = "yt-discovery" - YTComponentLabelMaster string = "yt-master" - YTComponentLabelScheduler string = "yt-scheduler" - YTComponentLabelControllerAgent string = "yt-controller-agent" - YTComponentLabelDataNode string = "yt-data-node" - YTComponentLabelExecNode string = "yt-exec-node" - YTComponentLabelTabletNode string = "yt-tablet-node" - YTComponentLabelHTTPProxy string = "yt-http-proxy" - YTComponentLabelRPCProxy string = "yt-rpc-proxy" - YTComponentLabelTCPProxy string = "yt-tcp-proxy" - YTComponentLabelUI string = "yt-ui" - YTComponentLabelYqlAgent string = "yt-yql-agent" - YTComponentLabelClient string = "yt-client" - YTComponentLabelMasterCache string = "yt-master-cache" -) +func ComponentLabel(component ComponentType) string { + // TODO(achulkov2): We should probably use `ytsaurus` instead of `yt` everywhere, but + // it will be an inconvenient change that requires all statefulsets to be recreated. + switch component { + case MasterType: + return "yt-master" + case MasterCacheType: + return "yt-master-cache" + case DiscoveryType: + return "yt-discovery" + case SchedulerType: + return "yt-scheduler" + case ControllerAgentType: + return "yt-controller-agent" + case DataNodeType: + return "yt-data-node" + case ExecNodeType: + return "yt-exec-node" + case TabletNodeType: + return "yt-tablet-node" + case HttpProxyType: + return "yt-http-proxy" + case RpcProxyType: + return "yt-rpc-proxy" + case TcpProxyType: + return "yt-tcp-proxy" + case QueueAgentType: + return "yt-queue-agent" + case QueryTrackerType: + return "yt-query-tracker" + case YqlAgentType: + return "yt-yql-agent" + case StrawberryControllerType: + return "yt-strawberry-controller" + case ChytType: + return "yt-chyt" + case SpytType: + return "yt-spyt" + case YtsaurusClientType: + return "yt-client" + case UIType: + return "yt-ui" + } + + panic(fmt.Sprintf("Unknown component type: %s", component)) +} + +func FormatComponentStringWithDefault(base string, name string) string { + if name != DefaultName { + return fmt.Sprintf("%s-%s", base, name) + } + return base +} diff --git a/pkg/consts/types.go b/pkg/consts/types.go index 3acff6f0..702a8e00 100644 --- a/pkg/consts/types.go +++ b/pkg/consts/types.go @@ -20,4 +20,6 @@ const ( UIType ComponentType = "UI" YqlAgentType ComponentType = "YqlAgent" YtsaurusClientType ComponentType = "YtsaurusClient" + ChytType ComponentType = "CHYT" + SpytType ComponentType = "SPYT" ) diff --git a/pkg/labeller/labeller.go b/pkg/labeller/labeller.go index 9c979e16..39bc74ab 100644 --- a/pkg/labeller/labeller.go +++ b/pkg/labeller/labeller.go @@ -16,35 +16,65 @@ type FetchableObject struct { } type Labeller struct { - APIProxy apiproxy.APIProxy - ObjectMeta *metav1.ObjectMeta - ComponentLabel string - ComponentName string - Annotations map[string]string + APIProxy apiproxy.APIProxy + ObjectMeta *metav1.ObjectMeta + ComponentType consts.ComponentType + // An optional name identifying a group of instances of the type above. + // Role for proxies, instance group name for nodes, may be empty. + ComponentNamePart string + Annotations map[string]string } func (l *Labeller) GetClusterName() string { return l.ObjectMeta.Name } +// GetComponentName Returns CamelCase component type without name part. +func (l *Labeller) GetComponentName() string { + return string(l.ComponentType) +} + +// GetFullComponentName Returns CamelCase component type with name part. +func (l *Labeller) GetFullComponentName() string { + if l.ComponentNamePart != "" { + return consts.FormatComponentStringWithDefault(l.GetComponentName(), l.ComponentNamePart) + } + + return l.GetComponentName() +} + +// GetComponentLabel Returns lower case hyphenated component type without name part. +func (l *Labeller) GetComponentLabel() string { + return consts.ComponentLabel(l.ComponentType) +} + +// GetFullComponentLabel Returns lower case hyphenated component type with name part. +func (l *Labeller) GetFullComponentLabel() string { + if l.ComponentNamePart != "" { + return consts.FormatComponentStringWithDefault(l.GetComponentLabel(), l.ComponentNamePart) + } + + return l.GetComponentLabel() +} + func (l *Labeller) GetSecretName() string { - return fmt.Sprintf("%s-secret", l.ComponentLabel) + return fmt.Sprintf("%s-secret", l.GetFullComponentLabel()) } func (l *Labeller) GetMainConfigMapName() string { - return fmt.Sprintf("%s-config", l.ComponentLabel) + return fmt.Sprintf("%s-config", l.GetFullComponentLabel()) } func (l *Labeller) GetSidecarConfigMapName(name string) string { - return fmt.Sprintf("%s-%s-config", l.ComponentLabel, name) + return fmt.Sprintf("%s-%s-config", l.GetFullComponentLabel(), name) } func (l *Labeller) GetInitJobName(name string) string { - return fmt.Sprintf("%s-init-job-%s", l.ComponentLabel, strings.ToLower(name)) + return fmt.Sprintf("%s-init-job-%s", l.GetFullComponentLabel(), strings.ToLower(name)) } func (l *Labeller) GetPodsRemovingStartedCondition() string { - return fmt.Sprintf("%sPodsRemovingStarted", l.ComponentName) + return fmt.Sprintf("%sPodsRemovingStarted", l.GetFullComponentName()) } func (l *Labeller) GetObjectMeta(name string) metav1.ObjectMeta { @@ -65,17 +95,29 @@ func (l *Labeller) GetInitJobObjectMeta() metav1.ObjectMeta { } } -func (l *Labeller) GetYTLabelValue(isInitJob bool) string { - result := fmt.Sprintf("%s-%s", l.ObjectMeta.Name, l.ComponentLabel) +func (l *Labeller) GetInstanceLabelValue(isInitJob bool) string { + result := fmt.Sprintf("%s-%s", l.GetClusterName(), l.GetFullComponentLabel()) if isInitJob { result = fmt.Sprintf("%s-%s", result, "init-job") } return result } +func (l *Labeller) GetComponentTypeLabelValue(isInitJob bool) string { + if isInitJob { + return fmt.Sprintf("%s-%s", l.GetComponentLabel(), "init-job") + } + return l.GetComponentLabel() +} + +func (l *Labeller) GetPartOfLabelValue() string { + // TODO(achulkov2): Change this from `yt` to `ytsaurus` at the same time as all other label values. + return fmt.Sprintf("yt-%s", l.GetClusterName()) +} + func (l *Labeller) GetSelectorLabelMap() map[string]string { return map[string]string{ - consts.YTComponentLabelName: l.GetYTLabelValue(false), + consts.YTComponentLabelName: l.GetInstanceLabelValue(false), } } @@ -88,11 +130,26 @@ func (l *Labeller) GetListOptions() []client.ListOption { func (l *Labeller) GetMetaLabelMap(isInitJob bool) map[string]string { return map[string]string{ - "app.kubernetes.io/name": "Ytsaurus", - "app.kubernetes.io/instance": l.ObjectMeta.Name, - "app.kubernetes.io/component": l.ComponentLabel, - "app.kubernetes.io/managed-by": "Ytsaurus-k8s-operator", - consts.YTComponentLabelName: l.GetYTLabelValue(isInitJob), + // This is supposed to be the name of the application. It makes + // sense to separate init jobs from the main components. It does + // not contain the name of the instance group for easier monitoring + // configuration. + // Template: yt-[-init-job]. + "app.kubernetes.io/name": l.GetComponentTypeLabelValue(isInitJob), + // Template: yt--. + "app.kubernetes.io/component": l.GetFullComponentLabel(), + // This is supposed to be the name of a higher level application + // that this app is part of: yt-. + "app.kubernetes.io/part-of": l.GetPartOfLabelValue(), + // Uppercase looks awful, even though it is more typical for k8s. + "app.kubernetes.io/managed-by": "ytsaurus-k8s-operator", + // It is nice to have the cluster name as a label. + // Template: . + consts.YTClusterLabelName: l.GetClusterName(), + // This label is used to check pods for readiness during updates. + // The name isn't quite right, but we keep it for backwards compatibility. + // Template: -yt--[-init-job]. + consts.YTComponentLabelName: l.GetInstanceLabelValue(isInitJob), } } diff --git a/pkg/resources/monitoring_service.go b/pkg/resources/monitoring_service.go index 3592a4d6..27909419 100644 --- a/pkg/resources/monitoring_service.go +++ b/pkg/resources/monitoring_service.go @@ -26,7 +26,7 @@ type MonitoringService struct { func NewMonitoringService(monitoringTargetPort int32, labeller *labeller2.Labeller, apiProxy apiproxy.APIProxy) *MonitoringService { return &MonitoringService{ - name: fmt.Sprintf("%s-monitoring", labeller.ComponentLabel), + name: fmt.Sprintf("%s-monitoring", labeller.GetFullComponentLabel()), labeller: labeller, apiProxy: apiProxy, monitoringTargetPort: monitoringTargetPort, diff --git a/pkg/resources/statefulset.go b/pkg/resources/statefulset.go index 13b03740..e01d6535 100644 --- a/pkg/resources/statefulset.go +++ b/pkg/resources/statefulset.go @@ -78,7 +78,7 @@ func (s *StatefulSet) getPods(ctx context.Context) *corev1.PodList { podList := &corev1.PodList{} err := s.proxy.ListObjects(ctx, podList, s.labeller.GetListOptions()...) if err != nil { - logger.Error(err, "unable to list pods for component", "component", s.labeller.ComponentName) + logger.Error(err, "unable to list pods for component", "component", s.labeller.GetFullComponentName()) return nil } @@ -94,7 +94,7 @@ func (s *StatefulSet) ArePodsRemoved(ctx context.Context) bool { } podsCount := len(podList.Items) if podsCount != 0 { - logger.Info("there are pods", "podsCount", podsCount, "component", s.labeller.ComponentName) + logger.Info("there are pods", "podsCount", podsCount, "component", s.labeller.GetFullComponentName()) return false } return true @@ -124,7 +124,7 @@ func (s *StatefulSet) ArePodsReady(ctx context.Context, minReadyInstanceCount *i if readyInstanceCount < effectiveMinReadyInstanceCount { logger.Info( "not enough pods are running", - "component", s.labeller.ComponentName, + "component", s.labeller.GetFullComponentName(), "readyInstanceCount", readyInstanceCount, "minReadyInstanceCount", effectiveMinReadyInstanceCount, "totalInstanceCount", len(podList.Items)) diff --git a/pkg/testutil/spec_builders.go b/pkg/testutil/spec_builders.go index c40f7e95..edef2150 100644 --- a/pkg/testutil/spec_builders.go +++ b/pkg/testutil/spec_builders.go @@ -123,15 +123,21 @@ func CreateBaseYtsaurusResource(namespace string) *ytv1.Ytsaurus { // TODO (l0kix2): merge with ytconfig build spec helpers. func WithDataNodes(ytsaurus *ytv1.Ytsaurus) *ytv1.Ytsaurus { - return WithDataNodesCount(ytsaurus, 3) + return WithDataNodesCount(ytsaurus, 3, nil) } -func WithDataNodesCount(ytsaurus *ytv1.Ytsaurus, count int) *ytv1.Ytsaurus { - ytsaurus.Spec.DataNodes = []ytv1.DataNodesSpec{ - { - InstanceSpec: CreateDataNodeInstanceSpec(count), - }, +func WithNamedDataNodes(ytsaurus *ytv1.Ytsaurus, name *string) *ytv1.Ytsaurus { + return WithDataNodesCount(ytsaurus, 3, name) +} + +func WithDataNodesCount(ytsaurus *ytv1.Ytsaurus, count int, name *string) *ytv1.Ytsaurus { + dataNodeSpec := ytv1.DataNodesSpec{ + InstanceSpec: CreateDataNodeInstanceSpec(count), + } + if name != nil { + dataNodeSpec.Name = *name } + ytsaurus.Spec.DataNodes = append(ytsaurus.Spec.DataNodes, dataNodeSpec) return ytsaurus } diff --git a/pkg/ytconfig/names.go b/pkg/ytconfig/names.go index 3f54ee1e..c6a000e1 100644 --- a/pkg/ytconfig/names.go +++ b/pkg/ytconfig/names.go @@ -102,15 +102,15 @@ func (g *Generator) GetStrawberryControllerHeadlessServiceName() string { } func (g *Generator) GetHTTPProxiesServiceName(role string) string { - return g.getName(fmt.Sprintf("%s-lb", g.FormatComponentStringWithDefault("http-proxies", role))) + return g.getName(fmt.Sprintf("%s-lb", consts.FormatComponentStringWithDefault("http-proxies", role))) } func (g *Generator) GetHTTPProxiesHeadlessServiceName(role string) string { - return g.getName(g.FormatComponentStringWithDefault("http-proxies", role)) + return g.getName(consts.FormatComponentStringWithDefault("http-proxies", role)) } func (g *Generator) GetHTTPProxiesStatefulSetName(role string) string { - return g.getName(g.FormatComponentStringWithDefault("hp", role)) + return g.getName(consts.FormatComponentStringWithDefault("hp", role)) } func (g *Generator) GetHTTPProxiesAddress(role string) string { @@ -129,27 +129,27 @@ func (g *Generator) GetSchedulerServiceName() string { } func (g *Generator) GetRPCProxiesStatefulSetName(role string) string { - return g.getName(g.FormatComponentStringWithDefault("rp", role)) + return g.getName(consts.FormatComponentStringWithDefault("rp", role)) } func (g *Generator) GetRPCProxiesServiceName(role string) string { - return g.getName(fmt.Sprintf("%s-lb", g.FormatComponentStringWithDefault("rpc-proxies", role))) + return g.getName(fmt.Sprintf("%s-lb", consts.FormatComponentStringWithDefault("rpc-proxies", role))) } func (g *Generator) GetRPCProxiesHeadlessServiceName(role string) string { - return g.getName(g.FormatComponentStringWithDefault("rpc-proxies", role)) + return g.getName(consts.FormatComponentStringWithDefault("rpc-proxies", role)) } func (g *Generator) GetTCPProxiesStatefulSetName(role string) string { - return g.getName(g.FormatComponentStringWithDefault("tp", role)) + return g.getName(consts.FormatComponentStringWithDefault("tp", role)) } func (g *Generator) GetTCPProxiesServiceName(role string) string { - return g.getName(fmt.Sprintf("%s-lb", g.FormatComponentStringWithDefault("tcp-proxies", role))) + return g.getName(fmt.Sprintf("%s-lb", consts.FormatComponentStringWithDefault("tcp-proxies", role))) } func (g *Generator) GetTCPProxiesHeadlessServiceName(role string) string { - return g.getName(g.FormatComponentStringWithDefault("tcp-proxies", role)) + return g.getName(consts.FormatComponentStringWithDefault("tcp-proxies", role)) } func (g *Generator) GetQueryTrackerStatefulSetName() string { @@ -169,34 +169,27 @@ func (g *Generator) GetQueueAgentServiceName() string { } func (g *NodeGenerator) GetDataNodesStatefulSetName(name string) string { - return g.getName(g.FormatComponentStringWithDefault("dnd", name)) + return g.getName(consts.FormatComponentStringWithDefault("dnd", name)) } func (g *NodeGenerator) GetDataNodesServiceName(name string) string { - return g.getName(g.FormatComponentStringWithDefault("data-nodes", name)) + return g.getName(consts.FormatComponentStringWithDefault("data-nodes", name)) } func (g *NodeGenerator) GetExecNodesStatefulSetName(name string) string { - return g.getName(g.FormatComponentStringWithDefault("end", name)) + return g.getName(consts.FormatComponentStringWithDefault("end", name)) } func (g *NodeGenerator) GetExecNodesServiceName(name string) string { - return g.getName(g.FormatComponentStringWithDefault("exec-nodes", name)) + return g.getName(consts.FormatComponentStringWithDefault("exec-nodes", name)) } func (g *NodeGenerator) GetTabletNodesStatefulSetName(name string) string { - return g.getName(g.FormatComponentStringWithDefault("tnd", name)) + return g.getName(consts.FormatComponentStringWithDefault("tnd", name)) } func (g *NodeGenerator) GetTabletNodesServiceName(name string) string { - return g.getName(g.FormatComponentStringWithDefault("tablet-nodes", name)) -} - -func (g *BaseGenerator) FormatComponentStringWithDefault(base string, name string) string { - if name != consts.DefaultName { - return fmt.Sprintf("%s-%s", base, name) - } - return base + return g.getName(consts.FormatComponentStringWithDefault("tablet-nodes", name)) } func (g *BaseGenerator) GetMasterCachesStatefulSetName() string { diff --git a/test/e2e/helpers_test.go b/test/e2e/helpers_test.go index ad83b7a7..019b9112 100644 --- a/test/e2e/helpers_test.go +++ b/test/e2e/helpers_test.go @@ -32,6 +32,13 @@ func getComponentPods(ctx context.Context, namespace string) map[string]corev1.P return result } +func getAllPods(ctx context.Context, namespace string) []corev1.Pod { + podList := corev1.PodList{} + err := k8sClient.List(ctx, &podList, ctrlcli.InNamespace(namespace)) + Expect(err).Should(Succeed()) + return podList.Items +} + type StringSet mapset.Set[string] func NewStringSet() StringSet { diff --git a/test/e2e/ytsaurus_controller_test.go b/test/e2e/ytsaurus_controller_test.go index 27bf306c..5352e659 100644 --- a/test/e2e/ytsaurus_controller_test.go +++ b/test/e2e/ytsaurus_controller_test.go @@ -11,6 +11,8 @@ import ( "sort" "time" + "k8s.io/utils/ptr" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "go.ytsaurus.tech/yt/go/mapreduce" @@ -163,9 +165,10 @@ func runYtsaurus(ytsaurus *ytv1.Ytsaurus) { if ytsaurus.Spec.Discovery.InstanceCount != 0 { pods = append(pods, "ds-0") } - if len(ytsaurus.Spec.DataNodes) != 0 { - pods = append(pods, "dnd-0") + for _, dataNodeGroup := range ytsaurus.Spec.DataNodes { + pods = append(pods, fmt.Sprintf("%v-0", consts.FormatComponentStringWithDefault("dnd", dataNodeGroup.Name))) } + if len(ytsaurus.Spec.ExecNodes) != 0 { pods = append(pods, "end-0") } @@ -923,6 +926,67 @@ func checkClusterViability(ytClient yt.Client) { Expect(hasPermission.Action).Should(Equal(yt.ActionDeny)) } +func checkPodLabelCount(pods []corev1.Pod, labelKey string, labelValue string, expectedCount int) { + podCount := 0 + for _, pod := range pods { + if pod.Labels[labelKey] == labelValue { + podCount++ + } + } + Expect(podCount).Should(Equal(expectedCount)) +} + +func checkPodLabels(ctx context.Context, namespace string) { + cluster := testutil.YtsaurusName + pods := getAllPods(ctx, namespace) + + for _, pod := range pods { + fmt.Fprintf(GinkgoWriter, "PodName: %v, Labels: %v\n", pod.Name, pod.ObjectMeta.Labels) + } + + Expect(pods).Should(ContainElement(And( + HaveField("Name", "dnd-0"), + HaveField("Labels", And( + HaveKeyWithValue("app.kubernetes.io/name", "yt-data-node"), + HaveKeyWithValue("app.kubernetes.io/component", "yt-data-node"), + HaveKeyWithValue("yt_component", fmt.Sprintf("%v-yt-data-node", cluster)), + HaveKeyWithValue("app.kubernetes.io/managed-by", "ytsaurus-k8s-operator"), + HaveKeyWithValue("app.kubernetes.io/part-of", fmt.Sprintf("yt-%v", cluster)), + HaveKeyWithValue("ytsaurus.tech/cluster-name", cluster), + )), + ))) + Expect(pods).Should(ContainElement(And( + HaveField("Name", "dnd-dn-t-1"), + HaveField("Labels", And( + HaveKeyWithValue("app.kubernetes.io/name", "yt-data-node"), + HaveKeyWithValue("app.kubernetes.io/component", "yt-data-node-dn-t"), + HaveKeyWithValue("yt_component", fmt.Sprintf("%v-yt-data-node-dn-t", cluster)), + HaveKeyWithValue("app.kubernetes.io/managed-by", "ytsaurus-k8s-operator"), + HaveKeyWithValue("app.kubernetes.io/part-of", fmt.Sprintf("yt-%v", cluster)), + HaveKeyWithValue("ytsaurus.tech/cluster-name", cluster), + )), + ))) + checkPodLabelCount(pods, "app.kubernetes.io/name", "yt-data-node", 6) + checkPodLabelCount(pods, "app.kubernetes.io/component", "yt-data-node", 3) + checkPodLabelCount(pods, "app.kubernetes.io/component", "yt-data-node-dn-t", 3) + + Expect(pods).Should(ContainElement(And( + HaveField("Name", "ms-0"), + HaveField("Labels", And( + HaveKeyWithValue("app.kubernetes.io/name", "yt-master"), + HaveKeyWithValue("app.kubernetes.io/component", "yt-master"), + HaveKeyWithValue("yt_component", fmt.Sprintf("%v-yt-master", cluster)), + HaveKeyWithValue("app.kubernetes.io/managed-by", "ytsaurus-k8s-operator"), + HaveKeyWithValue("app.kubernetes.io/part-of", fmt.Sprintf("yt-%v", cluster)), + HaveKeyWithValue("ytsaurus.tech/cluster-name", cluster), + )), + ))) + checkPodLabelCount(pods, "app.kubernetes.io/name", "yt-master", 1) + + // Init jobs have their own suffixes. + checkPodLabelCount(pods, "app.kubernetes.io/name", "yt-scheduler", 1) +} + func deployAndCheck(ytsaurus *ytv1.Ytsaurus, namespace string) { runYtsaurus(ytsaurus) @@ -940,6 +1004,7 @@ func getSimpleUpdateScenario(namespace, newImage string) func(ctx context.Contex return func(ctx context.Context) { By("Creating a Ytsaurus resource") ytsaurus := testutil.CreateBaseYtsaurusResource(namespace) + testutil.WithNamedDataNodes(ytsaurus, ptr.To("dn-t")) DeferCleanup(deleteYtsaurus, ytsaurus) name := types.NamespacedName{Name: ytsaurus.GetName(), Namespace: namespace} deployAndCheck(ytsaurus, namespace) @@ -947,6 +1012,9 @@ func getSimpleUpdateScenario(namespace, newImage string) func(ctx context.Contex By("Run cluster update") podsBeforeUpdate := getComponentPods(ctx, namespace) Expect(k8sClient.Get(ctx, name, ytsaurus)).Should(Succeed()) + + checkPodLabels(ctx, namespace) + ytsaurus.Spec.CoreImage = newImage Expect(k8sClient.Update(ctx, ytsaurus)).Should(Succeed()) EventuallyYtsaurus(ctx, name, reactionTimeout).Should(HaveClusterState(ytv1.ClusterStateUpdating)) diff --git a/ytop-chart/templates/crds/ytsaurus.cluster.ytsaurus.tech.yaml b/ytop-chart/templates/crds/ytsaurus.cluster.ytsaurus.tech.yaml index 42de1e31..3c80cbf4 100644 --- a/ytop-chart/templates/crds/ytsaurus.cluster.ytsaurus.tech.yaml +++ b/ytop-chart/templates/crds/ytsaurus.cluster.ytsaurus.tech.yaml @@ -109,83 +109,6 @@ spec: type: string type: object x-kubernetes-map-type: atomic - chyt: - properties: - image: - type: string - resources: - description: ResourceRequirements describes the compute resource - requirements. - properties: - claims: - description: Claims lists the names of resources, defined - in spec. - items: - description: ResourceClaim references one entry in PodSpec.ResourceClaims. - properties: - name: - description: Name must match the name of one entry in - pod.spec. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: Limits describes the maximum amount of compute - resources allowed. - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: Requests describes the minimum amount of compute - resources required. - type: object - type: object - tolerations: - items: - description: |- - The pod this Toleration is attached to tolerates any taint that matches - the trip - properties: - effect: - description: Effect indicates the taint effect to match. - Empty means match all taint effects. - type: string - key: - description: Key is the taint key that the toleration applies - to. - type: string - operator: - description: Operator represents a key's relationship to - the value. - type: string - tolerationSeconds: - description: |- - TolerationSeconds represents the period of time the toleration (which must be - of - format: int64 - type: integer - value: - description: Value is the taint value the toleration matches - to. - type: string - type: object - type: array - type: object configOverrides: description: |- LocalObjectReference contains enough information to let you locate the