kubesphere.io/api@v0.0.0-20231107125330-c9a03957060c/alerting/v2beta1/rulegroup_types.go (about) 1 /* 2 Copyright 2020 KubeSphere 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 v2beta1 18 19 import ( 20 "fmt" 21 "strings" 22 23 "github.com/prometheus/prometheus/model/labels" 24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 "k8s.io/apimachinery/pkg/util/intstr" 26 ) 27 28 const ( 29 ResourceKindRuleGroup = "RuleGroup" 30 ResourceKindClusterRuleGroup = "ClusterRuleGroup" 31 ResourceKindGlobalRuleGroup = "GlobalRuleGroup" 32 ) 33 34 // Duration is a valid time unit 35 // Supported units: y, w, d, h, m, s, ms Examples: `30s`, `1m`, `1h20m15s` 36 // +kubebuilder:validation:Pattern:="^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$" 37 type Duration string 38 39 type Comparator string 40 41 type Severity string 42 43 type MatchType string 44 45 const ( 46 ComparatorLT Comparator = "<" 47 ComparatorLE Comparator = "<=" 48 ComparatorGT Comparator = ">" 49 ComparatorGE Comparator = ">=" 50 51 SeverityWarning Severity = "warning" 52 SeverityError Severity = "error" 53 SeverityCritical Severity = "critical" 54 55 MatchEqual = "=" 56 MatchNotEqual = "!=" 57 MatchRegexp = "=~" 58 MatchNotRegexp = "!~" 59 ) 60 61 type Rule struct { 62 Alert string `json:"alert"` 63 64 Expr intstr.IntOrString `json:"expr,omitempty"` 65 66 For Duration `json:"for,omitempty"` 67 Severity Severity `json:"severity,omitempty"` 68 69 Labels map[string]string `json:"labels,omitempty"` 70 Annotations map[string]string `json:"annotations,omitempty"` 71 72 Disable bool `json:"disable,omitempty"` 73 } 74 75 type NamespaceRule struct { 76 Rule `json:",inline"` 77 // If ExprBuilder is not nil, the configured Expr will be ignored 78 ExprBuilder *NamespaceRuleExprBuilder `json:"exprBuilder,omitempty"` 79 } 80 81 type ClusterRule struct { 82 Rule `json:",inline"` 83 // If ExprBuilder is not nil, the configured Expr will be ignored 84 ExprBuilder *ClusterRuleExprBuilder `json:"exprBuilder,omitempty"` 85 } 86 87 type GlobalRule struct { 88 ClusterSelector *MetricLabelSelector `json:"clusterSelector,omitempty"` 89 NamespaceSelector *MetricLabelSelector `json:"namespaceSelector,omitempty"` 90 Rule `json:",inline"` 91 // If ExprBuilder is not nil, the configured Expr will be ignored 92 ExprBuilder *GlobalRuleExprBuilder `json:"exprBuilder,omitempty"` 93 } 94 95 // Only one of its members may be specified. 96 type MetricLabelSelector struct { 97 InValues []string `json:"inValues,omitempty"` 98 Matcher *Matcher `json:"matcher,omitempty"` 99 } 100 101 func (s *MetricLabelSelector) ParseToMatcher(labelName string) *labels.Matcher { 102 if s == nil { 103 return nil 104 } 105 if len(s.InValues) == 1 { 106 return &labels.Matcher{ 107 Type: labels.MatchEqual, 108 Name: labelName, 109 Value: s.InValues[0], 110 } 111 } 112 if len(s.InValues) > 1 { 113 return &labels.Matcher{ 114 Type: labels.MatchRegexp, 115 Name: labelName, 116 Value: fmt.Sprintf("(%s)", strings.Join(s.InValues, "|")), 117 } 118 } 119 if s.Matcher != nil { 120 var mtype labels.MatchType 121 switch s.Matcher.Type { 122 case MatchEqual: 123 mtype = labels.MatchEqual 124 case MatchNotEqual: 125 mtype = labels.MatchNotEqual 126 case MatchRegexp: 127 mtype = labels.MatchRegexp 128 case MatchNotRegexp: 129 mtype = labels.MatchNotRegexp 130 default: 131 return nil 132 } 133 return &labels.Matcher{ 134 Type: mtype, 135 Name: labelName, 136 Value: s.Matcher.Value, 137 } 138 } 139 return nil 140 } 141 142 func (s *MetricLabelSelector) Validate() error { 143 if s.Matcher != nil { 144 return s.Matcher.Validate() 145 } 146 return nil 147 } 148 149 type Matcher struct { 150 Type MatchType `json:"type"` 151 Value string `json:"value,omitempty"` 152 } 153 154 func (m *Matcher) Validate() error { 155 var mtype labels.MatchType 156 switch m.Type { 157 case MatchEqual: 158 mtype = labels.MatchEqual 159 case MatchNotEqual: 160 mtype = labels.MatchNotEqual 161 case MatchRegexp: 162 mtype = labels.MatchRegexp 163 case MatchNotRegexp: 164 mtype = labels.MatchNotRegexp 165 default: 166 return fmt.Errorf("unsupported match type [%s]", m.Type) 167 } 168 _, err := labels.NewMatcher(mtype, "name", m.Value) 169 if err != nil { 170 return fmt.Errorf("invalid matcher: %v", err) 171 } 172 return nil 173 } 174 175 type NamespaceRuleExprBuilder struct { 176 Workload *WorkloadExprBuilder `json:"workload,omitempty"` 177 } 178 179 type ClusterRuleExprBuilder struct { 180 Node *NodeExprBuilder `json:"node,omitempty"` 181 } 182 183 // Only one of its members may be specified. 184 type GlobalRuleExprBuilder struct { 185 Workload *ScopedWorkloadExprBuilder `json:"workload,omitempty"` 186 Node *ScopedNodeExprBuilder `json:"node,omitempty"` 187 } 188 189 type WorkloadKind string 190 191 const ( 192 WorkloadDeployment WorkloadKind = "deployment" 193 WorkloadStatefulSet WorkloadKind = "statefulset" 194 WorkloadDaemonSet WorkloadKind = "daemonset" 195 ) 196 197 type WorkloadExprBuilder struct { 198 WorkloadKind WorkloadKind `json:"kind"` 199 WorkloadNames []string `json:"names"` 200 Comparator Comparator `json:"comparator"` 201 202 MetricThreshold WorkloadMetricThreshold `json:"metricThreshold,omitempty"` 203 } 204 205 type ScopedWorkloadExprBuilder struct { 206 WorkloadKind WorkloadKind `json:"kind"` 207 WorkloadNames []ScopedWorkloadNames `json:"names"` 208 Comparator Comparator `json:"comparator"` 209 210 MetricThreshold WorkloadMetricThreshold `json:"metricThreshold,omitempty"` 211 } 212 213 // The cluster and namespace to which the workloads belongs must be specified. 214 type ScopedWorkloadNames struct { 215 Cluster string `json:"cluster"` 216 Namespace string `json:"namespace"` 217 Names []string `json:"names"` 218 } 219 220 const ( 221 MetricWorkloadCpuUsage = "namespace:workload_cpu_usage:sum" 222 MetricWorkloadMemoryUsage = "namespace:workload_memory_usage:sum" 223 MetricWorkloadMemoryUsageWoCache = "namespace:workload_memory_usage_wo_cache:sum" 224 MetricWorkloadNetworkTransmittedRate = "namespace:workload_net_bytes_transmitted:sum_irate" 225 MetricWorkloadNetworkReceivedRate = "namespace:workload_net_bytes_received:sum_irate" 226 MetricWorkloadPodUnavailableRatio = "namespace:%s_unavailable_replicas:ratio" // "%s" must be one of "deployment", "statefulset" and "daemonset" 227 ) 228 229 func (b *WorkloadExprBuilder) Build() string { 230 if b == nil { 231 return "" 232 } 233 if b.WorkloadKind == "" || len(b.WorkloadNames) == 0 || b.Comparator == "" { 234 return "" 235 } 236 237 var ( 238 threshold float64 239 metric string 240 ) 241 242 switch { 243 case b.MetricThreshold.Cpu != nil: 244 var cpu = b.MetricThreshold.Cpu 245 if cpu.Usage != nil { 246 metric = MetricWorkloadCpuUsage 247 threshold = *cpu.Usage 248 } 249 case b.MetricThreshold.Memory != nil: 250 var memory = b.MetricThreshold.Memory 251 switch { 252 case memory.Usage != nil: 253 metric = MetricWorkloadMemoryUsage 254 threshold = *memory.Usage 255 case memory.UsageWoCache != nil: 256 metric = MetricWorkloadMemoryUsageWoCache 257 threshold = *memory.UsageWoCache 258 } 259 case b.MetricThreshold.Network != nil: 260 var network = b.MetricThreshold.Network 261 switch { 262 case network.TransmittedRate != nil: 263 metric = MetricWorkloadNetworkTransmittedRate 264 threshold = *network.TransmittedRate 265 case network.ReceivedRate != nil: 266 metric = MetricWorkloadNetworkReceivedRate 267 threshold = *network.ReceivedRate 268 } 269 case b.MetricThreshold.Replica != nil: 270 var replica = b.MetricThreshold.Replica 271 if replica.UnavailableRatio != nil { 272 metric = fmt.Sprintf(MetricWorkloadPodUnavailableRatio, strings.ToLower(string(b.WorkloadKind))) 273 threshold = *replica.UnavailableRatio 274 } 275 } 276 277 if metric != "" { 278 var filter string 279 if len(b.WorkloadNames) == 1 { 280 filter = fmt.Sprintf(`{workload="%s:%s"}`, b.WorkloadKind, b.WorkloadNames[0]) 281 } else { 282 filter = fmt.Sprintf(`{workload=~"%s:(%s)"}`, b.WorkloadKind, strings.Join(b.WorkloadNames, "|")) 283 } 284 return metric + fmt.Sprintf("%s %s %v", filter, b.Comparator, threshold) 285 } 286 287 return "" 288 } 289 290 func (b *ScopedWorkloadExprBuilder) Build() string { 291 // include the workload names into builded expr only. 292 // the limited clusters and namespaces will be set to the clusterSelector and namespaceSelector separately. 293 294 var names = make(map[string]struct{}) 295 for _, snames := range b.WorkloadNames { 296 for _, name := range snames.Names { 297 names[name] = struct{}{} 298 } 299 } 300 301 var eb = WorkloadExprBuilder{ 302 WorkloadKind: b.WorkloadKind, 303 Comparator: b.Comparator, 304 MetricThreshold: b.MetricThreshold, 305 } 306 for name := range names { 307 eb.WorkloadNames = append(eb.WorkloadNames, name) 308 } 309 310 return eb.Build() 311 } 312 313 // Only one of its members may be specified. 314 type WorkloadMetricThreshold struct { 315 Cpu *WorkloadCpuThreshold `json:"cpu,omitempty"` 316 Memory *WorkloadMemoryThreshold `json:"memory,omitempty"` 317 Network *WorkloadNetworkThreshold `json:"network,omitempty"` 318 Replica *WorkloadReplicaThreshold `json:"replica,omitempty"` 319 } 320 321 // Only one of its members may be specified. 322 type WorkloadCpuThreshold struct { 323 // The unit is core 324 Usage *float64 `json:"usage,omitempty"` 325 } 326 327 // Only one of its members may be specified. 328 type WorkloadMemoryThreshold struct { 329 // The memory usage contains cache 330 // The unit is bytes 331 Usage *float64 `json:"usage,omitempty"` 332 // The memory usage contains no cache 333 // The unit is bytes 334 UsageWoCache *float64 `json:"usageWoCache,omitempty"` 335 } 336 337 // Only one of its members may be specified. 338 type WorkloadNetworkThreshold struct { 339 // The unit is bit/s 340 TransmittedRate *float64 `json:"transmittedRate,omitempty"` 341 // The unit is bit/s 342 ReceivedRate *float64 `json:"receivedRate,omitempty"` 343 } 344 345 // Only one of its members may be specified. 346 type WorkloadReplicaThreshold struct { 347 UnavailableRatio *float64 `json:"unavailableRatio,omitempty"` 348 } 349 350 type NodeExprBuilder struct { 351 NodeNames []string `json:"names"` 352 Comparator Comparator `json:"comparator"` 353 354 MetricThreshold NodeMetricThreshold `json:"metricThreshold"` 355 } 356 357 type ScopedNodeExprBuilder struct { 358 NodeNames []ScopedNodeNames `json:"names"` 359 Comparator Comparator `json:"comparator"` 360 361 MetricThreshold NodeMetricThreshold `json:"metricThreshold,omitempty"` 362 } 363 364 // The cluster to which the node belongs must be specified. 365 type ScopedNodeNames struct { 366 Cluster string `json:"cluster"` 367 Names []string `json:"names"` 368 } 369 370 const ( 371 MetricNodeCpuUtilization = "node:node_cpu_utilisation:avg1m" 372 MetricNodeCpuLoad1m = "node:load1:ratio" 373 MetricNodeCpuLoad5m = "node:load5:ratio" 374 MetricNodeCpuLoad15m = "node:load15:ratio" 375 MetricNodeMemoryUtilization = "node:node_memory_utilisation:" 376 MetricNodeMemoryAvailable = "node:node_memory_bytes_available:sum" 377 MetricNodeNetworkTransmittedRate = "node:node_net_bytes_transmitted:sum_irate" 378 MetricNodeNetwrokReceivedRate = "node:node_net_bytes_received:sum_irate" 379 MetricNodeDiskSpaceUtilization = "node:disk_space_utilization:ratio" 380 MetricNodeDiskSpaceAvailable = "node:disk_space_available:" 381 MetricNodeDiskInodeUtilization = "node:disk_inode_utilization:ratio" 382 MetricNodeDiskIopsRead = "node:data_volume_iops_reads:sum" 383 MetricNodeDiskIopsWrite = "node:data_volume_iops_writes:sum" 384 MetricNodeDiskThroughputRead = "node:data_volume_throughput_bytes_read:sum" 385 MetricNodeDiskThroughputWrite = "node:data_volume_throughput_bytes_write:sum" 386 MetricNodePodUtilization = "node:pod_utilization:ratio" 387 MetricNodePodAbnormalRatio = "node:pod_abnormal:ratio" 388 ) 389 390 func (b *NodeExprBuilder) Build() string { 391 if len(b.NodeNames) == 0 || b.Comparator == "" { 392 return "" 393 } 394 395 var ( 396 threshold float64 397 metric string 398 ) 399 400 switch { 401 case b.MetricThreshold.Cpu != nil: 402 var cpu = b.MetricThreshold.Cpu 403 switch { 404 case cpu.Utilization != nil: 405 metric = MetricNodeCpuUtilization 406 threshold = *cpu.Utilization 407 case cpu.Load1m != nil: 408 metric = MetricNodeCpuLoad1m 409 threshold = *cpu.Load1m 410 case cpu.Load5m != nil: 411 metric = MetricNodeCpuLoad5m 412 threshold = *cpu.Load5m 413 case cpu.Load15m != nil: 414 metric = MetricNodeCpuLoad15m 415 threshold = *cpu.Load15m 416 } 417 case b.MetricThreshold.Memory != nil: 418 var memory = b.MetricThreshold.Memory 419 switch { 420 case memory.Utilization != nil: 421 metric = MetricNodeMemoryUtilization 422 threshold = *memory.Utilization 423 case memory.Available != nil: 424 metric = MetricNodeMemoryAvailable 425 threshold = *memory.Available 426 } 427 case b.MetricThreshold.Network != nil: 428 var network = b.MetricThreshold.Network 429 switch { 430 case network.TransmittedRate != nil: 431 metric = MetricNodeNetworkTransmittedRate 432 threshold = *network.TransmittedRate 433 case network.ReceivedRate != nil: 434 metric = MetricNodeNetwrokReceivedRate 435 threshold = *network.ReceivedRate 436 } 437 case b.MetricThreshold.Disk != nil: 438 var disk = b.MetricThreshold.Disk 439 switch { 440 case disk.SpaceUtilization != nil: 441 metric = MetricNodeDiskSpaceUtilization 442 threshold = *disk.SpaceUtilization 443 case disk.SpaceAvailable != nil: 444 metric = MetricNodeDiskSpaceAvailable 445 threshold = *disk.SpaceAvailable 446 case disk.InodeUtilization != nil: 447 metric = MetricNodeDiskInodeUtilization 448 threshold = *disk.InodeUtilization 449 case disk.IopsRead != nil: 450 metric = MetricNodeDiskIopsRead 451 threshold = *disk.IopsRead 452 case disk.IopsWrite != nil: 453 metric = MetricNodeDiskIopsWrite 454 threshold = *disk.IopsWrite 455 case disk.ThroughputRead != nil: 456 metric = MetricNodeDiskThroughputRead 457 threshold = *disk.ThroughputRead 458 case disk.ThroughputWrite != nil: 459 metric = MetricNodeDiskThroughputWrite 460 threshold = *disk.ThroughputWrite 461 } 462 case b.MetricThreshold.Pod != nil: 463 var pod = b.MetricThreshold.Pod 464 switch { 465 case pod.Utilization != nil: 466 metric = MetricNodePodUtilization 467 threshold = *pod.Utilization 468 case pod.AbnormalRatio != nil: 469 metric = MetricNodePodAbnormalRatio 470 threshold = *pod.AbnormalRatio 471 } 472 } 473 474 if metric != "" { 475 var filter string 476 if len(b.NodeNames) == 1 { 477 filter = fmt.Sprintf(`{node="%s"}`, b.NodeNames[0]) 478 } else { 479 filter = fmt.Sprintf(`{node=~"(%s)"}`, strings.Join(b.NodeNames, "|")) 480 } 481 return metric + fmt.Sprintf("%s %s %v", filter, b.Comparator, threshold) 482 } 483 484 return "" 485 } 486 487 func (b *ScopedNodeExprBuilder) Build() string { 488 // include the node names into builded expr only. 489 // the limited clusters will be set to the clusterSelector. 490 491 var names = make(map[string]struct{}) 492 for _, snames := range b.NodeNames { 493 for _, name := range snames.Names { 494 names[name] = struct{}{} 495 } 496 } 497 498 var eb = NodeExprBuilder{ 499 Comparator: b.Comparator, 500 MetricThreshold: b.MetricThreshold, 501 } 502 for name := range names { 503 eb.NodeNames = append(eb.NodeNames, name) 504 } 505 506 return eb.Build() 507 } 508 509 // Only one of its members may be specified. 510 type NodeMetricThreshold struct { 511 Cpu *NodeCpuThreshold `json:"cpu,omitempty"` 512 Memory *NodeMemoryThreshold `json:"memory,omitempty"` 513 Network *NodeNetworkThreshold `json:"network,omitempty"` 514 Disk *NodeDiskThreshold `json:"disk,omitempty"` 515 Pod *NodePodThreshold `json:"pod,omitempty"` 516 } 517 518 // Only one of its members may be specified. 519 type NodeCpuThreshold struct { 520 Utilization *float64 `json:"utilization,omitempty"` 521 Load1m *float64 `json:"load1m,omitempty"` 522 Load5m *float64 `json:"load5m,omitempty"` 523 Load15m *float64 `json:"load15m,omitempty"` 524 } 525 526 // Only one of its members may be specified. 527 type NodeMemoryThreshold struct { 528 Utilization *float64 `json:"utilization,omitempty"` 529 // The unit is bytes 530 Available *float64 `json:"available,omitempty"` 531 } 532 533 // Only one of its members may be specified. 534 type NodePodThreshold struct { 535 Utilization *float64 `json:"utilization,omitempty"` 536 AbnormalRatio *float64 `json:"abnormalRatio,omitempty"` 537 } 538 539 // Only one of its members may be specified. 540 type NodeDiskThreshold struct { 541 SpaceUtilization *float64 `json:"spaceUtilization,omitempty"` 542 // The unit is bytes 543 SpaceAvailable *float64 `json:"spaceAvailable,omitempty"` 544 InodeUtilization *float64 `json:"inodeUtilization,omitempty"` 545 // The unit is io/s 546 IopsRead *float64 `json:"iopsRead,omitempty"` 547 // The unit is io/s 548 IopsWrite *float64 `json:"iopsWrite,omitempty"` 549 // The unit is bytes/s 550 ThroughputRead *float64 `json:"throughputRead,omitempty"` 551 // The unit is bytes/s 552 ThroughputWrite *float64 `json:"throughputWrite,omitempty"` 553 } 554 555 // Only one of its members may be specified. 556 type NodeNetworkThreshold struct { 557 // The unit is bit/s 558 TransmittedRate *float64 `json:"transmittedRate,omitempty"` 559 // The unit is bit/s 560 ReceivedRate *float64 `json:"receivedRate,omitempty"` 561 } 562 563 // RuleGroupSpec defines the desired state of RuleGroup 564 type RuleGroupSpec struct { 565 Interval string `json:"interval,omitempty"` 566 PartialResponseStrategy string `json:"partial_response_strategy,omitempty"` 567 Rules []NamespaceRule `json:"rules"` 568 } 569 570 // RuleGroupStatus defines the observed state of RuleGroup 571 type RuleGroupStatus struct { 572 // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster 573 // Important: Run "make" to regenerate code after modifying this file 574 } 575 576 //+kubebuilder:subresource:status 577 // +genclient 578 // +k8s:openapi-gen=true 579 // +kubebuilder:object:root=true 580 581 // RuleGroup is the Schema for the RuleGroup API 582 type RuleGroup struct { 583 metav1.TypeMeta `json:",inline"` 584 metav1.ObjectMeta `json:"metadata,omitempty"` 585 586 Spec RuleGroupSpec `json:"spec,omitempty"` 587 Status RuleGroupStatus `json:"status,omitempty"` 588 } 589 590 // +kubebuilder:object:root=true 591 592 // RuleGroupList contains a list of RuleGroup 593 type RuleGroupList struct { 594 metav1.TypeMeta `json:",inline"` 595 metav1.ListMeta `json:"metadata,omitempty"` 596 Items []RuleGroup `json:"items"` 597 } 598 599 // ClusterRuleGroupSpec defines the desired state of ClusterRuleGroup 600 type ClusterRuleGroupSpec struct { 601 Interval string `json:"interval,omitempty"` 602 PartialResponseStrategy string `json:"partial_response_strategy,omitempty"` 603 604 Rules []ClusterRule `json:"rules"` 605 } 606 607 // ClusterRuleGroupStatus defines the observed state of ClusterRuleGroup 608 type ClusterRuleGroupStatus struct { 609 // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster 610 // Important: Run "make" to regenerate code after modifying this file 611 } 612 613 // +kubebuilder:object:root=true 614 //+kubebuilder:subresource:status 615 // +genclient 616 // +genclient:nonNamespaced 617 // +kubebuilder:resource:scope=Cluster 618 619 // ClusterRuleGroup is the Schema for the ClusterRuleGroup API 620 type ClusterRuleGroup struct { 621 metav1.TypeMeta `json:",inline"` 622 metav1.ObjectMeta `json:"metadata,omitempty"` 623 624 Spec ClusterRuleGroupSpec `json:"spec,omitempty"` 625 Status ClusterRuleGroupStatus `json:"status,omitempty"` 626 } 627 628 // +kubebuilder:object:root=true 629 630 // ClusterRuleGroupList contains a list of ClusterRuleGroup 631 type ClusterRuleGroupList struct { 632 metav1.TypeMeta `json:",inline"` 633 metav1.ListMeta `json:"metadata,omitempty"` 634 Items []ClusterRuleGroup `json:"items"` 635 } 636 637 // GlobalRuleGroupSpec defines the desired state of GlobalRuleGroup 638 type GlobalRuleGroupSpec struct { 639 Interval string `json:"interval,omitempty"` 640 PartialResponseStrategy string `json:"partial_response_strategy,omitempty"` 641 642 Rules []GlobalRule `json:"rules"` 643 } 644 645 // GlobalRuleGroupStatus defines the observed state of GlobalRuleGroup 646 type GlobalRuleGroupStatus struct { 647 // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster 648 // Important: Run "make" to regenerate code after modifying this file 649 } 650 651 // +kubebuilder:object:root=true 652 //+kubebuilder:subresource:status 653 // +genclient 654 // +genclient:nonNamespaced 655 // +kubebuilder:resource:scope=Cluster 656 657 // GlobalRuleGroup is the Schema for the GlobalRuleGroup API 658 type GlobalRuleGroup struct { 659 metav1.TypeMeta `json:",inline"` 660 metav1.ObjectMeta `json:"metadata,omitempty"` 661 662 Spec GlobalRuleGroupSpec `json:"spec,omitempty"` 663 Status GlobalRuleGroupStatus `json:"status,omitempty"` 664 } 665 666 // +kubebuilder:object:root=true 667 668 // GlobalRuleGroupList contains a list of GlobalRuleGroup 669 type GlobalRuleGroupList struct { 670 metav1.TypeMeta `json:",inline"` 671 metav1.ListMeta `json:"metadata,omitempty"` 672 Items []GlobalRuleGroup `json:"items"` 673 } 674 675 func init() { 676 SchemeBuilder.Register(&RuleGroup{}, &RuleGroupList{}) 677 SchemeBuilder.Register(&ClusterRuleGroup{}, &ClusterRuleGroupList{}) 678 SchemeBuilder.Register(&GlobalRuleGroup{}, &GlobalRuleGroupList{}) 679 }