This is an automated email from the ASF dual-hosted git repository.
zhongxjian pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo-kubernetes.git
The following commit(s) were added to refs/heads/master by this push:
new 95b12ddf update status and metadata api (#837)
95b12ddf is described below
commit 95b12ddfbb49d6b0807ede45a4278bb249cf5d3c
Author: mfordjody <[email protected]>
AuthorDate: Wed Dec 31 20:37:40 2025 +0800
update status and metadata api (#837)
---
api/annotation/annotations.gen.go | 158 +++++++
api/annotation/annotations.yaml | 53 +++
api/label/labels.gen.go | 214 +++++++++
api/label/labels.yaml | 71 +++
api/meta/v1alpha1/status.pb.go | 221 ++++++++++
api/meta/v1alpha1/status.proto | 41 ++
api/meta/v1alpha1/status_json.gen.go | 34 ++
api/networking/v1alpha3/destination_rule.proto | 15 +
api/networking/v1alpha3/virtual_service.proto | 15 +
api/security/v1alpha3/authorization_policy.proto | 15 +
api/security/v1alpha3/ca.proto | 15 +
api/security/v1alpha3/peer_authentication.proto | 15 +
api/security/v1alpha3/request_authentication.proto | 15 +
dubbod/planet/pkg/bootstrap/config_controller.go | 16 +-
dubbod/planet/pkg/bootstrap/server.go | 10 +-
dubbod/planet/pkg/config/kube/crdclient/client.go | 4 +-
dubbod/planet/pkg/config/kube/crdclient/types.go | 66 +--
dubbod/planet/pkg/features/experimental.go | 4 +-
.../model/{subsetrule.go => destinationrule.go} | 14 +-
dubbod/planet/pkg/model/push_context.go | 100 ++---
dubbod/planet/pkg/model/service.go | 39 --
dubbod/planet/pkg/networking/grpcgen/cds.go | 4 +-
.../serviceregistry/kube/controller/controller.go | 3 +-
.../kube/controller/endpointslice.go | 13 +-
.../pkg/serviceregistry/kube/controller/pod.go | 10 +-
.../planet/pkg/serviceregistry/kube/conversion.go | 78 ----
.../planet/pkg/serviceregistry/util/label/label.go | 44 +-
dubbod/planet/pkg/xds/cds.go | 8 +-
go.mod | 1 +
go.sum | 2 +
manifests/charts/base/files/crd-all.yaml | 18 +-
pkg/adsc/adsc.go | 129 +-----
pkg/adsc/util.go | 22 -
pkg/config/schema/collections/collections.agent.go | 34 +-
pkg/config/schema/collections/collections.go | 34 +-
pkg/config/schema/gvk/resources.go | 10 +-
pkg/config/schema/gvr/resources.go | 4 +-
pkg/config/schema/kind/resources.go | 6 +-
pkg/config/schema/kubeclient/resources.go | 22 +-
pkg/config/schema/kubetypes/resources.go | 2 +-
pkg/kube/inject/inject.go | 16 +-
pkg/kube/inject/webhook.go | 38 +-
samples/grpc-app/README.md | 14 +-
tests/grpc-app/consumer/main.go | 14 +-
tools/metadata/main.go | 485 +++++++++++++++++++++
45 files changed, 1598 insertions(+), 548 deletions(-)
diff --git a/api/annotation/annotations.gen.go
b/api/annotation/annotations.gen.go
new file mode 100644
index 00000000..cfa91f72
--- /dev/null
+++ b/api/annotation/annotations.gen.go
@@ -0,0 +1,158 @@
+
+// GENERATED FILE -- DO NOT EDIT
+
+package annotation
+
+type FeatureStatus int
+
+const (
+ Alpha FeatureStatus = iota
+ Beta
+ Stable
+)
+
+func (s FeatureStatus) String() string {
+ switch s {
+ case Alpha:
+ return "Alpha"
+ case Beta:
+ return "Beta"
+ case Stable:
+ return "Stable"
+ }
+ return "Unknown"
+}
+
+type ResourceTypes int
+
+const (
+ Unknown ResourceTypes = iota
+ Pod
+)
+
+func (r ResourceTypes) String() string {
+ switch r {
+ case 1:
+ return "Pod"
+ }
+ return "Unknown"
+}
+
+// Instance describes a single resource annotation
+type Instance struct {
+ // The name of the annotation.
+ Name string
+
+ // Description of the annotation.
+ Description string
+
+ // FeatureStatus of this annotation.
+ FeatureStatus FeatureStatus
+
+ // Hide the existence of this annotation when outputting usage
information.
+ Hidden bool
+
+ // Mark this annotation as deprecated when generating usage information.
+ Deprecated bool
+
+ // The types of resources this annotation applies to.
+ Resources []ResourceTypes
+}
+
+var (
+
+ OrgApacheDubboRev = Instance {
+ Name: "dubbo.apache.org/rev",
+ Description: "Specifies a control plane revision to which a
given proxy "+
+ "is connected. This annotation is added automatically,
not "+
+ "set by a user. In contrary to the label "+
+ "dubbo.apache.org/rev, it represents the actual
revision, "+
+ "not the requested revision.",
+ FeatureStatus: Alpha,
+ Hidden: false,
+ Deprecated: false,
+ Resources: []ResourceTypes{
+ Pod,
+ },
+ }
+
+ OrgApacheDubboInjectTemplates = Instance {
+ Name: "inject.dubbo.apache.org/templates",
+ Description: "The name of the inject template(s) to use, as a
comma "+
+ "separate list.",
+ FeatureStatus: Alpha,
+ Hidden: false,
+ Deprecated: false,
+ Resources: []ResourceTypes{
+ Pod,
+ },
+ }
+
+ OrgApacheDubboProxyConfig = Instance {
+ Name: "proxy.dubbo.apache.org/config",
+ Description: "Overrides for the proxy configuration for this
specific "+
+ "proxy.",
+ FeatureStatus: Beta,
+ Hidden: false,
+ Deprecated: false,
+ Resources: []ResourceTypes{
+ Pod,
+ },
+ }
+
+ OrgApacheDubboProxyOverrides = Instance {
+ Name: "proxy.dubbo.apache.org/overrides",
+ Description: "Used internally to indicate user-specified
overrides in "+
+ "the proxy container of the pod during injection.",
+ FeatureStatus: Alpha,
+ Hidden: true,
+ Deprecated: false,
+ Resources: []ResourceTypes{
+ Pod,
+ },
+ }
+
+ OrgApacheDubboProxylessInject = Instance {
+ Name: "proxyless.dubbo.apache.org/inject",
+ Description: "Specifies whether or not an proxyless adapter
should be "+
+ "automatically injected into the workload.",
+ FeatureStatus: Alpha,
+ Hidden: false,
+ Deprecated: true,
+ Resources: []ResourceTypes{
+ Pod,
+ },
+ }
+
+ OrgApacheDubboProxylessStatus = Instance {
+ Name: "proxyless.dubbo.apache.org/status",
+ Description: "Generated by proxyless adapter injection that
indicates "+
+ "the status of the operation. Includes a version hash
of "+
+ "the executed template, as well as names of injected "+
+ "resources.",
+ FeatureStatus: Alpha,
+ Hidden: false,
+ Deprecated: false,
+ Resources: []ResourceTypes{
+ Pod,
+ },
+ }
+
+)
+
+func AllResourceAnnotations() []*Instance {
+ return []*Instance {
+ &OrgApacheDubboRev,
+ &OrgApacheDubboInjectTemplates,
+ &OrgApacheDubboProxyConfig,
+ &OrgApacheDubboProxyOverrides,
+ &OrgApacheDubboProxylessInject,
+ &OrgApacheDubboProxylessStatus,
+ }
+}
+
+func AllResourceTypes() []string {
+ return []string {
+ "Pod",
+ }
+}
diff --git a/api/annotation/annotations.yaml b/api/annotation/annotations.yaml
new file mode 100644
index 00000000..ab42b771
--- /dev/null
+++ b/api/annotation/annotations.yaml
@@ -0,0 +1,53 @@
+annotations:
+ - name: proxyless.dubbo.apache.org/inject
+ featureStatus: Alpha
+ description: Specifies whether or not an proxyless adapter should be
automatically
+ injected into the workload.
+ deprecated: true
+ hidden: false
+ resources:
+ - Pod
+
+ - name: proxyless.dubbo.apache.org/status
+ featureStatus: Alpha
+ description: Generated by proxyless adapter injection that indicates the
status of
+ the operation. Includes a version hash of the executed template, as well
as names of
+ injected resources.
+ deprecated: false
+ hidden: false
+ resources:
+ - Pod
+
+ - name: proxy.dubbo.apache.org/config
+ featureStatus: Beta
+ description: Overrides for the proxy configuration for this specific proxy.
+ deprecated: false
+ hidden: false
+ resources:
+ - Pod
+
+ - name: dubbo.apache.org/rev
+ featureStatus: Alpha
+ description: Specifies a control plane revision to which a given proxy is
connected.
+ This annotation is added automatically, not set by a user. In contrary
to the label dubbo.apache.org/rev,
+ it represents the actual revision, not the requested revision.
+ deprecated: false
+ hidden: false
+ resources:
+ - Pod
+
+ - name: proxy.dubbo.apache.org/overrides
+ featureStatus: Alpha
+ description: Used internally to indicate user-specified overrides in the
proxy container of the pod during injection.
+ deprecated: false
+ hidden: true
+ resources:
+ - Pod
+
+ - name: inject.dubbo.apache.org/templates
+ featureStatus: Alpha
+ description: The name of the inject template(s) to use, as a comma
separate list.
+ deprecated: false
+ hidden: false
+ resources:
+ - Pod
diff --git a/api/label/labels.gen.go b/api/label/labels.gen.go
new file mode 100644
index 00000000..0d7ba4b9
--- /dev/null
+++ b/api/label/labels.gen.go
@@ -0,0 +1,214 @@
+
+// GENERATED FILE -- DO NOT EDIT
+
+package label
+
+type FeatureStatus int
+
+const (
+ Alpha FeatureStatus = iota
+ Beta
+ Stable
+)
+
+func (s FeatureStatus) String() string {
+ switch s {
+ case Alpha:
+ return "Alpha"
+ case Beta:
+ return "Beta"
+ case Stable:
+ return "Stable"
+ }
+ return "Unknown"
+}
+
+type ResourceTypes int
+
+const (
+ Unknown ResourceTypes = iota
+ Any
+ Deployment
+ Gateway
+ HorizontalPodAutoscaler
+ Namespace
+ Pod
+ PodDisruptionBudget
+ Service
+ ServiceAccount
+)
+
+func (r ResourceTypes) String() string {
+ switch r {
+ case 1:
+ return "Any"
+ case 2:
+ return "Deployment"
+ case 3:
+ return "Gateway"
+ case 4:
+ return "HorizontalPodAutoscaler"
+ case 5:
+ return "Namespace"
+ case 6:
+ return "Pod"
+ case 7:
+ return "PodDisruptionBudget"
+ case 8:
+ return "Service"
+ case 9:
+ return "ServiceAccount"
+ }
+ return "Unknown"
+}
+
+// Instance describes a single resource label
+type Instance struct {
+ // The name of the label.
+ Name string
+
+ // Description of the label.
+ Description string
+
+ // FeatureStatus of this label.
+ FeatureStatus FeatureStatus
+
+ // Hide the existence of this label when outputting usage information.
+ Hidden bool
+
+ // Mark this label as deprecated when generating usage information.
+ Deprecated bool
+
+ // The types of resources this label applies to.
+ Resources []ResourceTypes
+}
+
+var (
+
+ OrgApacheDubboRev = Instance {
+ Name: "dubbo.apache.org/rev",
+ Description: "Dubbo control plane revision or tag associated
with the "+
+ "resource; e.g. `canary`",
+ FeatureStatus: Beta,
+ Hidden: false,
+ Deprecated: false,
+ Resources: []ResourceTypes{
+ Namespace,
+ Gateway,
+ Pod,
+ },
+ }
+
+ IoK8sNetworkingGatewayGatewayClassName = Instance {
+ Name: "gateway.networking.k8s.io/gateway-class-name",
+ Description: "Automatically added to all resources
[automatically "+
+
"created](/docs/tasks/traffic-management/ingress/gateway-api/#automated-deployment)
"+
+ "by Dubbo Gateway controller to indicate which "+
+ "`GatewayClass` resulted in the object creation. Users
"+
+ "should not set this label themselves.",
+ FeatureStatus: Stable,
+ Hidden: false,
+ Deprecated: false,
+ Resources: []ResourceTypes{
+ ServiceAccount,
+ Deployment,
+ Service,
+ PodDisruptionBudget,
+ HorizontalPodAutoscaler,
+ },
+ }
+
+ IoK8sNetworkingGatewayGatewayName = Instance {
+ Name: "gateway.networking.k8s.io/gateway-name",
+ Description: "Automatically added to all resources
[automatically "+
+
"created](/docs/tasks/traffic-management/ingress/gateway-api/#automated-deployment)
"+
+ "by Dubbo Gateway controller to indicate which
`Gateway` "+
+ "resulted in the object creation. Users should not set
"+
+ "this label themselves.",
+ FeatureStatus: Stable,
+ Hidden: false,
+ Deprecated: false,
+ Resources: []ResourceTypes{
+ ServiceAccount,
+ Deployment,
+ Service,
+ PodDisruptionBudget,
+ HorizontalPodAutoscaler,
+ },
+ }
+
+ OrgApacheDubboOperatorComponent = Instance {
+ Name: "operator.dubbo.apache.org/component",
+ Description: "Dubbo operator component name of the resource,
e.g. "+
+ "`Pilot`",
+ FeatureStatus: Alpha,
+ Hidden: true,
+ Deprecated: false,
+ Resources: []ResourceTypes{
+ Any,
+ },
+ }
+
+ OrgApacheDubboOperatorManaged = Instance {
+ Name: "operator.dubbo.apache.org/managed",
+ Description: "Set to `Reconcile` if the Dubbo operator will
reconcile "+
+ "the resource.",
+ FeatureStatus: Alpha,
+ Hidden: true,
+ Deprecated: false,
+ Resources: []ResourceTypes{
+ Any,
+ },
+ }
+
+ OrgApacheDubboOperatorVersion = Instance {
+ Name: "operator.dubbo.apache.org/version",
+ Description: "The Dubbo operator version that installed the
resource, "+
+ "e.g. `1.6.0`",
+ FeatureStatus: Alpha,
+ Hidden: true,
+ Deprecated: false,
+ Resources: []ResourceTypes{
+ Any,
+ },
+ }
+
+ OrgApacheDubboProxylessInject = Instance {
+ Name: "proxyless.dubbo.apache.org/inject",
+ Description: "Specifies whether or not an proxyless adapter
should be "+
+ "automatically injected into the workload.",
+ FeatureStatus: Alpha,
+ Hidden: false,
+ Deprecated: false,
+ Resources: []ResourceTypes{
+ Pod,
+ },
+ }
+
+)
+
+func AllResourceLabels() []*Instance {
+ return []*Instance {
+ &OrgApacheDubboRev,
+ &IoK8sNetworkingGatewayGatewayClassName,
+ &IoK8sNetworkingGatewayGatewayName,
+ &OrgApacheDubboOperatorComponent,
+ &OrgApacheDubboOperatorManaged,
+ &OrgApacheDubboOperatorVersion,
+ &OrgApacheDubboProxylessInject,
+ }
+}
+
+func AllResourceTypes() []string {
+ return []string {
+ "Any",
+ "Deployment",
+ "Gateway",
+ "HorizontalPodAutoscaler",
+ "Namespace",
+ "Pod",
+ "PodDisruptionBudget",
+ "Service",
+ "ServiceAccount",
+ }
+}
diff --git a/api/label/labels.yaml b/api/label/labels.yaml
new file mode 100644
index 00000000..9f04ae5b
--- /dev/null
+++ b/api/label/labels.yaml
@@ -0,0 +1,71 @@
+labels:
+ - name: dubbo.apache.org/rev
+ featureStatus: Beta
+ description: Dubbo control plane revision or tag associated with the
resource; e.g. `canary`
+ hidden: false
+ deprecated: false
+ resources:
+ - Namespace
+ - Gateway
+ - Pod
+
+ - name: operator.dubbo.apache.org/component
+ featureStatus: Alpha
+ description: Dubbo operator component name of the resource, e.g. `Pilot`
+ hidden: true
+ deprecated: false
+ resources:
+ - Any
+
+ - name: operator.dubbo.apache.org/managed
+ featureStatus: Alpha
+ description: Set to `Reconcile` if the Dubbo operator will reconcile the
resource.
+ hidden: true
+ deprecated: false
+ resources:
+ - Any
+
+ - name: operator.dubbo.apache.org/version
+ featureStatus: Alpha
+ description: The Dubbo operator version that installed the resource, e.g.
`1.6.0`
+ hidden: true
+ deprecated: false
+ resources:
+ - Any
+
+ - name: proxyless.dubbo.apache.org/inject
+ featureStatus: Alpha
+ description: Specifies whether or not an proxyless adapter should be
automatically
+ injected into the workload.
+ deprecated: false
+ hidden: false
+ resources:
+ - Pod
+
+
+ - name: gateway.networking.k8s.io/gateway-name
+ featureStatus: Stable
+ description: Automatically added to all resources [automatically
created](/docs/tasks/traffic-management/ingress/gateway-api/#automated-deployment)
+ by Dubbo Gateway controller to indicate which `Gateway` resulted in the
object creation. Users should not set this label themselves.
+ deprecated: false
+ hidden: false
+ resources:
+ - ServiceAccount
+ - Deployment
+ - Service
+ - PodDisruptionBudget
+ - HorizontalPodAutoscaler
+
+ - name: gateway.networking.k8s.io/gateway-class-name
+ featureStatus: Stable
+ description: Automatically added to all resources [automatically
created](/docs/tasks/traffic-management/ingress/gateway-api/#automated-deployment)
+ by Dubbo Gateway controller to indicate which `GatewayClass` resulted in
the object creation. Users should not set this label themselves.
+ deprecated: false
+ hidden: false
+ resources:
+ - ServiceAccount
+ - Deployment
+ - Service
+ - PodDisruptionBudget
+ - HorizontalPodAutoscaler
+
diff --git a/api/meta/v1alpha1/status.pb.go b/api/meta/v1alpha1/status.pb.go
new file mode 100644
index 00000000..047ec446
--- /dev/null
+++ b/api/meta/v1alpha1/status.pb.go
@@ -0,0 +1,221 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.36.10
+// protoc v6.33.0
+// source: status.proto
+
+package v1alpha1
+
+import (
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ reflect "reflect"
+ sync "sync"
+ unsafe "unsafe"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type DubboStatus struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ // +optional
+ // +patchMergeKey=type
+ // +patchStrategy=merge
+ Conditions []*DubboCondition
`protobuf:"bytes,1,rep,name=conditions,proto3" json:"conditions,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *DubboStatus) Reset() {
+ *x = DubboStatus{}
+ mi := &file_status_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *DubboStatus) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DubboStatus) ProtoMessage() {}
+
+func (x *DubboStatus) ProtoReflect() protoreflect.Message {
+ mi := &file_status_proto_msgTypes[0]
+ if x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use DubboStatus.ProtoReflect.Descriptor instead.
+func (*DubboStatus) Descriptor() ([]byte, []int) {
+ return file_status_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *DubboStatus) GetConditions() []*DubboCondition {
+ if x != nil {
+ return x.Conditions
+ }
+ return nil
+}
+
+type DubboCondition struct {
+ state protoimpl.MessageState `protogen:"open.v1"`
+ Type string `protobuf:"bytes,1,opt,name=type,proto3"
json:"type,omitempty"`
+ Status string
`protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"`
+ // +optional
+ Reason string `protobuf:"bytes,3,opt,name=reason,proto3"
json:"reason,omitempty"`
+ // +optional
+ // +protoc-gen-crd:validation:XIntOrString
+ ObservedGeneration int64
`protobuf:"varint,4,opt,name=observed_generation,json=observedGeneration,proto3"
json:"observed_generation,omitempty"`
+ unknownFields protoimpl.UnknownFields
+ sizeCache protoimpl.SizeCache
+}
+
+func (x *DubboCondition) Reset() {
+ *x = DubboCondition{}
+ mi := &file_status_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *DubboCondition) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DubboCondition) ProtoMessage() {}
+
+func (x *DubboCondition) ProtoReflect() protoreflect.Message {
+ mi := &file_status_proto_msgTypes[1]
+ if x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use DubboCondition.ProtoReflect.Descriptor instead.
+func (*DubboCondition) Descriptor() ([]byte, []int) {
+ return file_status_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *DubboCondition) GetType() string {
+ if x != nil {
+ return x.Type
+ }
+ return ""
+}
+
+func (x *DubboCondition) GetStatus() string {
+ if x != nil {
+ return x.Status
+ }
+ return ""
+}
+
+func (x *DubboCondition) GetReason() string {
+ if x != nil {
+ return x.Reason
+ }
+ return ""
+}
+
+func (x *DubboCondition) GetObservedGeneration() int64 {
+ if x != nil {
+ return x.ObservedGeneration
+ }
+ return 0
+}
+
+var File_status_proto protoreflect.FileDescriptor
+
+const file_status_proto_rawDesc = "" +
+ "\n" +
+ "\fstatus.proto\x12\x13dubbo.meta.v1alpha1\"R\n" +
+ "\vDubboStatus\x12C\n" +
+ "\n" +
+ "conditions\x18\x01 \x03(\v2#.dubbo.meta.v1alpha1.DubboConditionR\n" +
+ "conditions\"\x85\x01\n" +
+ "\x0eDubboCondition\x12\x12\n" +
+ "\x04type\x18\x01 \x01(\tR\x04type\x12\x16\n" +
+ "\x06status\x18\x02 \x01(\tR\x06status\x12\x16\n" +
+ "\x06reason\x18\x03 \x01(\tR\x06reason\x12/\n" +
+ "\x13observed_generation\x18\x04
\x01(\x03R\x12observedGenerationB\x14Z\x12/api/meta/v1alpha1b\x06proto3"
+
+var (
+ file_status_proto_rawDescOnce sync.Once
+ file_status_proto_rawDescData []byte
+)
+
+func file_status_proto_rawDescGZIP() []byte {
+ file_status_proto_rawDescOnce.Do(func() {
+ file_status_proto_rawDescData =
protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_status_proto_rawDesc),
len(file_status_proto_rawDesc)))
+ })
+ return file_status_proto_rawDescData
+}
+
+var file_status_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
+var file_status_proto_goTypes = []any{
+ (*DubboStatus)(nil), // 0: dubbo.meta.v1alpha1.DubboStatus
+ (*DubboCondition)(nil), // 1: dubbo.meta.v1alpha1.DubboCondition
+}
+var file_status_proto_depIdxs = []int32{
+ 1, // 0: dubbo.meta.v1alpha1.DubboStatus.conditions:type_name ->
dubbo.meta.v1alpha1.DubboCondition
+ 1, // [1:1] is the sub-list for method output_type
+ 1, // [1:1] is the sub-list for method input_type
+ 1, // [1:1] is the sub-list for extension type_name
+ 1, // [1:1] is the sub-list for extension extendee
+ 0, // [0:1] is the sub-list for field type_name
+}
+
+func init() { file_status_proto_init() }
+func file_status_proto_init() {
+ if File_status_proto != nil {
+ return
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor:
unsafe.Slice(unsafe.StringData(file_status_proto_rawDesc),
len(file_status_proto_rawDesc)),
+ NumEnums: 0,
+ NumMessages: 2,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_status_proto_goTypes,
+ DependencyIndexes: file_status_proto_depIdxs,
+ MessageInfos: file_status_proto_msgTypes,
+ }.Build()
+ File_status_proto = out.File
+ file_status_proto_goTypes = nil
+ file_status_proto_depIdxs = nil
+}
diff --git a/api/meta/v1alpha1/status.proto b/api/meta/v1alpha1/status.proto
new file mode 100644
index 00000000..5c1b164d
--- /dev/null
+++ b/api/meta/v1alpha1/status.proto
@@ -0,0 +1,41 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
+
+syntax = "proto3";
+
+package dubbo.meta.v1alpha1;
+
+option go_package = "/api/meta/v1alpha1";
+
+message DubboStatus {
+ // +optional
+ // +patchMergeKey=type
+ // +patchStrategy=merge
+ repeated DubboCondition conditions = 1;
+}
+
+message DubboCondition {
+ string type = 1;
+
+ string status = 2;
+
+ // +optional
+ string reason = 3;
+
+ // +optional
+ // +protoc-gen-crd:validation:XIntOrString
+ int64 observed_generation = 4;
+}
diff --git a/api/meta/v1alpha1/status_json.gen.go
b/api/meta/v1alpha1/status_json.gen.go
new file mode 100644
index 00000000..3c2e1260
--- /dev/null
+++ b/api/meta/v1alpha1/status_json.gen.go
@@ -0,0 +1,34 @@
+// Code generated by protoc-gen-jsonshim. DO NOT EDIT.
+package v1alpha1
+
+import (
+ bytes "bytes"
+ jsonpb "github.com/golang/protobuf/jsonpb"
+)
+
+// MarshalJSON is a custom marshaler for DubboStatus
+func (this *DubboStatus) MarshalJSON() ([]byte, error) {
+ str, err := StatusMarshaler.MarshalToString(this)
+ return []byte(str), err
+}
+
+// UnmarshalJSON is a custom unmarshaler for DubboStatus
+func (this *DubboStatus) UnmarshalJSON(b []byte) error {
+ return StatusUnmarshaler.Unmarshal(bytes.NewReader(b), this)
+}
+
+// MarshalJSON is a custom marshaler for DubboCondition
+func (this *DubboCondition) MarshalJSON() ([]byte, error) {
+ str, err := StatusMarshaler.MarshalToString(this)
+ return []byte(str), err
+}
+
+// UnmarshalJSON is a custom unmarshaler for DubboCondition
+func (this *DubboCondition) UnmarshalJSON(b []byte) error {
+ return StatusUnmarshaler.Unmarshal(bytes.NewReader(b), this)
+}
+
+var (
+ StatusMarshaler = &jsonpb.Marshaler{}
+ StatusUnmarshaler = &jsonpb.Unmarshaler{AllowUnknownFields: true}
+)
diff --git a/api/networking/v1alpha3/destination_rule.proto
b/api/networking/v1alpha3/destination_rule.proto
new file mode 100644
index 00000000..a6f66394
--- /dev/null
+++ b/api/networking/v1alpha3/destination_rule.proto
@@ -0,0 +1,15 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
\ No newline at end of file
diff --git a/api/networking/v1alpha3/virtual_service.proto
b/api/networking/v1alpha3/virtual_service.proto
new file mode 100644
index 00000000..a6f66394
--- /dev/null
+++ b/api/networking/v1alpha3/virtual_service.proto
@@ -0,0 +1,15 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
\ No newline at end of file
diff --git a/api/security/v1alpha3/authorization_policy.proto
b/api/security/v1alpha3/authorization_policy.proto
new file mode 100644
index 00000000..a6f66394
--- /dev/null
+++ b/api/security/v1alpha3/authorization_policy.proto
@@ -0,0 +1,15 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
\ No newline at end of file
diff --git a/api/security/v1alpha3/ca.proto b/api/security/v1alpha3/ca.proto
new file mode 100644
index 00000000..a6f66394
--- /dev/null
+++ b/api/security/v1alpha3/ca.proto
@@ -0,0 +1,15 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
\ No newline at end of file
diff --git a/api/security/v1alpha3/peer_authentication.proto
b/api/security/v1alpha3/peer_authentication.proto
new file mode 100644
index 00000000..a6f66394
--- /dev/null
+++ b/api/security/v1alpha3/peer_authentication.proto
@@ -0,0 +1,15 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
\ No newline at end of file
diff --git a/api/security/v1alpha3/request_authentication.proto
b/api/security/v1alpha3/request_authentication.proto
new file mode 100644
index 00000000..a6f66394
--- /dev/null
+++ b/api/security/v1alpha3/request_authentication.proto
@@ -0,0 +1,15 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You 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.
\ No newline at end of file
diff --git a/dubbod/planet/pkg/bootstrap/config_controller.go
b/dubbod/planet/pkg/bootstrap/config_controller.go
index ff77ac5d..2777e567 100644
--- a/dubbod/planet/pkg/bootstrap/config_controller.go
+++ b/dubbod/planet/pkg/bootstrap/config_controller.go
@@ -178,9 +178,12 @@ func (s *Server) initConfigSources(args *PlanetArgs) (err
error) {
s.ConfigStores = append(s.ConfigStores,
configController)
log.Infof("Started File configSource %s",
configSource.Address)
case XDS:
+ // XDS config source support (legacy - MCP protocol
removed)
+ // Note: MCP was a legacy protocol replaced by
APIGenerator in Istio
+ // This XDS config source may not be needed for
proxyless mesh
// TLS settings removed from ConfigSource - use
insecure credentials
// TODO: Implement TLS support when needed
- xdsMCP, err := adsc.New(srcAddress.Host,
&adsc.ADSConfig{
+ xdsClient, err := adsc.New(srcAddress.Host,
&adsc.ADSConfig{
InitialDiscoveryRequests:
adsc.ConfigInitialRequests(),
Config: adsc.Config{
Namespace: args.Namespace,
@@ -199,11 +202,11 @@ func (s *Server) initConfigSources(args *PlanetArgs) (err
error) {
store := memory.Make(collections.Planet)
// TODO: enable namespace filter for memory controller
configController := memory.NewController(store)
-
configController.RegisterHasSyncedHandler(xdsMCP.HasSynced)
- xdsMCP.Store = configController
- err = xdsMCP.Run()
+
configController.RegisterHasSyncedHandler(xdsClient.HasSynced)
+ xdsClient.Store = configController
+ err = xdsClient.Run()
if err != nil {
- return fmt.Errorf("MCP: failed running %v", err)
+ return fmt.Errorf("XDS config source: failed
running %v", err)
}
s.ConfigStores = append(s.ConfigStores,
configController)
log.Infof("Started XDS configSource %s",
configSource.Address)
@@ -230,7 +233,8 @@ func (s *Server) initConfigSources(args *PlanetArgs) (err
error) {
func (s *Server) initConfigController(args *PlanetArgs) error {
meshGlobalConfig := s.environment.Mesh()
if len(meshGlobalConfig.ConfigSources) > 0 {
- // Using MCP for config.
+ // XDS config source support (legacy - MCP protocol removed)
+ // Note: MCP was a legacy protocol replaced by APIGenerator in
Istio
if err := s.initConfigSources(args); err != nil {
return err
}
diff --git a/dubbod/planet/pkg/bootstrap/server.go
b/dubbod/planet/pkg/bootstrap/server.go
index 046e3282..556d2d5b 100644
--- a/dubbod/planet/pkg/bootstrap/server.go
+++ b/dubbod/planet/pkg/bootstrap/server.go
@@ -491,8 +491,8 @@ func (s *Server) initRegistryEventHandlers() {
var configKind kind.Kind
switch schemaID {
- case "SubsetRule":
- configKind = kind.SubsetRule
+ case "DestinationRule":
+ configKind = kind.DestinationRule
case "serviceRoute", "ServiceRoute":
configKind = kind.ServiceRoute
case "PeerAuthentication":
@@ -517,18 +517,18 @@ func (s *Server) initRegistryEventHandlers() {
// Log the config change
log.Infof("configHandler: %s event for %s/%s/%s", event,
configKey.Kind, configKey.Namespace, configKey.Name)
- // Some configs
(SubsetRule/ServiceRoute/PeerAuthentication/HTTPRoute) require Full push to
ensure
+ // Some configs
(DestinationRule/ServiceRoute/PeerAuthentication/HTTPRoute) require Full push
to ensure
// PushContext is re-initialized and configuration is reloaded.
// PeerAuthentication must rebuild AuthenticationPolicies to
enable STRICT mTLS on LDS; without
// a full push the cached PushContext would continue serving
plaintext listeners.
// HTTPRoute must rebuild HTTPRoute index to enable Gateway API
routing.
- needsFullPush := configKind == kind.SubsetRule || configKind ==
kind.ServiceRoute || configKind == kind.PeerAuthentication || configKind ==
kind.HTTPRoute
+ needsFullPush := configKind == kind.DestinationRule ||
configKind == kind.ServiceRoute || configKind == kind.PeerAuthentication ||
configKind == kind.HTTPRoute
// Trigger ConfigUpdate to push changes to all connected proxies
s.XDSServer.ConfigUpdate(&model.PushRequest{
ConfigsUpdated: sets.New(configKey),
Reason:
model.NewReasonStats(model.DependentResource),
- Full: needsFullPush, // Full push for
SubsetRule/ServiceRoute to reload PushContext
+ Full: needsFullPush, // Full push for
DestinationRule/ServiceRoute to reload PushContext
})
}
schemas := collections.Planet.All()
diff --git a/dubbod/planet/pkg/config/kube/crdclient/client.go
b/dubbod/planet/pkg/config/kube/crdclient/client.go
index fe04e088..d5a361f7 100644
--- a/dubbod/planet/pkg/config/kube/crdclient/client.go
+++ b/dubbod/planet/pkg/config/kube/crdclient/client.go
@@ -206,10 +206,10 @@ func (cl *Client) addCRD(name string, opts
krt.OptionsBuilder) {
if s.IsBuiltin() {
kc = kclient.NewUntypedInformer(cl.client, gvr, filter)
} else {
- // For SubsetRule and ServiceRoute, we use Dynamic client which
returns unstructured objects
+ // For DestinationRule and ServiceRoute, we use Dynamic client
which returns unstructured objects
// So we need to use DynamicInformer type to ensure the
informer expects unstructured objects
informerType := kubetypes.StandardInformer
- if resourceGVK == gvk.SubsetRule || resourceGVK ==
gvk.ServiceRoute || resourceGVK == gvk.PeerAuthentication {
+ if resourceGVK == gvk.DestinationRule || resourceGVK ==
gvk.ServiceRoute || resourceGVK == gvk.PeerAuthentication {
informerType = kubetypes.DynamicInformer
cl.logger.Debugf("addCRD: using DynamicInformer for %v
(uses Dynamic client)", resourceGVK)
}
diff --git a/dubbod/planet/pkg/config/kube/crdclient/types.go
b/dubbod/planet/pkg/config/kube/crdclient/types.go
index dc34fa2a..59895f25 100644
--- a/dubbod/planet/pkg/config/kube/crdclient/types.go
+++ b/dubbod/planet/pkg/config/kube/crdclient/types.go
@@ -21,11 +21,11 @@ import (
"context"
"fmt"
+ dubboapimetav1alpha1
"github.com/apache/dubbo-kubernetes/api/meta/v1alpha1"
"github.com/apache/dubbo-kubernetes/pkg/config"
"github.com/apache/dubbo-kubernetes/pkg/config/schema/gvk"
"github.com/apache/dubbo-kubernetes/pkg/kube"
"github.com/apache/dubbo-kubernetes/pkg/util/protomarshal"
- istioioapimetav1alpha1 "istio.io/api/meta/v1alpha1"
istioioapinetworkingv1alpha3 "istio.io/api/networking/v1alpha3"
istioioapisecurityv1beta1 "istio.io/api/security/v1beta1"
apiistioioapinetworkingv1 "istio.io/client-go/pkg/apis/networking/v1"
@@ -54,8 +54,8 @@ func assignSpec[T any](dst *T, src *T) {
func create(c kube.Client, cfg config.Config, objMeta metav1.ObjectMeta)
(metav1.Object, error) {
switch cfg.GroupVersionKind {
- case gvk.SubsetRule:
- // SubsetRule uses networking.dubbo.apache.org API group, not
networking.istio.io
+ case gvk.DestinationRule:
+ // DestinationRule uses networking.dubbo.apache.org API group,
not networking.istio.io
// Use Dynamic client to access it, but reuse Istio's
DestinationRule spec structure
spec := cfg.Spec.(*istioioapinetworkingv1alpha3.DestinationRule)
clonedSpec := protomarshal.Clone(spec)
@@ -71,13 +71,13 @@ func create(c kube.Client, cfg config.Config, objMeta
metav1.ObjectMeta) (metav1
u := &unstructured.Unstructured{Object: uObj}
u.SetGroupVersionKind(schema.GroupVersionKind{
Group: "networking.dubbo.apache.org",
- Version: "v1",
- Kind: "SubsetRule",
+ Version: "v1alpha3",
+ Kind: "DestinationRule",
})
return c.Dynamic().Resource(schema.GroupVersionResource{
Group: "networking.dubbo.apache.org",
- Version: "v1",
- Resource: "subsetrules",
+ Version: "v1alpha3",
+ Resource: "destinationrules",
}).Namespace(cfg.Namespace).Create(context.TODO(), u,
metav1.CreateOptions{})
case gvk.PeerAuthentication:
spec := cfg.Spec.(*istioioapisecurityv1beta1.PeerAuthentication)
@@ -148,8 +148,8 @@ func create(c kube.Client, cfg config.Config, objMeta
metav1.ObjectMeta) (metav1
func update(c kube.Client, cfg config.Config, objMeta metav1.ObjectMeta)
(metav1.Object, error) {
switch cfg.GroupVersionKind {
- case gvk.SubsetRule:
- // SubsetRule uses networking.dubbo.apache.org API group, use
Dynamic client
+ case gvk.DestinationRule:
+ // DestinationRule uses networking.dubbo.apache.org API group,
use Dynamic client
spec := cfg.Spec.(*istioioapinetworkingv1alpha3.DestinationRule)
clonedSpec := protomarshal.Clone(spec)
obj := &apiistioioapinetworkingv1.DestinationRule{
@@ -163,13 +163,13 @@ func update(c kube.Client, cfg config.Config, objMeta
metav1.ObjectMeta) (metav1
u := &unstructured.Unstructured{Object: uObj}
u.SetGroupVersionKind(schema.GroupVersionKind{
Group: "networking.dubbo.apache.org",
- Version: "v1",
- Kind: "SubsetRule",
+ Version: "v1alpha3",
+ Kind: "DestinationRule",
})
return c.Dynamic().Resource(schema.GroupVersionResource{
Group: "networking.dubbo.apache.org",
- Version: "v1",
- Resource: "subsetrules",
+ Version: "v1alpha3",
+ Resource: "destinationrules",
}).Namespace(cfg.Namespace).Update(context.TODO(), u,
metav1.UpdateOptions{})
case gvk.PeerAuthentication:
spec := cfg.Spec.(*istioioapisecurityv1beta1.PeerAuthentication)
@@ -238,9 +238,9 @@ func update(c kube.Client, cfg config.Config, objMeta
metav1.ObjectMeta) (metav1
func updateStatus(c kube.Client, cfg config.Config, objMeta metav1.ObjectMeta)
(metav1.Object, error) {
switch cfg.GroupVersionKind {
- case gvk.SubsetRule:
- // SubsetRule uses networking.dubbo.apache.org API group, use
Dynamic client
- status := cfg.Status.(*istioioapimetav1alpha1.IstioStatus)
+ case gvk.DestinationRule:
+ // DestinationRule uses networking.dubbo.apache.org API group,
use Dynamic client
+ status := cfg.Status.(*dubboapimetav1alpha1.DubboStatus)
clonedStatus := protomarshal.Clone(status)
obj := &apiistioioapinetworkingv1.DestinationRule{
ObjectMeta: objMeta,
@@ -253,16 +253,16 @@ func updateStatus(c kube.Client, cfg config.Config,
objMeta metav1.ObjectMeta) (
u := &unstructured.Unstructured{Object: uObj}
u.SetGroupVersionKind(schema.GroupVersionKind{
Group: "networking.dubbo.apache.org",
- Version: "v1",
- Kind: "SubsetRule",
+ Version: "v1alpha3",
+ Kind: "DestinationRule",
})
return c.Dynamic().Resource(schema.GroupVersionResource{
Group: "networking.dubbo.apache.org",
- Version: "v1",
- Resource: "subsetrules",
+ Version: "v1alpha3",
+ Resource: "destinationrules",
}).Namespace(cfg.Namespace).UpdateStatus(context.TODO(), u,
metav1.UpdateOptions{})
case gvk.PeerAuthentication:
- status := cfg.Status.(*istioioapimetav1alpha1.IstioStatus)
+ status := cfg.Status.(*dubboapimetav1alpha1.DubboStatus)
clonedStatus := protomarshal.Clone(status)
obj := &apiistioioapisecurityv1.PeerAuthentication{
ObjectMeta: objMeta,
@@ -285,7 +285,7 @@ func updateStatus(c kube.Client, cfg config.Config, objMeta
metav1.ObjectMeta) (
}).Namespace(cfg.Namespace).UpdateStatus(context.TODO(), u,
metav1.UpdateOptions{})
case gvk.ServiceRoute:
// ServiceRoute uses networking.dubbo.apache.org API group, use
Dynamic client
- status := cfg.Status.(*istioioapimetav1alpha1.IstioStatus)
+ status := cfg.Status.(*dubboapimetav1alpha1.DubboStatus)
clonedStatus := protomarshal.Clone(status)
obj := &apiistioioapinetworkingv1.VirtualService{
ObjectMeta: objMeta,
@@ -331,8 +331,8 @@ func patch(c kube.Client, orig config.Config, origMeta
metav1.ObjectMeta, mod co
return nil, fmt.Errorf("gvk mismatch: %v, modified: %v",
orig.GroupVersionKind, mod.GroupVersionKind)
}
switch orig.GroupVersionKind {
- case gvk.SubsetRule:
- // SubsetRule uses networking.dubbo.apache.org API group, use
Dynamic client
+ case gvk.DestinationRule:
+ // DestinationRule uses networking.dubbo.apache.org API group,
use Dynamic client
origSpec :=
orig.Spec.(*istioioapinetworkingv1alpha3.DestinationRule)
modSpec :=
mod.Spec.(*istioioapinetworkingv1alpha3.DestinationRule)
clonedOrigSpec := protomarshal.Clone(origSpec)
@@ -351,8 +351,8 @@ func patch(c kube.Client, orig config.Config, origMeta
metav1.ObjectMeta, mod co
}
return c.Dynamic().Resource(schema.GroupVersionResource{
Group: "networking.dubbo.apache.org",
- Version: "v1",
- Resource: "subsetrules",
+ Version: "v1alpha3",
+ Resource: "destinationrules",
}).Namespace(orig.Namespace).Patch(context.TODO(), orig.Name,
typ, patchBytes, metav1.PatchOptions{FieldManager: "planet-discovery"})
case gvk.PeerAuthentication:
origSpec :=
orig.Spec.(*istioioapisecurityv1beta1.PeerAuthentication)
@@ -455,12 +455,12 @@ func delete(c kube.Client, typ config.GroupVersionKind,
name, namespace string,
deleteOptions.Preconditions =
&metav1.Preconditions{ResourceVersion: resourceVersion}
}
switch typ {
- case gvk.SubsetRule:
- // SubsetRule uses networking.dubbo.apache.org API group, use
Dynamic client
+ case gvk.DestinationRule:
+ // DestinationRule uses networking.dubbo.apache.org API group,
use Dynamic client
return c.Dynamic().Resource(schema.GroupVersionResource{
Group: "networking.dubbo.apache.org",
- Version: "v1",
- Resource: "subsetrules",
+ Version: "v1alpha3",
+ Resource: "destinationrules",
}).Namespace(namespace).Delete(context.TODO(), name,
deleteOptions)
case gvk.PeerAuthentication:
return c.Dynamic().Resource(schema.GroupVersionResource{
@@ -559,7 +559,7 @@ var translationMap = map[config.GroupVersionKind]func(r
runtime.Object) config.C
Spec: &obj.Spec,
}
},
- gvk.SubsetRule: func(r runtime.Object) config.Config {
+ gvk.DestinationRule: func(r runtime.Object) config.Config {
var obj *apiistioioapinetworkingv1.DestinationRule
// Handle unstructured objects from Dynamic client
// First try to convert from unstructured, as Dynamic client
returns unstructured objects
@@ -583,12 +583,12 @@ var translationMap = map[config.GroupVersionKind]func(r
runtime.Object) config.C
panic(fmt.Sprintf("failed to convert
object %T to DestinationRule: %v", r, err))
}
} else {
- panic(fmt.Sprintf("unexpected object type for
SubsetRule: %T, expected *unstructured.Unstructured or
*apiistioioapinetworkingv1.DestinationRule, conversion error: %v", r, err))
+ panic(fmt.Sprintf("unexpected object type for
DestinationRule: %T, expected *unstructured.Unstructured or
*apiistioioapinetworkingv1.DestinationRule, conversion error: %v", r, err))
}
}
return config.Config{
Meta: config.Meta{
- GroupVersionKind: gvk.SubsetRule,
+ GroupVersionKind: gvk.DestinationRule,
Name: obj.Name,
Namespace: obj.Namespace,
Labels: obj.Labels,
diff --git a/dubbod/planet/pkg/features/experimental.go
b/dubbod/planet/pkg/features/experimental.go
index ce09bff6..699de332 100644
--- a/dubbod/planet/pkg/features/experimental.go
+++ b/dubbod/planet/pkg/features/experimental.go
@@ -24,8 +24,8 @@ var (
EnableLeaderElection = env.Register("ENABLE_LEADER_ELECTION", true,
"If enabled (default), starts a leader election client and
gains leadership before executing controllers. "+
"If false, it assumes that only one instance of dubbod
is running and skips leader election.").Get()
- EnableEnhancedSubsetRuleMerge =
env.Register("ENABLE_ENHANCED_DESTINATIONRULE_MERGE", true,
- "If enabled, Dubbo merge subsetrules considering their exportTo
fields,"+
+ EnableEnhancedDestinationRuleMerge =
env.Register("ENABLE_ENHANCED_DESTINATIONRULE_MERGE", true,
+ "If enabled, Dubbo merge destinationrules considering their
exportTo fields,"+
" they will be kept as independent rules if the
exportTos are not equal.").Get()
EnableGatewayAPI = env.Register("PLANET_ENABLE_GATEWAY_API", true,
"If this is set to true, support for Kubernetes gateway-api
(github.com/kubernetes-sigs/gateway-api) will "+
diff --git a/dubbod/planet/pkg/model/subsetrule.go
b/dubbod/planet/pkg/model/destinationrule.go
similarity index 88%
rename from dubbod/planet/pkg/model/subsetrule.go
rename to dubbod/planet/pkg/model/destinationrule.go
index 7d92f477..cb409d40 100644
--- a/dubbod/planet/pkg/model/subsetrule.go
+++ b/dubbod/planet/pkg/model/destinationrule.go
@@ -27,7 +27,7 @@ import (
"k8s.io/apimachinery/pkg/types"
)
-func (ps *PushContext) mergeSubsetRule(p *consolidatedSubRules, subRuleConfig
config.Config, exportToSet sets.Set[visibility.Instance]) {
+func (ps *PushContext) mergeDestinationRule(p *consolidatedSubRules,
subRuleConfig config.Config, exportToSet sets.Set[visibility.Instance]) {
rule := subRuleConfig.Spec.(*networking.DestinationRule)
resolvedHost := host.Name(rule.Host)
@@ -40,11 +40,11 @@ func (ps *PushContext) mergeSubsetRule(p
*consolidatedSubRules, subRuleConfig co
}
if mdrList, exists := subRules[resolvedHost]; exists {
- log.Infof("mergeSubsetRule: found existing rules for host %s
(count: %d)", resolvedHost, len(mdrList))
+ log.Infof("mergeDestinationRule: found existing rules for host
%s (count: %d)", resolvedHost, len(mdrList))
// `appendSeparately` determines if the incoming destination
rule would become a new unique entry in the processedDestRules list.
appendSeparately := true
for _, mdr := range mdrList {
- if features.EnableEnhancedSubsetRuleMerge {
+ if features.EnableEnhancedDestinationRuleMerge {
if exportToSet.Equals(mdr.exportTo) {
appendSeparately = false
} else if len(mdr.exportTo) > 0 &&
exportToSet.SupersetOf(mdr.exportTo) {
@@ -72,7 +72,7 @@ func (ps *PushContext) mergeSubsetRule(p
*consolidatedSubRules, subRuleConfig co
// at the same time added as a unique entry in the
processedDestRules.
if bothWithoutSelector || (bothWithSelector &&
selectorsMatch) {
appendSeparately = false
- log.Debugf("mergeSubsetRule: will merge rules
for host %s (bothWithoutSelector: %v, bothWithSelector: %v, selectorsMatch:
%v)",
+ log.Debugf("mergeDestinationRule: will merge
rules for host %s (bothWithoutSelector: %v, bothWithSelector: %v,
selectorsMatch: %v)",
resolvedHost, bothWithoutSelector,
bothWithSelector, selectorsMatch)
}
@@ -99,7 +99,7 @@ func (ps *PushContext) mergeSubsetRule(p
*consolidatedSubRules, subRuleConfig co
}
// Merge top-level traffic policy. Historically we only
copied the first non-nil policy,
- // which meant a later SubsetRule that supplied TLS
settings was ignored once a prior
+ // which meant a later DestinationRule that supplied
TLS settings was ignored once a prior
// rule (e.g. subsets only) existed. To match Istio's
behavior and ensure Proxyless gRPC
// can enable mTLS after subsets are defined, allow the
incoming rule to override the TLS
// portion even when a Common TrafficPolicy already
exists.
@@ -107,14 +107,14 @@ func (ps *PushContext) mergeSubsetRule(p
*consolidatedSubRules, subRuleConfig co
if mergedRule.TrafficPolicy == nil {
// First rule with TrafficPolicy, copy
it entirely
mergedRule.TrafficPolicy =
rule.TrafficPolicy
- log.Infof("mergeSubsetRule: copied
TrafficPolicy from new rule to merged rule for host %s (has TLS: %v)",
+ log.Infof("mergeDestinationRule: copied
TrafficPolicy from new rule to merged rule for host %s (has TLS: %v)",
resolvedHost,
rule.TrafficPolicy.Tls != nil)
} else {
// Merge TrafficPolicy fields, with TLS
settings from the latest rule taking precedence
if rule.TrafficPolicy.Tls != nil {
// TLS settings from the latest
rule always win (ISTIO_MUTUAL/DUBBO_MUTUAL)
mergedRule.TrafficPolicy.Tls =
rule.TrafficPolicy.Tls
- log.Infof("mergeSubsetRule:
updated TLS settings in merged TrafficPolicy for host %s (mode: %v)",
+
log.Infof("mergeDestinationRule: updated TLS settings in merged TrafficPolicy
for host %s (mode: %v)",
resolvedHost,
rule.TrafficPolicy.Tls.Mode)
}
// Merge other TrafficPolicy fields if
needed (loadBalancer, connectionPool, etc.)
diff --git a/dubbod/planet/pkg/model/push_context.go
b/dubbod/planet/pkg/model/push_context.go
index f209cc03..22336fcc 100644
--- a/dubbod/planet/pkg/model/push_context.go
+++ b/dubbod/planet/pkg/model/push_context.go
@@ -77,7 +77,7 @@ type PushContext struct {
ServiceIndex serviceIndex
serviceRouteIndex serviceRouteIndex
httpRouteIndex httpRouteIndex
- subsetRuleIndex subsetRuleIndex
+ destinationRuleIndex destinationRuleIndex
serviceAccounts map[serviceAccountKey][]string
AuthenticationPolicies *AuthenticationPolicies
PushVersion string
@@ -141,7 +141,7 @@ type ConsolidatedSubRule struct {
type exportToDefaults struct {
service sets.Set[visibility.Instance]
serviceRoute sets.Set[visibility.Instance]
- subsetRule sets.Set[visibility.Instance]
+ destinationRule sets.Set[visibility.Instance]
}
type serviceRouteIndex struct {
@@ -160,7 +160,7 @@ type httpRouteIndex struct {
hostToRoutes map[host.Name][]config.Config
}
-type subsetRuleIndex struct {
+type destinationRuleIndex struct {
namespaceLocal map[string]*consolidatedSubRules
exportedByNamespace map[string]*consolidatedSubRules
rootNamespaceLocal *consolidatedSubRules
@@ -175,7 +175,7 @@ func NewPushContext() *PushContext {
return &PushContext{
ServiceIndex: newServiceIndex(),
serviceRouteIndex: newServiceRouteIndex(),
- subsetRuleIndex: newSubsetRuleIndex(),
+ destinationRuleIndex: newDestinationRuleIndex(),
serviceAccounts: map[serviceAccountKey][]string{},
}
}
@@ -199,8 +199,8 @@ func newServiceRouteIndex() serviceRouteIndex {
return out
}
-func newSubsetRuleIndex() subsetRuleIndex {
- return subsetRuleIndex{
+func newDestinationRuleIndex() destinationRuleIndex {
+ return destinationRuleIndex{
namespaceLocal: map[string]*consolidatedSubRules{},
exportedByNamespace: map[string]*consolidatedSubRules{},
}
@@ -315,14 +315,14 @@ func (pr *PushRequest) PushReason() string {
}
func (ps *PushContext) initDefaultExportMaps() {
- ps.exportToDefaults.subsetRule = sets.New[visibility.Instance]()
+ ps.exportToDefaults.destinationRule = sets.New[visibility.Instance]()
if ps.Mesh.DefaultDestinationRuleExportTo != nil {
for _, e := range ps.Mesh.DefaultDestinationRuleExportTo {
-
ps.exportToDefaults.subsetRule.Insert(visibility.Instance(e))
+
ps.exportToDefaults.destinationRule.Insert(visibility.Instance(e))
}
} else {
// default to *
- ps.exportToDefaults.subsetRule.Insert(visibility.Public)
+ ps.exportToDefaults.destinationRule.Insert(visibility.Public)
}
ps.exportToDefaults.service = sets.New[visibility.Instance]()
@@ -532,7 +532,7 @@ func (ps *PushContext) createNewContext(env *Environment) {
ps.initKubernetesGateways(env)
ps.initServiceRoutes(env)
ps.initHTTPRoutes(env)
- ps.initSubsetRules(env)
+ ps.initDestinationRules(env)
ps.initAuthenticationPolicies(env)
}
@@ -562,27 +562,27 @@ func (ps *PushContext) updateContext(env *Environment,
oldPushContext *PushConte
}
}
- // Check if subsetRules have changed base on:
- // 1. SubsetRule updates in ConfigsUpdated
+ // Check if destinationrules have changed base on:
+ // 1. DestinationRule updates in ConfigsUpdated
// 2. Full push (Full: true) - always re-initialize on full push
- subsetRulesChanged := pushReq != nil && (pushReq.Full ||
HasConfigsOfKind(pushReq.ConfigsUpdated, kind.SubsetRule) ||
+ destinationRuleChanged := pushReq != nil && (pushReq.Full ||
HasConfigsOfKind(pushReq.ConfigsUpdated, kind.DestinationRule) ||
len(pushReq.AddressesUpdated) > 0)
if pushReq != nil {
- subsetRuleCount := 0
+ destinationRuleCount := 0
for cfg := range pushReq.ConfigsUpdated {
- if cfg.Kind == kind.SubsetRule {
- subsetRuleCount++
+ if cfg.Kind == kind.DestinationRule {
+ destinationRuleCount++
}
}
- if subsetRuleCount > 0 {
- log.Debugf("updateContext: detected %d SubsetRule
config changes", subsetRuleCount)
+ if destinationRuleCount > 0 {
+ log.Debugf("updateContext: detected %d DestinationRule
config changes", destinationRuleCount)
}
if pushReq.Full {
- log.Debugf("updateContext: Full push requested, will
re-initialize SubsetRule and ServiceRoute indexes")
+ log.Debugf("updateContext: Full push requested, will
re-initialize DestinationRule and ServiceRoute indexes")
}
- log.Debugf("updateContext: subsetRulesChanged=%v,
serviceRoutesChanged=%v, pushReq.ConfigsUpdated size=%d, Full=%v",
- subsetRulesChanged, serviceRoutesChanged,
len(pushReq.ConfigsUpdated), pushReq != nil && pushReq.Full)
+ log.Debugf("updateContext: destinationRuleChanged=%v,
serviceRoutesChanged=%v, pushReq.ConfigsUpdated size=%d, Full=%v",
+ destinationRuleChanged, serviceRoutesChanged,
len(pushReq.ConfigsUpdated), pushReq != nil && pushReq.Full)
}
// Also check if the actual number of services has changed
@@ -636,12 +636,12 @@ func (ps *PushContext) updateContext(env *Environment,
oldPushContext *PushConte
ps.httpRouteIndex = oldPushContext.httpRouteIndex
}
- if subsetRulesChanged {
- log.Debugf("updateContext: SubsetRules changed, re-initializing
SubsetRule index")
- ps.initSubsetRules(env)
+ if destinationRuleChanged {
+ log.Debugf("updateContext: DestinationRules changed,
re-initializing DestinationRule index")
+ ps.initDestinationRules(env)
} else {
- log.Debugf("updateContext: SubsetRules unchanged, reusing old
SubsetRule index")
- ps.subsetRuleIndex = oldPushContext.subsetRuleIndex
+ log.Debugf("updateContext: DestinationRules unchanged, reusing
old DestinationRule index")
+ ps.destinationRuleIndex = oldPushContext.destinationRuleIndex
}
authnPoliciesChanged := pushReq != nil && (pushReq.Full ||
HasConfigsOfKind(pushReq.ConfigsUpdated, kind.PeerAuthentication))
@@ -892,7 +892,7 @@ func sortConfigBySelectorAndCreationTime(configs
[]config.Config) []config.Confi
return configs
}
-func (ps *PushContext) setSubsetRules(configs []config.Config) {
+func (ps *PushContext) setDestinationRules(configs []config.Config) {
sortConfigBySelectorAndCreationTime(configs)
namespaceLocalSubRules := make(map[string]*consolidatedSubRules)
@@ -927,13 +927,13 @@ func (ps *PushContext) setSubsetRules(configs
[]config.Config) {
}
// Merge this destination rule with any public/private
dest rules for same host in the same namespace
// If there are no duplicates, the dest rule will be
added to the list
-
ps.mergeSubsetRule(namespaceLocalSubRules[configs[i].Namespace], configs[i],
exportToSet)
+
ps.mergeDestinationRule(namespaceLocalSubRules[configs[i].Namespace],
configs[i], exportToSet)
}
isPrivateOnly := false
// No exportTo in destinationRule. Use the global default
// We only honor . and *
- if exportToSet.IsEmpty() &&
ps.exportToDefaults.subsetRule.Contains(visibility.Private) {
+ if exportToSet.IsEmpty() &&
ps.exportToDefaults.destinationRule.Contains(visibility.Private) {
isPrivateOnly = true
} else if exportToSet.Len() == 1 &&
(exportToSet.Contains(visibility.Private) ||
exportToSet.Contains(visibility.Instance(configs[i].Namespace))) {
isPrivateOnly = true
@@ -943,18 +943,18 @@ func (ps *PushContext) setSubsetRules(configs
[]config.Config) {
if _, exist :=
exportedDestRulesByNamespace[configs[i].Namespace]; !exist {
exportedDestRulesByNamespace[configs[i].Namespace] = newConsolidatedDestRules()
}
-
ps.mergeSubsetRule(exportedDestRulesByNamespace[configs[i].Namespace],
configs[i], exportToSet)
+
ps.mergeDestinationRule(exportedDestRulesByNamespace[configs[i].Namespace],
configs[i], exportToSet)
} else if configs[i].Namespace == ps.Mesh.RootNamespace {
- ps.mergeSubsetRule(rootNamespaceLocalDestRules,
configs[i], exportToSet)
+ ps.mergeDestinationRule(rootNamespaceLocalDestRules,
configs[i], exportToSet)
}
}
- ps.subsetRuleIndex.namespaceLocal = namespaceLocalSubRules
- ps.subsetRuleIndex.exportedByNamespace = exportedDestRulesByNamespace
- ps.subsetRuleIndex.rootNamespaceLocal = rootNamespaceLocalDestRules
+ ps.destinationRuleIndex.namespaceLocal = namespaceLocalSubRules
+ ps.destinationRuleIndex.exportedByNamespace =
exportedDestRulesByNamespace
+ ps.destinationRuleIndex.rootNamespaceLocal = rootNamespaceLocalDestRules
// Log indexing results
- log.Debugf("setSubsetRules: indexed %d namespaces with local rules",
len(namespaceLocalSubRules))
+ log.Debugf("setDestinationRules: indexed %d namespaces with local
rules", len(namespaceLocalSubRules))
for ns, rules := range namespaceLocalSubRules {
totalRules := 0
for hostname, ruleList := range rules.specificSubRules {
@@ -967,26 +967,26 @@ func (ps *PushContext) setSubsetRules(configs
[]config.Config) {
if hasTLS {
tlsMode =
dr.TrafficPolicy.Tls.Mode.String()
}
- log.Debugf("setSubsetRules: namespace
%s, hostname %s: DestinationRule has %d subsets, TLS mode: %s",
+ log.Debugf("setDestinationRules:
namespace %s, hostname %s: DestinationRule has %d subsets, TLS mode: %s",
ns, hostname, len(dr.Subsets),
tlsMode)
}
}
}
- log.Debugf("setSubsetRules: namespace %s has %d
DestinationRules with %d specific hostnames", ns, totalRules,
len(rules.specificSubRules))
+ log.Debugf("setDestinationRules: namespace %s has %d
DestinationRules with %d specific hostnames", ns, totalRules,
len(rules.specificSubRules))
}
- log.Debugf("setSubsetRules: indexed %d namespaces with exported rules",
len(exportedDestRulesByNamespace))
+ log.Debugf("setDestinationRules: indexed %d namespaces with exported
rules", len(exportedDestRulesByNamespace))
if rootNamespaceLocalDestRules != nil {
totalRootRules := 0
for _, ruleList := range
rootNamespaceLocalDestRules.specificSubRules {
totalRootRules += len(ruleList)
}
- log.Debugf("setSubsetRules: root namespace has %d
DestinationRules with %d specific hostnames", totalRootRules,
len(rootNamespaceLocalDestRules.specificSubRules))
+ log.Debugf("setDestinationRules: root namespace has %d
DestinationRules with %d specific hostnames", totalRootRules,
len(rootNamespaceLocalDestRules.specificSubRules))
}
}
-func (ps *PushContext) initSubsetRules(env *Environment) {
- configs := env.List(gvk.SubsetRule, NamespaceAll)
- log.Debugf("initSubsetRules: found %d SubsetRule configs", len(configs))
+func (ps *PushContext) initDestinationRules(env *Environment) {
+ configs := env.List(gvk.DestinationRule, NamespaceAll)
+ log.Debugf("initDestinationRules: found %d DestinationRule configs",
len(configs))
// values returned from ConfigStore.List are immutable.
// Therefore, we make a copy
@@ -998,12 +998,12 @@ func (ps *PushContext) initSubsetRules(env *Environment) {
if dr.TrafficPolicy != nil && dr.TrafficPolicy.Tls !=
nil {
tlsMode = dr.TrafficPolicy.Tls.Mode.String()
}
- log.Debugf("initSubsetRules: SubsetRule %s/%s for host
%s with %d subsets, TLS mode: %s",
+ log.Debugf("initDestinationRules: DestinationRule %s/%s
for host %s with %d subsets, TLS mode: %s",
configs[i].Namespace, configs[i].Name, dr.Host,
len(dr.Subsets), tlsMode)
}
}
- ps.setSubsetRules(subRules)
+ ps.setDestinationRules(subRules)
}
func (ps *PushContext) initServiceAccounts(env *Environment, services
[]*Service) {
@@ -1049,12 +1049,12 @@ func (ps *PushContext) ServiceRouteForHost(hostname
host.Name) *networking.Virtu
return nil
}
-// DestinationRuleForService returns the first DestinationRule (SubsetRule)
applicable to the service hostname/namespace.
+// DestinationRuleForService returns the first DestinationRule applicable to
the service hostname/namespace.
func (ps *PushContext) DestinationRuleForService(namespace string, hostname
host.Name) *networking.DestinationRule {
log.Debugf("DestinationRuleForService: looking for DestinationRule for
%s/%s", namespace, hostname)
// Check namespace-local rules first
- if nsRules := ps.subsetRuleIndex.namespaceLocal[namespace]; nsRules !=
nil {
+ if nsRules := ps.destinationRuleIndex.namespaceLocal[namespace];
nsRules != nil {
log.Debugf("DestinationRuleForService: checking namespace-local
rules for %s (found %d specific rules)", namespace,
len(nsRules.specificSubRules))
if dr := firstDestinationRule(nsRules, hostname); dr != nil {
hasTLS := dr.TrafficPolicy != nil &&
dr.TrafficPolicy.Tls != nil
@@ -1071,8 +1071,8 @@ func (ps *PushContext)
DestinationRuleForService(namespace string, hostname host
}
// Check exported rules
- log.Debugf("DestinationRuleForService: checking exported rules (found
%d exported namespaces)", len(ps.subsetRuleIndex.exportedByNamespace))
- for ns, exported := range ps.subsetRuleIndex.exportedByNamespace {
+ log.Debugf("DestinationRuleForService: checking exported rules (found
%d exported namespaces)", len(ps.destinationRuleIndex.exportedByNamespace))
+ for ns, exported := range ps.destinationRuleIndex.exportedByNamespace {
if dr := firstDestinationRule(exported, hostname); dr != nil {
hasTLS := dr.TrafficPolicy != nil &&
dr.TrafficPolicy.Tls != nil
tlsMode := "none"
@@ -1086,7 +1086,7 @@ func (ps *PushContext)
DestinationRuleForService(namespace string, hostname host
}
// Finally, check root namespace scoped rules
- if rootRules := ps.subsetRuleIndex.rootNamespaceLocal; rootRules != nil
{
+ if rootRules := ps.destinationRuleIndex.rootNamespaceLocal; rootRules
!= nil {
log.Debugf("DestinationRuleForService: checking root namespace
rules (found %d specific rules)", len(rootRules.specificSubRules))
if dr := firstDestinationRule(rootRules, hostname); dr != nil {
hasTLS := dr.TrafficPolicy != nil &&
dr.TrafficPolicy.Tls != nil
@@ -1129,7 +1129,7 @@ func firstDestinationRule(csr *consolidatedSubRules,
hostname host.Name) *networ
if rules := csr.specificSubRules[hostname]; len(rules) > 0 {
log.Infof("firstDestinationRule: found %d rules for hostname
%s", len(rules), hostname)
// The first rule should contain the merged result if merge was
successful.
- // However, if merge failed (e.g.,
EnableEnhancedSubsetRuleMerge is disabled),
+ // However, if merge failed (e.g.,
EnableEnhancedDestinationRuleMerge is disabled),
// we need to check all rules and prefer the one with TLS
configuration.
// we return the one that has TLS if available, or the first
one otherwise.
var bestRule *networking.DestinationRule
diff --git a/dubbod/planet/pkg/model/service.go
b/dubbod/planet/pkg/model/service.go
index 3a47dc6c..27e25a25 100644
--- a/dubbod/planet/pkg/model/service.go
+++ b/dubbod/planet/pkg/model/service.go
@@ -17,8 +17,6 @@
package model
import (
- "istio.io/api/annotation"
- corev1 "k8s.io/api/core/v1"
"strconv"
"strings"
"sync"
@@ -56,14 +54,6 @@ const (
Terminating HealthStatus = 4
)
-type TrafficDistribution int
-
-const (
- TrafficDistributionAny TrafficDistribution = iota
- TrafficDistributionPreferSameZone
- TrafficDistributionPreferSameNode
-)
-
type TrafficDirection string
const (
@@ -154,10 +144,6 @@ type K8sAttributes struct {
// spec.InternalTrafficPolicy == Local
NodeLocal bool
- // TrafficDistribution determines the service-level traffic
distribution.
- // This may be overridden by locality load balancing settings.
- TrafficDistribution TrafficDistribution
-
// ObjectName is the object name of the underlying object. This may
differ from the Service.Attributes.Name for legacy semantics.
ObjectName string
@@ -515,31 +501,6 @@ func (m *AddressMap) DeepCopy() *AddressMap {
}
}
-func GetTrafficDistribution(specValue *string, annotations map[string]string)
TrafficDistribution {
- if specValue != nil {
- switch *specValue {
- case corev1.ServiceTrafficDistributionPreferSameZone,
corev1.ServiceTrafficDistributionPreferClose:
- return TrafficDistributionPreferSameZone
- case corev1.ServiceTrafficDistributionPreferSameNode:
- return TrafficDistributionPreferSameNode
- }
- }
- // The TrafficDistribution field is quite new, so we allow a legacy
annotation option as well
- // This also has some custom types
- trafficDistributionAnnotationValue :=
strings.ToLower(annotations[annotation.NetworkingTrafficDistribution.Name])
- switch trafficDistributionAnnotationValue {
- case strings.ToLower(corev1.ServiceTrafficDistributionPreferClose),
strings.ToLower(corev1.ServiceTrafficDistributionPreferSameZone):
- return TrafficDistributionPreferSameZone
- case strings.ToLower(corev1.ServiceTrafficDistributionPreferSameNode):
- return TrafficDistributionPreferSameNode
- default:
- if trafficDistributionAnnotationValue != "" {
- log.Warnf("Unknown traffic distribution annotation,
defaulting to any")
- }
- return TrafficDistributionAny
- }
-}
-
func BuildSubsetKey(direction TrafficDirection, subsetName string, hostname
host.Name, port int) string {
return string(direction) + "|" + strconv.Itoa(port) + "|" + subsetName
+ "|" + string(hostname)
}
diff --git a/dubbod/planet/pkg/networking/grpcgen/cds.go
b/dubbod/planet/pkg/networking/grpcgen/cds.go
index 78a4a90c..cf90f252 100644
--- a/dubbod/planet/pkg/networking/grpcgen/cds.go
+++ b/dubbod/planet/pkg/networking/grpcgen/cds.go
@@ -239,9 +239,9 @@ func (b *clusterBuilder)
applyDestinationRule(defaultCluster *cluster.Cluster) (
// Apply TLS to default cluster if it exists and doesn't have
TransportSocket yet
// This ensures that default cluster gets TLS from the top-level
TrafficPolicy in DestinationRule
- // When SubsetRule sets ISTIO_MUTUAL, inbound listener enforces STRICT
mTLS, so outbound must also use TLS
+ // When DestinationRule sets ISTIO_MUTUAL, inbound listener enforces
STRICT mTLS, so outbound must also use TLS
// NOTE: We re-check hasTLS here because firstDestinationRule might
have returned a different rule
- // than the one checked in build(), especially when multiple
SubsetRules exist and merge failed
+ // than the one checked in build(), especially when multiple
DestinationRules exist and merge failed
if defaultCluster != nil && defaultCluster.TransportSocket == nil {
// Re-check TLS in case DestinationRule was found here but not
in build()
recheckTLS := dr != nil && dr.TrafficPolicy != nil &&
dr.TrafficPolicy.Tls != nil
diff --git a/dubbod/planet/pkg/serviceregistry/kube/controller/controller.go
b/dubbod/planet/pkg/serviceregistry/kube/controller/controller.go
index a1dbf0e9..6e393271 100644
--- a/dubbod/planet/pkg/serviceregistry/kube/controller/controller.go
+++ b/dubbod/planet/pkg/serviceregistry/kube/controller/controller.go
@@ -43,7 +43,6 @@ import (
"github.com/apache/dubbo-kubernetes/pkg/slices"
"github.com/hashicorp/go-multierror"
"go.uber.org/atomic"
- "istio.io/api/label"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
klabels "k8s.io/apimachinery/pkg/labels"
@@ -550,7 +549,7 @@ func (c *Controller) servicesForNamespacedName(name
types.NamespacedName) []*mod
func (c *Controller) Network(endpointIP string, labels labels.Instance)
network.ID {
// 1. check the pod/workloadEntry label
- if nw := labels[label.TopologyNetwork.Name]; nw != "" {
+ if nw := labels["topology.dubbo.apache.org/network"]; nw != "" {
return network.ID(nw)
}
// 2. check the system namespace labels
diff --git a/dubbod/planet/pkg/serviceregistry/kube/controller/endpointslice.go
b/dubbod/planet/pkg/serviceregistry/kube/controller/endpointslice.go
index dc616d46..65102397 100644
--- a/dubbod/planet/pkg/serviceregistry/kube/controller/endpointslice.go
+++ b/dubbod/planet/pkg/serviceregistry/kube/controller/endpointslice.go
@@ -18,18 +18,15 @@ package controller
import (
"fmt"
- "strings"
"sync"
"github.com/apache/dubbo-kubernetes/dubbod/planet/pkg/model"
"github.com/apache/dubbo-kubernetes/pkg/config"
"github.com/apache/dubbo-kubernetes/pkg/config/host"
"github.com/apache/dubbo-kubernetes/pkg/config/schema/kind"
- "github.com/apache/dubbo-kubernetes/pkg/config/visibility"
"github.com/apache/dubbo-kubernetes/pkg/kube/kclient"
"github.com/apache/dubbo-kubernetes/pkg/util/sets"
"github.com/hashicorp/go-multierror"
- "istio.io/api/annotation"
corev1 "k8s.io/api/core/v1"
v1 "k8s.io/api/discovery/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -524,15 +521,7 @@ func getServiceNamespacedName(slice *v1.EndpointSlice)
types.NamespacedName {
}
func serviceNeedsPush(svc *corev1.Service) bool {
- if svc.Annotations[annotation.NetworkingExportTo.Name] != "" {
- namespaces :=
strings.Split(svc.Annotations[annotation.NetworkingExportTo.Name], ",")
- for _, ns := range namespaces {
- ns = strings.TrimSpace(ns)
- if ns == string(visibility.None) {
- return false
- }
- }
- }
+ // In proxyless mesh, all services need to be pushed
return true
}
diff --git a/dubbod/planet/pkg/serviceregistry/kube/controller/pod.go
b/dubbod/planet/pkg/serviceregistry/kube/controller/pod.go
index e956d514..799d0c1d 100644
--- a/dubbod/planet/pkg/serviceregistry/kube/controller/pod.go
+++ b/dubbod/planet/pkg/serviceregistry/kube/controller/pod.go
@@ -24,7 +24,6 @@ import (
"github.com/apache/dubbo-kubernetes/pkg/kube/kclient"
"github.com/apache/dubbo-kubernetes/pkg/maps"
"github.com/apache/dubbo-kubernetes/pkg/util/sets"
- "istio.io/api/annotation"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
)
@@ -193,12 +192,9 @@ func (pc *PodCache) deleteIP(ip string, podKey
types.NamespacedName) bool {
}
func (pc *PodCache) labelFilter(old, cur *v1.Pod) bool {
- // If labels/annotations updated, trigger proxy push
- labelsChanged := !maps.Equal(old.Labels, cur.Labels)
- // Annotations are only used in endpoints in one case, so just compare
that one
- relevantAnnotationsChanged :=
old.Annotations[annotation.AmbientRedirection.Name] !=
cur.Annotations[annotation.AmbientRedirection.Name]
- changed := labelsChanged || relevantAnnotationsChanged
- return changed
+ // If labels updated, trigger proxy push
+ // In proxyless mesh, we don't need to check ambient redirection
annotations
+ return !maps.Equal(old.Labels, cur.Labels)
}
func (pc *PodCache) proxyUpdates(pod *v1.Pod, isPodUpdate bool) {
diff --git a/dubbod/planet/pkg/serviceregistry/kube/conversion.go
b/dubbod/planet/pkg/serviceregistry/kube/conversion.go
index 86ede643..1ab025fd 100644
--- a/dubbod/planet/pkg/serviceregistry/kube/conversion.go
+++ b/dubbod/planet/pkg/serviceregistry/kube/conversion.go
@@ -17,8 +17,6 @@
package kube
import (
- "strings"
-
meshv1alpha1 "github.com/apache/dubbo-kubernetes/api/mesh/v1alpha1"
"github.com/apache/dubbo-kubernetes/dubbod/planet/pkg/model"
"github.com/apache/dubbo-kubernetes/dubbod/planet/pkg/serviceregistry/provider"
@@ -26,10 +24,7 @@ import (
"github.com/apache/dubbo-kubernetes/pkg/config/constants"
"github.com/apache/dubbo-kubernetes/pkg/config/host"
"github.com/apache/dubbo-kubernetes/pkg/config/kube"
- "github.com/apache/dubbo-kubernetes/pkg/config/visibility"
"github.com/apache/dubbo-kubernetes/pkg/spiffe"
- "github.com/apache/dubbo-kubernetes/pkg/util/sets"
- "istio.io/api/annotation"
corev1 "k8s.io/api/core/v1"
)
@@ -41,17 +36,12 @@ func ConvertService(svc corev1.Service, domainSuffix
string, clusterID cluster.I
addrs := []string{constants.UnspecifiedIP}
resolution := model.ClientSideLB
externalName := ""
- nodeLocal := false
if svc.Spec.Type == corev1.ServiceTypeExternalName &&
svc.Spec.ExternalName != "" {
externalName = svc.Spec.ExternalName
resolution = model.Alias
}
- if svc.Spec.InternalTrafficPolicy != nil &&
*svc.Spec.InternalTrafficPolicy == corev1.ServiceInternalTrafficPolicyLocal {
- nodeLocal = true
- }
-
if svc.Spec.ClusterIP == corev1.ClusterIPNone { // headless services
should not be load balanced
resolution = model.Passthrough
} else if svc.Spec.ClusterIP != "" {
@@ -65,24 +55,6 @@ func ConvertService(svc corev1.Service, domainSuffix string,
clusterID cluster.I
for _, port := range svc.Spec.Ports {
ports = append(ports, convertPort(port))
}
- var exportTo sets.Set[visibility.Instance]
- serviceaccounts := make([]string, 0)
- if svc.Annotations[annotation.AlphaCanonicalServiceAccounts.Name] != ""
{
- serviceaccounts = append(serviceaccounts,
strings.Split(svc.Annotations[annotation.AlphaCanonicalServiceAccounts.Name],
",")...)
- }
- if svc.Annotations[annotation.AlphaKubernetesServiceAccounts.Name] !=
"" {
- for _, ksa := range
strings.Split(svc.Annotations[annotation.AlphaKubernetesServiceAccounts.Name],
",") {
- serviceaccounts = append(serviceaccounts,
kubeToDubboServiceAccount(ksa, svc.Namespace, mesh))
- }
- }
- if svc.Annotations[annotation.NetworkingExportTo.Name] != "" {
- namespaces :=
strings.Split(svc.Annotations[annotation.NetworkingExportTo.Name], ",")
- exportTo =
sets.NewWithLength[visibility.Instance](len(namespaces))
- for _, ns := range namespaces {
- ns = strings.TrimSpace(ns)
- exportTo.Insert(visibility.Instance(ns))
- }
- }
dubboService := &model.Service{
Hostname: ServiceHostname(svc.Name, svc.Namespace,
domainSuffix),
@@ -94,65 +66,19 @@ func ConvertService(svc corev1.Service, domainSuffix
string, clusterID cluster.I
Ports: ports,
DefaultAddress: addrs[0],
Resolution: resolution,
- ServiceAccounts: serviceaccounts,
ResourceVersion: svc.ResourceVersion,
Attributes: model.ServiceAttributes{
ServiceRegistry: provider.Kubernetes,
Name: svc.Name,
Namespace: svc.Namespace,
Labels: svc.Labels,
- ExportTo: exportTo,
LabelSelectors: svc.Spec.Selector,
},
}
- switch svc.Spec.Type {
- case corev1.ServiceTypeNodePort:
- if _, ok :=
svc.Annotations[annotation.TrafficNodeSelector.Name]; !ok {
- break
- }
- // store the service port to node port mappings
- portMap := make(map[uint32]uint32)
- for _, p := range svc.Spec.Ports {
- portMap[uint32(p.Port)] = uint32(p.NodePort)
- }
- dubboService.Attributes.ClusterExternalPorts =
map[cluster.ID]map[uint32]uint32{clusterID: portMap}
- // address mappings will be done elsewhere
- case corev1.ServiceTypeLoadBalancer:
- if len(svc.Status.LoadBalancer.Ingress) > 0 {
- var lbAddrs []string
- for _, ingress := range svc.Status.LoadBalancer.Ingress
{
- if len(ingress.IP) > 0 {
- lbAddrs = append(lbAddrs, ingress.IP)
- } else if len(ingress.Hostname) > 0 {
- // DO NOT resolve the DNS here. In
environments like AWS, the ELB hostname
- // does not have a repeatable DNS
address and IPs resolved at an earlier point
- // in time may not work. So, when we
get just hostnames instead of IPs, we need
- // to smartly switch from EDS to
strict_dns rather than doing the naive thing of
- // resolving the DNS name and hoping
the resolution is one-time task.
- lbAddrs = append(lbAddrs,
ingress.Hostname)
- }
- }
- if len(lbAddrs) > 0 {
- if
dubboService.Attributes.ClusterExternalAddresses == nil {
-
dubboService.Attributes.ClusterExternalAddresses = &model.AddressMap{}
- }
-
dubboService.Attributes.ClusterExternalAddresses.SetAddressesFor(clusterID,
lbAddrs)
- }
- }
- }
-
dubboService.Attributes.Type = string(svc.Spec.Type)
dubboService.Attributes.ExternalName = externalName
- dubboService.Attributes.TrafficDistribution =
model.GetTrafficDistribution(svc.Spec.TrafficDistribution, svc.Annotations)
- dubboService.Attributes.NodeLocal = nodeLocal
dubboService.Attributes.PublishNotReadyAddresses =
svc.Spec.PublishNotReadyAddresses
- if len(svc.Spec.ExternalIPs) > 0 {
- if dubboService.Attributes.ClusterExternalAddresses == nil {
- dubboService.Attributes.ClusterExternalAddresses =
&model.AddressMap{}
- }
-
dubboService.Attributes.ClusterExternalAddresses.AddAddressesFor(clusterID,
svc.Spec.ExternalIPs)
- }
return dubboService
}
@@ -164,10 +90,6 @@ func convertPort(port corev1.ServicePort) *model.Port {
}
}
-func kubeToDubboServiceAccount(saname string, ns string, mesh
*meshv1alpha1.MeshGlobalConfig) string {
- return spiffe.MustGenSpiffeURI(mesh, ns, saname)
-}
-
func SecureNamingSAN(pod *corev1.Pod, mesh *meshv1alpha1.MeshGlobalConfig)
string {
return spiffe.MustGenSpiffeURI(mesh, pod.Namespace,
pod.Spec.ServiceAccountName)
}
diff --git a/dubbod/planet/pkg/serviceregistry/util/label/label.go
b/dubbod/planet/pkg/serviceregistry/util/label/label.go
index d0b065ae..7b2db81e 100644
--- a/dubbod/planet/pkg/serviceregistry/util/label/label.go
+++ b/dubbod/planet/pkg/serviceregistry/util/label/label.go
@@ -17,61 +17,31 @@
package label
import (
- "strings"
-
"github.com/apache/dubbo-kubernetes/pkg/cluster"
"github.com/apache/dubbo-kubernetes/pkg/config/labels"
"github.com/apache/dubbo-kubernetes/pkg/network"
- "istio.io/api/label"
)
const (
- LabelHostname = "kubernetes.io/hostname"
-
- LabelTopologyZone = "topology.kubernetes.io/zone"
- LabelTopologySubzone = "topology.dubbo.apache.org/subzone"
- LabelTopologyRegion = "topology.kubernetes.io/region"
+ LabelTopologyCluster = "topology.dubbo.apache.org/cluster"
+ LabelTopologyNetwork = "topology.dubbo.apache.org/network"
)
func AugmentLabels(in labels.Instance, clusterID cluster.ID, locality, k8sNode
string, networkID network.ID) labels.Instance {
// Copy the original labels to a new map.
- out := make(labels.Instance, len(in)+6)
+ out := make(labels.Instance, len(in)+2)
for k, v := range in {
out[k] = v
}
- region, zone, subzone := SplitLocalityLabel(locality)
- if len(region) > 0 {
- out[LabelTopologyRegion] = region
- }
- if len(zone) > 0 {
- out[LabelTopologyZone] = zone
- }
- if len(subzone) > 0 {
- out[label.TopologySubzone.Name] = subzone
- }
+ // In proxyless mesh, locality is not used, so we skip
region/zone/subzone labels
if len(clusterID) > 0 {
- out[label.TopologyCluster.Name] = clusterID.String()
- }
- if len(k8sNode) > 0 {
- out[LabelHostname] = k8sNode
+ out[LabelTopologyCluster] = clusterID.String()
}
// In c.Network(), we already set the network label in priority order
pod labels > namespace label
// We won't let proxy.Metadata.Network override the above.
- if len(networkID) > 0 && out[label.TopologyNetwork.Name] == "" {
- out[label.TopologyNetwork.Name] = networkID.String()
+ if len(networkID) > 0 && out[LabelTopologyNetwork] == "" {
+ out[LabelTopologyNetwork] = networkID.String()
}
return out
}
-
-func SplitLocalityLabel(locality string) (region, zone, subzone string) {
- items := strings.Split(locality, "/")
- switch len(items) {
- case 1:
- return items[0], "", ""
- case 2:
- return items[0], items[1], ""
- default:
- return items[0], items[1], items[2]
- }
-}
diff --git a/dubbod/planet/pkg/xds/cds.go b/dubbod/planet/pkg/xds/cds.go
index 7bf7987a..733f7319 100644
--- a/dubbod/planet/pkg/xds/cds.go
+++ b/dubbod/planet/pkg/xds/cds.go
@@ -34,11 +34,11 @@ func cdsNeedsPush(req *model.PushRequest, proxy
*model.Proxy) (*model.PushReques
}
// with TLS configuration (ISTIO_MUTUAL), CDS must be pushed to update
cluster TransportSocket.
- // Even if req.Full is false, we need to check if SubsetRule was
updated, as it affects cluster TLS config.
+ // Even if req.Full is false, we need to check if DestinationRule was
updated, as it affects cluster TLS config.
if req != nil && req.ConfigsUpdated != nil {
- // Check if SubsetRule was updated - this requires CDS push to
update cluster TransportSocket
- if model.HasConfigsOfKind(req.ConfigsUpdated, kind.SubsetRule) {
- log.Debugf("cdsNeedsPush: SubsetRule updated, CDS push
required to update cluster TLS config")
+ // Check if DestinationRule was updated - this requires CDS
push to update cluster TransportSocket
+ if model.HasConfigsOfKind(req.ConfigsUpdated,
kind.DestinationRule) {
+ log.Debugf("cdsNeedsPush: DestinationRule updated, CDS
push required to update cluster TLS config")
return req, true
}
}
diff --git a/go.mod b/go.mod
index 72963c4b..719cf87c 100644
--- a/go.mod
+++ b/go.mod
@@ -158,6 +158,7 @@ require (
github.com/gobwas/glob v0.2.3 // indirect
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da //
indirect
+ github.com/gomarkdown/markdown v0.0.0-20250810172220-2e2c11897d1a //
indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/gnostic-models v0.7.0 // indirect
github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a // indirect
diff --git a/go.sum b/go.sum
index c7a2c11a..208bf724 100644
--- a/go.sum
+++ b/go.sum
@@ -343,6 +343,8 @@ github.com/golang/protobuf v1.4.0/go.mod
h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
github.com/golang/protobuf v1.4.1/go.mod
h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.5.4
h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod
h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
+github.com/gomarkdown/markdown v0.0.0-20250810172220-2e2c11897d1a
h1:l7A0loSszR5zHd/qK53ZIHMO8b3bBSmENnQ6eKnUT0A=
+github.com/gomarkdown/markdown v0.0.0-20250810172220-2e2c11897d1a/go.mod
h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
github.com/google/btree v1.1.3/go.mod
h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/generative-ai-go v0.15.1
h1:n8aQUpvhPOlGVuM2DRkJ2jvx04zpp42B778AROJa+pQ=
diff --git a/manifests/charts/base/files/crd-all.yaml
b/manifests/charts/base/files/crd-all.yaml
index 96333392..91b32e55 100644
--- a/manifests/charts/base/files/crd-all.yaml
+++ b/manifests/charts/base/files/crd-all.yaml
@@ -24,19 +24,19 @@ metadata:
chart: dubbo
heritage: Tiller
release: dubbo
- name: subsetrules.networking.dubbo.apache.org
+ name: destinationrules.networking.dubbo.apache.org
spec:
group: networking.dubbo.apache.org
names:
categories:
- dubbo
- networking
- kind: SubsetRule
- listKind: SubsetRuleList
- plural: subsetrules
+ kind: DestinationRule
+ listKind: DestinationRuleList
+ plural: destinationrules
shortNames:
- - ssr
- singular: subsetrules
+ - dr
+ singular: destinationrule
scope: Namespaced
versions:
- additionalPrinterColumns:
@@ -95,7 +95,7 @@ spec:
- DISABLE
- SIMPLE
- MUTUAL
- - ISTIO_MUTUAL
+ - DUBBO_MUTUAL
type: string
type: object
type: object
@@ -114,12 +114,12 @@ spec:
description: |-
Indicates whether connections to this port should
be secured using TLS.
- Valid Options: DISABLE, SIMPLE, MUTUAL,
ISTIO_MUTUAL
+ Valid Options: DISABLE, SIMPLE, MUTUAL,
DUBBO_MUTUAL
enum:
- DISABLE
- SIMPLE
- MUTUAL
- - ISTIO_MUTUAL
+ - DUBBO_MUTUAL
type: string
type: object
type: object
diff --git a/pkg/adsc/adsc.go b/pkg/adsc/adsc.go
index f5858216..efb53294 100644
--- a/pkg/adsc/adsc.go
+++ b/pkg/adsc/adsc.go
@@ -33,7 +33,6 @@ import (
"github.com/apache/dubbo-kubernetes/dubbod/planet/pkg/networking/util"
v3 "github.com/apache/dubbo-kubernetes/dubbod/planet/pkg/xds/v3"
"github.com/apache/dubbo-kubernetes/pkg/backoff"
- "github.com/apache/dubbo-kubernetes/pkg/config"
"github.com/apache/dubbo-kubernetes/pkg/config/schema/collections"
"github.com/apache/dubbo-kubernetes/pkg/config/schema/gvk"
"github.com/apache/dubbo-kubernetes/pkg/security"
@@ -49,9 +48,7 @@ import (
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/protobuf/proto"
- anypb "google.golang.org/protobuf/types/known/anypb"
pstruct "google.golang.org/protobuf/types/known/structpb"
- mcp "istio.io/api/mcp/v1alpha1"
dubbolog "github.com/apache/dubbo-kubernetes/pkg/log"
)
@@ -91,7 +88,7 @@ type Config struct {
Revision string
// Meta includes additional metadata for the node
Meta *pstruct.Struct
- // BackoffPolicy determines the reconnect policy. Based on MCP client.
+ // BackoffPolicy determines the reconnect policy.
BackoffPolicy backoff.BackOff
}
@@ -348,26 +345,10 @@ func (a *ADSC) WaitClear() {
}
}
-// HasSynced returns true if MCP configs have synced
+// HasSynced returns true if configs have synced
+// MCP support removed - it's a legacy protocol replaced by APIGenerator
func (a *ADSC) HasSynced() bool {
- if a.cfg == nil || len(a.cfg.InitialDiscoveryRequests) == 0 {
- return true
- }
-
- a.mutex.RLock()
- defer a.mutex.RUnlock()
-
- for _, req := range a.cfg.InitialDiscoveryRequests {
- _, isMCP := convertTypeURLToMCPGVK(req.TypeUrl)
- if !isMCP {
- continue
- }
-
- if _, ok := a.sync[req.TypeUrl]; !ok {
- return false
- }
- }
-
+ // MCP was replaced by APIGenerator in Istio, not needed for proxyless
mesh
return true
}
@@ -423,41 +404,6 @@ func (a *ADSC) ack(msg *discovery.DiscoveryResponse) {
})
}
-func (a *ADSC) mcpToPlanet(m *mcp.Resource) (*config.Config, error) {
- if m == nil || m.Metadata == nil {
- return &config.Config{}, nil
- }
- c := &config.Config{
- Meta: config.Meta{
- ResourceVersion: m.Metadata.Version,
- Labels: m.Metadata.Labels,
- Annotations: m.Metadata.Annotations,
- },
- }
-
- if !config.ObjectInRevision(c, a.cfg.Revision) { // In case upstream
does not support rev in node meta.
- return nil, nil
- }
-
- if c.Meta.Annotations == nil {
- c.Meta.Annotations = make(map[string]string)
- }
- nsn := strings.Split(m.Metadata.Name, "/")
- if len(nsn) != 2 {
- return nil, fmt.Errorf("invalid name %s", m.Metadata.Name)
- }
- c.Namespace = nsn[0]
- c.Name = nsn[1]
- var err error
- c.CreationTimestamp = m.Metadata.CreateTime.AsTime()
-
- pb, err := m.Body.UnmarshalNew()
- if err != nil {
- return nil, err
- }
- c.Spec = pb
- return c, nil
-}
func (a *ADSC) handleRecv() {
// We connected, so reset the backoff
@@ -487,7 +433,7 @@ func (a *ADSC) handleRecv() {
}
// Group-value-kind - used for high level api generator.
- resourceGvk, isMCP := convertTypeURLToMCPGVK(msg.TypeUrl)
+ // MCP support removed - it's a legacy protocol replaced by
APIGenerator
// TODO WithLabels
if a.cfg.ResponseHandler != nil {
@@ -546,9 +492,7 @@ func (a *ADSC) handleRecv() {
}
a.handleRDS(routes)
default:
- if isMCP {
- a.handleMCP(resourceGvk, msg.Resources)
- }
+ // MCP support removed - it's a legacy protocol
replaced by APIGenerator
}
// If we got no resource - still save to the store with empty
name/namespace, to notify sync
@@ -557,11 +501,6 @@ func (a *ADSC) handleRecv() {
// TODO: add hook to inject nacks
a.mutex.Lock()
- if isMCP {
- if _, exist := a.sync[resourceGvk.String()]; !exist {
- a.sync[resourceGvk.String()] = time.Now()
- }
- }
a.Received[msg.TypeUrl] = msg
a.ack(msg)
a.mutex.Unlock()
@@ -573,62 +512,6 @@ func (a *ADSC) handleRecv() {
}
}
-func (a *ADSC) handleMCP(groupVersionKind config.GroupVersionKind, resources
[]*anypb.Any) {
- // Generic - fill up the store
- if a.Store == nil {
- return
- }
-
- existingConfigs := a.Store.List(groupVersionKind, "")
-
- received := make(map[string]*config.Config)
- for _, rsc := range resources {
- m := &mcp.Resource{}
- err := rsc.UnmarshalTo(m)
- if err != nil {
- log.Errorf("Error unmarshalling received MCP config
%v", err)
- continue
- }
- newCfg, err := a.mcpToPlanet(m)
- if err != nil {
- log.Errorf("Invalid data: %v (%v)", err,
string(rsc.Value))
- continue
- }
- if newCfg == nil {
- continue
- }
- received[newCfg.Namespace+"/"+newCfg.Name] = newCfg
-
- newCfg.GroupVersionKind = groupVersionKind
- oldCfg := a.Store.Get(newCfg.GroupVersionKind, newCfg.Name,
newCfg.Namespace)
-
- if oldCfg == nil {
- if _, err = a.Store.Create(*newCfg); err != nil {
- log.Errorf("Error adding a new resource to the
store %v", err)
- continue
- }
- } else if oldCfg.ResourceVersion != newCfg.ResourceVersion ||
newCfg.ResourceVersion == "" {
- // update the store only when resource version differs
or unset.
- // newCfg.Annotations[mem.ResourceVersion] =
newCfg.ResourceVersion
- newCfg.ResourceVersion = oldCfg.ResourceVersion
- if _, err = a.Store.Update(*newCfg); err != nil {
- log.Errorf("Error updating an existing resource
in the store %v", err)
- continue
- }
- }
- }
-
- // remove deleted resources from cache
- for _, config := range existingConfigs {
- if _, ok := received[config.Namespace+"/"+config.Name]; !ok {
- if err := a.Store.Delete(config.GroupVersionKind,
config.Name, config.Namespace, nil); err != nil {
- log.Errorf("Error deleting an outdated resource
from the store %v", err)
- continue
- }
- }
- }
-}
-
// nolint: staticcheck
func (a *ADSC) handleLDS(ll []*listener.Listener) {
lh := map[string]*listener.Listener{}
diff --git a/pkg/adsc/util.go b/pkg/adsc/util.go
index f10e51f0..0e991593 100644
--- a/pkg/adsc/util.go
+++ b/pkg/adsc/util.go
@@ -18,10 +18,7 @@ package adsc
import (
"crypto/tls"
- "strings"
- "github.com/apache/dubbo-kubernetes/pkg/config"
- "github.com/apache/dubbo-kubernetes/pkg/config/schema/collections"
"github.com/apache/dubbo-kubernetes/pkg/security"
)
@@ -53,22 +50,3 @@ func getClientCertFn(config *Config) func(requestInfo
*tls.CertificateRequestInf
return nil
}
-func convertTypeURLToMCPGVK(typeURL string) (config.GroupVersionKind, bool) {
- parts := strings.SplitN(typeURL, "/", 3)
- if len(parts) != 3 {
- return config.GroupVersionKind{}, false
- }
-
- gvk := config.GroupVersionKind{
- Group: parts[0],
- Version: parts[1],
- Kind: parts[2],
- }
-
- _, isMCP := collections.Planet.FindByGroupVersionKind(gvk)
- if isMCP {
- return gvk, true
- }
-
- return config.GroupVersionKind{}, false
-}
diff --git a/pkg/config/schema/collections/collections.agent.go
b/pkg/config/schema/collections/collections.agent.go
index d857de64..b2959b44 100644
--- a/pkg/config/schema/collections/collections.agent.go
+++ b/pkg/config/schema/collections/collections.agent.go
@@ -25,8 +25,8 @@ import (
sigsk8siogatewayapiapisv1 "sigs.k8s.io/gateway-api/apis/v1"
sigsk8siogatewayapiapisv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
+ dubboapimetav1alpha1
"github.com/apache/dubbo-kubernetes/api/meta/v1alpha1"
"github.com/apache/dubbo-kubernetes/pkg/config/schema/collection"
- istioioapimetav1alpha1 "istio.io/api/meta/v1alpha1"
istioioapinetworkingv1alpha3 "istio.io/api/networking/v1alpha3"
istioioapisecurityv1beta1 "istio.io/api/security/v1beta1"
k8sioapiadmissionregistrationv1 "k8s.io/api/admissionregistration/v1"
@@ -40,23 +40,23 @@ var (
Plural: "peerauthentications",
Version: "v1",
VersionAliases: []string{},
- Proto: "istio.security.v1beta1.PeerAuthentication",
StatusProto: "istio.meta.v1alpha1.IstioStatus",
- ReflectType:
reflect.TypeOf(&istioioapisecurityv1beta1.PeerAuthentication{}).Elem(),
StatusType: reflect.TypeOf(&istioioapimetav1alpha1.IstioStatus{}).Elem(),
- ProtoPackage: "istio.io/api/security/v1beta1", StatusPackage:
"istio.io/api/meta/v1alpha1",
+ Proto: "istio.security.v1beta1.PeerAuthentication",
StatusProto: "istio.meta.v1alpha1.DubboStatus",
+ ReflectType:
reflect.TypeOf(&istioioapisecurityv1beta1.PeerAuthentication{}).Elem(),
StatusType: reflect.TypeOf(&dubboapimetav1alpha1.DubboStatus{}).Elem(),
+ ProtoPackage: "istio.io/api/security/v1beta1", StatusPackage:
"github.com/apache/dubbo-kubernetes/api/meta/v1alpha1",
ClusterScoped: false,
Synthetic: false,
Builtin: false,
}.MustBuild()
- SubsetRule = collection.Builder{
- Identifier: "SubsetRule",
+ DestinationRule = collection.Builder{
+ Identifier: "DestinationRule",
Group: "networking.dubbo.apache.org",
- Kind: "SubsetRule",
- Plural: "subsetrules",
- Version: "v1",
+ Kind: "DestinationRule",
+ Plural: "destinationrules",
+ Version: "v1alpha3",
VersionAliases: []string{},
- Proto: "istio.networking.v1alpha3.DestinationRule",
StatusProto: "istio.meta.v1alpha1.IstioStatus",
- ReflectType:
reflect.TypeOf(&istioioapinetworkingv1alpha3.DestinationRule{}).Elem(),
StatusType: reflect.TypeOf(&istioioapimetav1alpha1.IstioStatus{}).Elem(),
- ProtoPackage: "istio.io/api/networking/v1alpha3",
StatusPackage: "istio.io/api/meta/v1alpha1",
+ Proto: "istio.networking.v1alpha3.DestinationRule",
StatusProto: "istio.meta.v1alpha1.DubboStatus",
+ ReflectType:
reflect.TypeOf(&istioioapinetworkingv1alpha3.DestinationRule{}).Elem(),
StatusType: reflect.TypeOf(&dubboapimetav1alpha1.DubboStatus{}).Elem(),
+ ProtoPackage: "istio.io/api/networking/v1alpha3",
StatusPackage: "github.com/apache/dubbo-kubernetes/api/meta/v1alpha1",
ClusterScoped: false,
Synthetic: false,
Builtin: false,
@@ -68,9 +68,9 @@ var (
Plural: "serviceroutes",
Version: "v1",
VersionAliases: []string{},
- Proto: "istio.networking.v1alpha3.VirtualService",
StatusProto: "istio.meta.v1alpha1.IstioStatus",
- ReflectType:
reflect.TypeOf(&istioioapinetworkingv1alpha3.VirtualService{}).Elem(),
StatusType: reflect.TypeOf(&istioioapimetav1alpha1.IstioStatus{}).Elem(),
- ProtoPackage: "istio.io/api/networking/v1alpha3",
StatusPackage: "istio.io/api/meta/v1alpha1",
+ Proto: "istio.networking.v1alpha3.VirtualService",
StatusProto: "istio.meta.v1alpha1.DubboStatus",
+ ReflectType:
reflect.TypeOf(&istioioapinetworkingv1alpha3.VirtualService{}).Elem(),
StatusType: reflect.TypeOf(&dubboapimetav1alpha1.DubboStatus{}).Elem(),
+ ProtoPackage: "istio.io/api/networking/v1alpha3",
StatusPackage: "github.com/apache/dubbo-kubernetes/api/meta/v1alpha1",
ClusterScoped: false,
Synthetic: false,
Builtin: false,
@@ -146,7 +146,7 @@ var (
Planet = collection.NewSchemasBuilder().
MustAdd(PeerAuthentication).
- MustAdd(SubsetRule).
+ MustAdd(DestinationRule).
MustAdd(ServiceRoute).
Build()
@@ -158,7 +158,7 @@ var (
All = collection.NewSchemasBuilder().
MustAdd(PeerAuthentication).
- MustAdd(SubsetRule).
+ MustAdd(DestinationRule).
MustAdd(ServiceRoute).
MustAdd(MutatingWebhookConfiguration).
MustAdd(ValidatingWebhookConfiguration).
diff --git a/pkg/config/schema/collections/collections.go
b/pkg/config/schema/collections/collections.go
index eaf58844..5526ab90 100644
--- a/pkg/config/schema/collections/collections.go
+++ b/pkg/config/schema/collections/collections.go
@@ -25,8 +25,8 @@ import (
sigsk8siogatewayapiapisv1 "sigs.k8s.io/gateway-api/apis/v1"
sigsk8siogatewayapiapisv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
+ dubboapimetav1alpha1
"github.com/apache/dubbo-kubernetes/api/meta/v1alpha1"
"github.com/apache/dubbo-kubernetes/pkg/config/schema/collection"
- istioioapimetav1alpha1 "istio.io/api/meta/v1alpha1"
istioioapinetworkingv1alpha3 "istio.io/api/networking/v1alpha3"
istioioapisecurityv1beta1 "istio.io/api/security/v1beta1"
k8sioapiadmissionregistrationv1 "k8s.io/api/admissionregistration/v1"
@@ -40,23 +40,23 @@ var (
Plural: "peerauthentications",
Version: "v1",
VersionAliases: []string{},
- Proto: "istio.security.v1beta1.PeerAuthentication",
StatusProto: "istio.meta.v1alpha1.IstioStatus",
- ReflectType:
reflect.TypeOf(&istioioapisecurityv1beta1.PeerAuthentication{}).Elem(),
StatusType: reflect.TypeOf(&istioioapimetav1alpha1.IstioStatus{}).Elem(),
- ProtoPackage: "istio.io/api/security/v1beta1", StatusPackage:
"istio.io/api/meta/v1alpha1",
+ Proto: "istio.security.v1beta1.PeerAuthentication",
StatusProto: "dubbo.meta.v1alpha1.DubboStatus",
+ ReflectType:
reflect.TypeOf(&istioioapisecurityv1beta1.PeerAuthentication{}).Elem(),
StatusType: reflect.TypeOf(&dubboapimetav1alpha1.DubboStatus{}).Elem(),
+ ProtoPackage: "istio.io/api/security/v1beta1", StatusPackage:
"github.com/apache/dubbo-kubernetes/api/meta/v1alpha1",
ClusterScoped: false,
Synthetic: false,
Builtin: false,
}.MustBuild()
- SubsetRule = collection.Builder{
- Identifier: "SubsetRule",
+ DestinationRule = collection.Builder{
+ Identifier: "DestinationRule",
Group: "networking.dubbo.apache.org",
- Kind: "SubsetRule",
- Plural: "subsetrules",
- Version: "v1",
+ Kind: "DestinationRule",
+ Plural: "destinationrules",
+ Version: "v1alpha3",
VersionAliases: []string{},
- Proto: "istio.networking.v1alpha3.DestinationRule",
StatusProto: "istio.meta.v1alpha1.IstioStatus",
- ReflectType:
reflect.TypeOf(&istioioapinetworkingv1alpha3.DestinationRule{}).Elem(),
StatusType: reflect.TypeOf(&istioioapimetav1alpha1.IstioStatus{}).Elem(),
- ProtoPackage: "istio.io/api/networking/v1alpha3",
StatusPackage: "istio.io/api/meta/v1alpha1",
+ Proto: "istio.networking.v1alpha3.DestinationRule",
StatusProto: "dubbo.meta.v1alpha1.DubboStatus",
+ ReflectType:
reflect.TypeOf(&istioioapinetworkingv1alpha3.DestinationRule{}).Elem(),
StatusType: reflect.TypeOf(&dubboapimetav1alpha1.DubboStatus{}).Elem(),
+ ProtoPackage: "istio.io/api/networking/v1alpha3",
StatusPackage: "github.com/apache/dubbo-kubernetes/api/meta/v1alpha1",
ClusterScoped: false,
Synthetic: false,
Builtin: false,
@@ -68,9 +68,9 @@ var (
Plural: "serviceroutes",
Version: "v1",
VersionAliases: []string{},
- Proto: "istio.networking.v1alpha3.VirtualService",
StatusProto: "istio.meta.v1alpha1.IstioStatus",
- ReflectType:
reflect.TypeOf(&istioioapinetworkingv1alpha3.VirtualService{}).Elem(),
StatusType: reflect.TypeOf(&istioioapimetav1alpha1.IstioStatus{}).Elem(),
- ProtoPackage: "istio.io/api/networking/v1alpha3",
StatusPackage: "istio.io/api/meta/v1alpha1",
+ Proto: "istio.networking.v1alpha3.VirtualService",
StatusProto: "dubbo.meta.v1alpha1.DubboStatus",
+ ReflectType:
reflect.TypeOf(&istioioapinetworkingv1alpha3.VirtualService{}).Elem(),
StatusType: reflect.TypeOf(&dubboapimetav1alpha1.DubboStatus{}).Elem(),
+ ProtoPackage: "istio.io/api/networking/v1alpha3",
StatusPackage: "github.com/apache/dubbo-kubernetes/api/meta/v1alpha1",
ClusterScoped: false,
Synthetic: false,
Builtin: false,
@@ -146,7 +146,7 @@ var (
Planet = collection.NewSchemasBuilder().
MustAdd(PeerAuthentication).
- MustAdd(SubsetRule).
+ MustAdd(DestinationRule).
MustAdd(ServiceRoute).
Build()
@@ -158,7 +158,7 @@ var (
All = collection.NewSchemasBuilder().
MustAdd(PeerAuthentication).
- MustAdd(SubsetRule).
+ MustAdd(DestinationRule).
MustAdd(ServiceRoute).
MustAdd(MutatingWebhookConfiguration).
MustAdd(ValidatingWebhookConfiguration).
diff --git a/pkg/config/schema/gvk/resources.go
b/pkg/config/schema/gvk/resources.go
index aee010d4..bcd12201 100644
--- a/pkg/config/schema/gvk/resources.go
+++ b/pkg/config/schema/gvk/resources.go
@@ -38,7 +38,7 @@ var (
Pod = config.GroupVersionKind{Group: "",
Version: "v1", Kind: "Pod"}
MeshGlobalConfig = config.GroupVersionKind{Group: "",
Version: "v1alpha1", Kind: "MeshGlobalConfig"}
PeerAuthentication = config.GroupVersionKind{Group:
"security.dubbo.apache.org", Version: "v1", Kind: "PeerAuthentication"}
- SubsetRule = config.GroupVersionKind{Group:
"networking.dubbo.apache.org", Version: "v1", Kind: "SubsetRule"}
+ DestinationRule = config.GroupVersionKind{Group:
"networking.dubbo.apache.org", Version: "v1alpha3", Kind: "DestinationRule"}
ServiceRoute = config.GroupVersionKind{Group:
"networking.dubbo.apache.org", Version: "v1", Kind: "ServiceRoute"}
EndpointSlice = config.GroupVersionKind{Group:
"discovery.k8s.io", Version: "v1", Kind: "EndpointSlice"}
Endpoints = config.GroupVersionKind{Group: "",
Version: "v1", Kind: "Endpoints"}
@@ -79,8 +79,8 @@ func ToGVR(g config.GroupVersionKind)
(schema.GroupVersionResource, bool) {
return gvr.MeshGlobalConfig, true
case PeerAuthentication:
return gvr.PeerAuthentication, true
- case SubsetRule:
- return gvr.SubsetRule, true
+ case DestinationRule:
+ return gvr.DestinationRule, true
case ServiceRoute:
return gvr.ServiceRoute, true
case EndpointSlice:
@@ -119,8 +119,8 @@ func FromGVR(g schema.GroupVersionResource)
(config.GroupVersionKind, bool) {
return PeerAuthentication, true
case gvr.ServiceRoute:
return ServiceRoute, true
- case gvr.SubsetRule:
- return SubsetRule, true
+ case gvr.DestinationRule:
+ return DestinationRule, true
case gvr.EndpointSlice:
return EndpointSlice, true
case gvr.Endpoints:
diff --git a/pkg/config/schema/gvr/resources.go
b/pkg/config/schema/gvr/resources.go
index 8e860ff9..08d627b6 100644
--- a/pkg/config/schema/gvr/resources.go
+++ b/pkg/config/schema/gvr/resources.go
@@ -35,7 +35,7 @@ var (
ServiceAccount = schema.GroupVersionResource{Group: "",
Version: "v1", Resource: "serviceaccounts"}
MeshGlobalConfig = schema.GroupVersionResource{Group: "",
Version: "v1alpha1", Resource: "meshglobalconfigs"}
PeerAuthentication = schema.GroupVersionResource{Group:
"security.dubbo.apache.org", Version: "v1", Resource: "peerauthentications"}
- SubsetRule = schema.GroupVersionResource{Group:
"networking.dubbo.apache.org", Version: "v1", Resource: "subsetrules"}
+ DestinationRule =
schema.GroupVersionResource{Group: "networking.dubbo.apache.org", Version:
"v1alpha3", Resource: "destinationrules"}
ServiceRoute = schema.GroupVersionResource{Group:
"networking.dubbo.apache.org", Version: "v1", Resource: "serviceroutes"}
EndpointSlice = schema.GroupVersionResource{Group:
"discovery.k8s.io", Version: "v1", Resource: "endpointslices"}
Endpoints = schema.GroupVersionResource{Group: "",
Version: "v1", Resource: "endpoints"}
@@ -65,7 +65,7 @@ func IsClusterScoped(g schema.GroupVersionResource) bool {
return false
case PeerAuthentication:
return false
- case SubsetRule:
+ case DestinationRule:
return false
case ServiceRoute:
return false
diff --git a/pkg/config/schema/kind/resources.go
b/pkg/config/schema/kind/resources.go
index 08e14e4b..02b94b07 100644
--- a/pkg/config/schema/kind/resources.go
+++ b/pkg/config/schema/kind/resources.go
@@ -32,7 +32,7 @@ const (
MutatingWebhookConfiguration
PeerAuthentication
ServiceRoute
- SubsetRule
+ DestinationRule
Gateway
GatewayClass
HTTPRoute
@@ -68,8 +68,8 @@ func (k Kind) String() string {
return "PeerAuthentication"
case ServiceRoute:
return "ServiceRoute"
- case SubsetRule:
- return "SubsetRule"
+ case DestinationRule:
+ return "DestinationRule"
case GatewayClass:
return "GatewayClass"
case Gateway:
diff --git a/pkg/config/schema/kubeclient/resources.go
b/pkg/config/schema/kubeclient/resources.go
index 3fcc5670..5849a396 100644
--- a/pkg/config/schema/kubeclient/resources.go
+++ b/pkg/config/schema/kubeclient/resources.go
@@ -120,7 +120,7 @@ func gvrToObject(g schema.GroupVersionResource)
runtime.Object {
return &apiistioioapisecurityv1.PeerAuthentication{}
case gvr.ServiceRoute:
return &apiistioioapinetworkingv1.VirtualService{}
- case gvr.SubsetRule:
+ case gvr.DestinationRule:
return &apiistioioapinetworkingv1.DestinationRule{}
case gvr.GatewayClass:
return &sigsk8siogatewayapiapisv1.GatewayClass{}
@@ -243,35 +243,35 @@ func getInformerFiltered(c ClientGetter, opts
ktypes.InformerOptions, g schema.G
w = func(options metav1.ListOptions) (watch.Interface, error) {
return
c.Dynamic().Resource(gvr).Namespace(opts.Namespace).Watch(context.Background(),
options)
}
- case gvr.SubsetRule:
- // SubsetRule uses networking.dubbo.apache.org API group, not
networking.istio.io
+ case gvr.DestinationRule:
+ // DestinationRule uses networking.dubbo.apache.org API group,
not networking.istio.io
// Use Dynamic client to access it
gvr := schema.GroupVersionResource{
Group: "networking.dubbo.apache.org",
- Version: "v1",
- Resource: "subsetrules",
+ Version: "v1alpha3",
+ Resource: "destinationrules",
}
l = func(options metav1.ListOptions) (runtime.Object, error) {
// Log the namespace being watched for diagnosis
if opts.Namespace == "" {
- log.Infof("SubsetRule informer: List called for
all namespaces")
+ log.Infof("DestinationRule informer: List
called for all namespaces")
} else {
- log.Infof("SubsetRule informer: List called for
namespace %s", opts.Namespace)
+ log.Infof("DestinationRule informer: List
called for namespace %s", opts.Namespace)
}
return
c.Dynamic().Resource(gvr).Namespace(opts.Namespace).List(context.Background(),
options)
}
w = func(options metav1.ListOptions) (watch.Interface, error) {
// Log the namespace being watched for diagnosis
if opts.Namespace == "" {
- log.Infof("SubsetRule informer: Watch called
for all namespaces")
+ log.Infof("DestinationRule informer: Watch
called for all namespaces")
} else {
- log.Infof("SubsetRule informer: Watch called
for namespace %s", opts.Namespace)
+ log.Infof("DestinationRule informer: Watch
called for namespace %s", opts.Namespace)
}
watchInterface, err :=
c.Dynamic().Resource(gvr).Namespace(opts.Namespace).Watch(context.Background(),
options)
if err != nil {
- log.Errorf("SubsetRule informer: Watch failed:
%v", err)
+ log.Errorf("DestinationRule informer: Watch
failed: %v", err)
} else {
- log.Infof("SubsetRule informer: Watch
connection established successfully")
+ log.Infof("DestinationRule informer: Watch
connection established successfully")
}
return watchInterface, err
}
diff --git a/pkg/config/schema/kubetypes/resources.go
b/pkg/config/schema/kubetypes/resources.go
index 993774c7..c5721a57 100644
--- a/pkg/config/schema/kubetypes/resources.go
+++ b/pkg/config/schema/kubetypes/resources.go
@@ -41,7 +41,7 @@ func getGvk(obj any) (config.GroupVersionKind, bool) {
case *apiistioioapisecurityv1.PeerAuthentication:
return gvk.PeerAuthentication, true
case *apiistioioapinetworkingv1.DestinationRule:
- return gvk.SubsetRule, true
+ return gvk.DestinationRule, true
case *apiistioioapinetworkingv1.VirtualService:
return gvk.ServiceRoute, true
case *k8sioapicorev1.ConfigMap:
diff --git a/pkg/kube/inject/inject.go b/pkg/kube/inject/inject.go
index 716750ee..b538ba59 100644
--- a/pkg/kube/inject/inject.go
+++ b/pkg/kube/inject/inject.go
@@ -25,9 +25,9 @@ import (
"strings"
"text/template"
+ "github.com/apache/dubbo-kubernetes/api/annotation"
meshv1alpha1 "github.com/apache/dubbo-kubernetes/api/mesh/v1alpha1"
common_features "github.com/apache/dubbo-kubernetes/pkg/features"
- "istio.io/api/annotation"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
@@ -213,7 +213,7 @@ func getProxyImage(values map[string]any, defaultImage
string) string {
}
func selectTemplates(params InjectionParameters) []string {
- if a, f := params.pod.Annotations[annotation.InjectTemplates.Name]; f {
+ if a, f :=
params.pod.Annotations[annotation.OrgApacheDubboInjectTemplates.Name]; f {
names := []string{}
for _, tmplName := range strings.Split(a, ",") {
name := strings.TrimSpace(tmplName)
@@ -280,7 +280,7 @@ func stripPod(req InjectionParameters) *corev1.Pod {
pod.Spec.Containers = modifyContainers(pod.Spec.Containers, c,
Remove)
}
- delete(pod.Annotations, annotation.SidecarStatus.Name)
+ delete(pod.Annotations, annotation.OrgApacheDubboProxylessStatus.Name)
return pod
}
@@ -337,8 +337,8 @@ func injectRequired(ignored []string, config *Config,
podSpec *corev1.PodSpec, m
var useDefault bool
var inject bool
- objectSelector := annos["proxyless.dubbo.apache.org/inject"]
- if lbl, labelPresent :=
metadata.GetLabels()["proxyless.dubbo.apache.org/inject"]; labelPresent {
+ objectSelector := annos[annotation.OrgApacheDubboProxylessInject.Name]
+ if lbl, labelPresent :=
metadata.GetLabels()[annotation.OrgApacheDubboProxylessInject.Name];
labelPresent {
// The label is the new API; if both are present we prefer the
label
objectSelector = lbl
}
@@ -351,7 +351,7 @@ func injectRequired(ignored []string, config *Config,
podSpec *corev1.PodSpec, m
useDefault = true
default:
log.Warnf("Invalid value for %s: %q. Only 'true' and 'false'
are accepted. Falling back to default injection policy.",
- "proxyless.dubbo.apache.org/inject", objectSelector)
+ annotation.OrgApacheDubboProxylessInject.Name,
objectSelector)
useDefault = true
}
@@ -381,7 +381,7 @@ func injectRequired(ignored []string, config *Config,
podSpec *corev1.PodSpec, m
func injectionStatus(pod *corev1.Pod) *InjectionStatus {
var statusBytes []byte
if pod.ObjectMeta.Annotations != nil {
- if value, ok :=
pod.ObjectMeta.Annotations[annotation.SidecarStatus.Name]; ok {
+ if value, ok :=
pod.ObjectMeta.Annotations[annotation.OrgApacheDubboProxylessStatus.Name]; ok {
statusBytes = []byte(value)
}
}
@@ -416,7 +416,7 @@ func reinsertOverrides(pod *corev1.Pod) (*corev1.Pod,
error) {
}
existingOverrides := podOverrides{}
- if annotationOverrides, f :=
pod.Annotations[annotation.ProxyOverrides.Name]; f {
+ if annotationOverrides, f :=
pod.Annotations[annotation.OrgApacheDubboProxyOverrides.Name]; f {
if err := json.Unmarshal([]byte(annotationOverrides),
&existingOverrides); err != nil {
return nil, err
}
diff --git a/pkg/kube/inject/webhook.go b/pkg/kube/inject/webhook.go
index 9ede17f3..133f1bea 100644
--- a/pkg/kube/inject/webhook.go
+++ b/pkg/kube/inject/webhook.go
@@ -30,15 +30,13 @@ import (
"text/template"
"time"
+ meshv1alpha1 "github.com/apache/dubbo-kubernetes/api/mesh/v1alpha1"
"github.com/apache/dubbo-kubernetes/dubbod/planet/pkg/model"
opconfig "github.com/apache/dubbo-kubernetes/operator/pkg/apis"
- "github.com/apache/dubbo-kubernetes/pkg/config/mesh"
"github.com/apache/dubbo-kubernetes/pkg/kube"
"github.com/apache/dubbo-kubernetes/pkg/kube/multicluster"
"github.com/apache/dubbo-kubernetes/pkg/util/protomarshal"
"gomodules.xyz/jsonpatch/v2"
- "istio.io/api/annotation"
- meshconfig "istio.io/api/mesh/v1alpha1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
@@ -67,7 +65,7 @@ var (
type Webhook struct {
mu sync.RWMutex
watcher Watcher
- meshConfig *meshconfig.MeshConfig
+ meshConfig *meshv1alpha1.MeshGlobalConfig
env *model.Environment
Config *Config
valuesConfig ValuesConfig
@@ -97,8 +95,8 @@ type InjectionParameters struct {
templates map[string]*template.Template
defaultTemplate []string
aliases map[string][]string
- meshConfig *meshconfig.MeshConfig
- proxyConfig *meshconfig.ProxyConfig
+ meshGlobalConfig *meshv1alpha1.MeshGlobalConfig
+ proxyConfig *meshv1alpha1.ProxyConfig
valuesConfig ValuesConfig
revision string
proxyEnvs map[string]string
@@ -267,7 +265,7 @@ func (wh *Webhook) inject(ar *kube.AdmissionReview, path
string) *kube.Admission
templates: wh.Config.Templates,
defaultTemplate: wh.Config.DefaultTemplates,
aliases: wh.Config.Aliases,
- meshConfig: wh.meshConfig,
+ meshGlobalConfig: wh.meshConfig,
proxyConfig: proxyConfig,
valuesConfig: wh.valuesConfig,
injectedAnnotations: wh.Config.InjectedAnnotations,
@@ -454,29 +452,9 @@ func addApplicationContainerConfig(pod *corev1.Pod) {
}
func reorderPod(pod *corev1.Pod, req InjectionParameters) error {
- var merr error
- mc := req.meshConfig
- // Get copy of pod proxyconfig, to determine container ordering
- if pca, f :=
req.pod.ObjectMeta.GetAnnotations()[annotation.ProxyConfig.Name]; f {
- mc, merr = mesh.ApplyProxyConfig(pca, req.meshConfig)
- if merr != nil {
- return merr
- }
- }
-
- // nolint: staticcheck
- holdPod :=
mc.GetDefaultConfig().GetHoldApplicationUntilProxyStarts().GetValue()
-
- proxyLocation := MoveLast
- // If HoldApplicationUntilProxyStarts is set, reorder the proxy location
- if holdPod {
- proxyLocation = MoveFirst
- }
-
- // Proxy container should be last, unless
HoldApplicationUntilProxyStarts is set
- // This is to ensure `kubectl exec` and similar commands continue to
default to the user's container
- pod.Spec.Containers = modifyContainers(pod.Spec.Containers,
ProxyContainerName, proxyLocation)
-
+ // Proxy container should be last to ensure `kubectl exec` and similar
commands
+ // continue to default to the user's container
+ pod.Spec.Containers = modifyContainers(pod.Spec.Containers,
ProxyContainerName, MoveLast)
return nil
}
diff --git a/samples/grpc-app/README.md b/samples/grpc-app/README.md
index 42516e91..fe7c8f25 100644
--- a/samples/grpc-app/README.md
+++ b/samples/grpc-app/README.md
@@ -55,14 +55,14 @@ grpcurl -plaintext -d '{"url":
"xds:///provider.grpc-app.svc.cluster.local:7070"
## Traffic Management
-### Creating subsets with SubsetRule
+### Creating subsets with DestinationRule
First, create a subset for each version of the workload to enable traffic
splitting:
```bash
cat <<EOF | kubectl apply -f -
-apiVersion: networking.dubbo.apache.org/v1
-kind: SubsetRule
+apiVersion: networking.dubbo.apache.org/v1alpha3
+kind: DestinationRule
metadata:
name: provider-versions
namespace: grpc-app
@@ -84,7 +84,7 @@ Using the subsets defined above, you can send weighted
traffic to different vers
```bash
cat <<EOF | kubectl apply -f -
-apiVersion: networking.dubbo.apache.org/v1
+apiVersion: networking.dubbo.apache.org/v1alpha3
kind: ServiceRoute
metadata:
name: provider-weights
@@ -131,12 +131,12 @@ Due to the changes to the application itself required to
enable security in gRPC
### Enable client-side mTLS
-To enable client-side mTLS, apply a `SubsetRule` with `tls` settings:
+To enable client-side mTLS, apply a `DestinationRule` with `tls` settings:
```bash
cat <<EOF | kubectl apply -f -
-apiVersion: networking.dubbo.apache.org/v1
-kind: SubsetRule
+apiVersion: networking.dubbo.apache.org/v1alpha3
+kind: DestinationRule
metadata:
name: provider-mtls
namespace: grpc-app
diff --git a/tests/grpc-app/consumer/main.go b/tests/grpc-app/consumer/main.go
index 95fed0e3..c5dad251 100644
--- a/tests/grpc-app/consumer/main.go
+++ b/tests/grpc-app/consumer/main.go
@@ -365,12 +365,12 @@ func (s *testServerImpl) ForwardEcho(ctx context.Context,
req *pb.ForwardEchoReq
// Double-check after acquiring write lock
if cached, exists = s.connCache[req.Url]; !exists || cached ==
nil || cached.conn == nil {
conn = nil
- // When TLS is configured (SubsetRule ISTIO_MUTUAL),
gRPC xDS client needs
+ // When TLS is configured (DestinationRule
ISTIO_MUTUAL), gRPC xDS client needs
// to fetch certificates from CertificateProvider. The
CertificateProvider uses file_watcher
// to read certificate files. If the files are not
ready or CertificateProvider is not
// initialized, certificate fetching will timeout.
// We wait a short time to ensure CertificateProvider
is ready and certificate files are accessible.
- // This is especially important when SubsetRule is just
created and TLS is enabled.
+ // This is especially important when DestinationRule is
just created and TLS is enabled.
// The CertificateProvider may need time to initialize,
especially on first connection.
// We wait 3 seconds to give CertificateProvider enough
time to initialize (reduced from 5s for faster startup).
log.Printf("ForwardEcho: waiting 3 seconds to ensure
CertificateProvider is ready...")
@@ -391,7 +391,7 @@ func (s *testServerImpl) ForwardEcho(ctx context.Context,
req *pb.ForwardEchoReq
// Dial with xDS URL - use background context, not the
request context
// The request context might timeout before xDS
configuration is received
- // When TLS is configured (SubsetRule ISTIO_MUTUAL),
gRPC xDS client needs
+ // When TLS is configured (DestinationRule
ISTIO_MUTUAL), gRPC xDS client needs
// to fetch certificates from CertificateProvider. This
may take time, especially on
// first connection. We use a longer timeout context to
allow certificate fetching.
log.Printf("ForwardEcho: creating new connection for
%s...", req.Url)
@@ -427,7 +427,7 @@ func (s *testServerImpl) ForwardEcho(ctx context.Context,
req *pb.ForwardEchoReq
// was established before xDS config was received, it might be using
FallbackCreds (plaintext).
// We'll proceed with RPC calls, but if they fail with TLS/plaintext
mismatch errors,
// we'll clear the cache and retry.
- // When TLS is configured (SubsetRule ISTIO_MUTUAL), gRPC xDS client
needs
+ // When TLS is configured (DestinationRule ISTIO_MUTUAL), gRPC xDS
client needs
// to fetch certificates from CertificateProvider during TLS handshake.
The TLS handshake
// happens when the connection state transitions to READY. If
CertificateProvider is not ready,
// the TLS handshake will timeout. We need to wait for the connection
to be READY, which
@@ -595,7 +595,7 @@ func (s *testServerImpl) ForwardEcho(ctx context.Context,
req *pb.ForwardEchoReq
// 1. If client config changed (plaintext -> TLS), new
connection uses TLS
// 2. If server config changed (TLS -> plaintext), new
connection uses plaintext
// 3. Connection behavior is consistent with current
xDS configuration
- // - When only client TLS (SubsetRule ISTIO_MUTUAL) but
server plaintext: connection SHOULD FAIL
+ // - When only client TLS (DestinationRule
ISTIO_MUTUAL) but server plaintext: connection SHOULD FAIL
// - When client TLS + server mTLS (PeerAuthentication
STRICT): connection SHOULD SUCCEED
// - When both plaintext: connection SHOULD SUCCEED
// By clearing cache and reconnecting, we ensure
connection uses current xDS config.
@@ -613,8 +613,8 @@ func (s *testServerImpl) ForwardEcho(ctx context.Context,
req *pb.ForwardEchoReq
log.Printf("ForwardEcho: WARNING -
detected TLS/plaintext mismatch error: %v", err)
log.Printf("ForwardEcho: NOTE - This
error indicates that client and server TLS configuration are mismatched")
log.Printf("ForwardEcho: This usually
happens when:")
- log.Printf("ForwardEcho: 1.
SubsetRule with ISTIO_MUTUAL exists but PeerAuthentication with STRICT does not
(client TLS, server plaintext)")
- log.Printf("ForwardEcho: 2.
SubsetRule was deleted but cached connection still uses TLS")
+ log.Printf("ForwardEcho: 1.
DestinationRule with ISTIO_MUTUAL exists but PeerAuthentication with STRICT
does not (client TLS, server plaintext)")
+ log.Printf("ForwardEcho: 2.
DestinationRule was deleted but cached connection still uses TLS")
log.Printf("ForwardEcho: Clearing
connection cache to force reconnection with updated xDS config...")
}
diff --git a/tools/metadata/main.go b/tools/metadata/main.go
new file mode 100644
index 00000000..04aa67ca
--- /dev/null
+++ b/tools/metadata/main.go
@@ -0,0 +1,485 @@
+package main
+
+import (
+ "bytes"
+ "flag"
+ "fmt"
+ "log"
+ "os"
+ "path/filepath"
+ "regexp"
+ "sort"
+ "strings"
+ "text/template"
+
+ "github.com/gomarkdown/markdown"
+ "github.com/gomarkdown/markdown/html"
+ "github.com/gomarkdown/markdown/parser"
+ "github.com/spf13/cobra"
+ "sigs.k8s.io/yaml"
+)
+
+const (
+ outputTemplate = `
+// GENERATED FILE -- DO NOT EDIT
+
+package {{ .Package }}
+
+type FeatureStatus int
+
+const (
+ Alpha FeatureStatus = iota
+ Beta
+ Stable
+)
+
+func (s FeatureStatus) String() string {
+ switch s {
+ case Alpha:
+ return "Alpha"
+ case Beta:
+ return "Beta"
+ case Stable:
+ return "Stable"
+ }
+ return "Unknown"
+}
+
+type ResourceTypes int
+
+const (
+ Unknown ResourceTypes = iota
+ {{- range .KnownTypes }}
+ {{ . }}
+ {{- end }}
+)
+
+func (r ResourceTypes) String() string {
+ switch r {
+ {{- range $i, $t := .KnownTypes }}
+ case {{ add $i 1 }}:
+ return "{{$t}}"
+ {{- end }}
+ }
+ return "Unknown"
+}
+
+// Instance describes a single resource {{ .Collection.NameLowercase }}
+type Instance struct {
+ // The name of the {{ .Collection.NameLowercase }}.
+ Name string
+
+ // Description of the {{ .Collection.NameLowercase }}.
+ Description string
+
+ // FeatureStatus of this {{ .Collection.NameLowercase }}.
+ FeatureStatus FeatureStatus
+
+ // Hide the existence of this {{ .Collection.NameLowercase }} when
outputting usage information.
+ Hidden bool
+
+ // Mark this {{ .Collection.NameLowercase }} as deprecated when
generating usage information.
+ Deprecated bool
+
+ // The types of resources this {{ .Collection.NameLowercase }} applies
to.
+ Resources []ResourceTypes
+}
+
+var (
+{{ range .Variables }}
+ {{ .GoName }} = Instance {
+ Name: "{{ .Name }}",
+ Description: {{ processGoDescription .Description 24 }},
+ FeatureStatus: {{ .FeatureStatus }},
+ Hidden: {{ .Hidden }},
+ Deprecated: {{ .Deprecated }},
+ Resources: []ResourceTypes{
+ {{- range .Resources }}
+ {{ . }},
+ {{- end }}
+ },
+ }
+{{ end }}
+)
+
+func AllResource{{ .Collection.NamePlural }}() []*Instance {
+ return []*Instance {
+ {{- range .Variables }}
+ &{{ .GoName }},
+ {{- end }}
+ }
+}
+
+func AllResourceTypes() []string {
+ return []string {
+ {{- range .KnownTypes }}
+ "{{ . }}",
+ {{- end }}
+ }
+}
+`
+)
+
+type FeatureStatus string
+
+const (
+ Alpha FeatureStatus = "Alpha"
+ Beta FeatureStatus = "Beta"
+ Stable FeatureStatus = "Stable"
+)
+
+type Collection struct {
+ Name string
+ NamePlural string
+ NameLowercase string
+ NameLowercasePlural string
+ ConceptLink string
+}
+
+var (
+ annotations = Collection{
+ Name: "Annotation",
+ NamePlural: "Annotations",
+ NameLowercase: "annotation",
+ NameLowercasePlural: "annotations",
+ ConceptLink:
"https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/",
+ }
+
+ labels = Collection{
+ Name: "Label",
+ NamePlural: "Labels",
+ NameLowercase: "label",
+ NameLowercasePlural: "labels",
+ ConceptLink:
"https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/",
+ }
+)
+
+func collectionForType(typ string) (Collection, error) {
+ switch typ {
+ case annotations.NameLowercase:
+ return annotations, nil
+ case labels.NameLowercase:
+ return labels, nil
+ default:
+ return Collection{}, fmt.Errorf("unrecognized variable_type:
%s", typ)
+ }
+}
+
+var (
+ input string
+ output string
+ collectionType string
+ collection Collection
+
+ nameSeparator = regexp.MustCompile(`[._\-]`)
+
+ rootCmd = cobra.Command{
+ Use: "metadata",
+ Short: "Generates a Go source file and HTML file containing
annotations/labels.",
+ Long: "Generates a Go source file and HTML file containing
annotation/label definitions based " +
+ "on an input YAML file.",
+ Run: func(cmd *cobra.Command, args []string) {
+ processFlags()
+ yamlContent, err := os.ReadFile(input)
+ if err != nil {
+ log.Fatalf("unable to read input YAML file:
%v", err)
+ }
+
+ // Unmarshal the file.
+ var variables []Variable
+ switch collectionType {
+ case annotations.NameLowercase:
+ var cfg AnnotationConfiguration
+ if err = yaml.Unmarshal(yamlContent, &cfg); err
!= nil {
+ log.Fatalf("error parsing input YAML
file: %v", err)
+ }
+ variables = cfg.Variables
+ case labels.NameLowercase:
+ var cfg LabelConfiguration
+ if err = yaml.Unmarshal(yamlContent, &cfg); err
!= nil {
+ log.Fatalf("error parsing input YAML
file: %v", err)
+ }
+ variables = cfg.Variables
+ default:
+ log.Fatalf("invalid value for collection_type:
%s", collectionType)
+ }
+
+ // Find all the known resource types
+ m := make(map[string]bool)
+ for _, a := range variables {
+ for _, r := range a.Resources {
+ m[r] = true
+ }
+ }
+ knownTypes := make([]string, 0, len(m))
+ for k := range m {
+ knownTypes = append(knownTypes, k)
+ }
+ sort.Strings(knownTypes)
+
+ // Process/cleanup the values read in from YAML.
+ for i := range variables {
+ if variables[i].Name == "" {
+ log.Fatalf("variable %d in input YAML
file missing name", i)
+ }
+
+ // Generate sensible defaults for values if not
provided in the yaml.
+ variables[i].GoName =
generateVariableName(variables[i])
+ variables[i].FeatureStatus =
generateFeatureStatus(variables[i])
+ }
+
+ // sort by name
+ sort.Slice(variables, func(i, j int) bool {
+ return strings.Compare(variables[i].Name,
variables[j].Name) < 0
+ })
+
+ // Create the output file template.
+ t, err :=
template.New("varTemplate").Funcs(template.FuncMap{
+ "processGoDescription": processGoDescription,
"add": add,
+ }).Parse(outputTemplate)
+ if err != nil {
+ log.Fatalf("failed parsing variable template:
%v", err)
+ }
+
+ // Generate the Go source.
+ var goSource bytes.Buffer
+ if err := t.Execute(&goSource, map[string]interface{}{
+ "Package": getPackage(),
+ "KnownTypes": knownTypes,
+ "Variables": variables,
+ "Collection": collection,
+ }); err != nil {
+ log.Fatalf("failed generating output Go source
code %s: %v", output, err)
+ }
+
+ if err := os.WriteFile(output, goSource.Bytes(),
0o666); err != nil {
+ log.Fatalf("Failed writing to output file %s:
%v", output, err)
+ }
+ },
+ }
+)
+
+func init() {
+ rootCmd.PersistentFlags().StringVar(&input, "input", "",
+ "Input YAML file to be parsed.")
+ rootCmd.PersistentFlags().StringVar(&output, "output", "",
+ "Output Go file to be generated.")
+ rootCmd.PersistentFlags().StringVar(&collectionType, "collection_type",
annotations.NameLowercase,
+ fmt.Sprintf("Output type for the generated collection. Allowed
values are '%s' or '%s'.",
+ annotations.NameLowercase, labels.NameLowercase))
+ flag.CommandLine.VisitAll(func(gf *flag.Flag) {
+ rootCmd.PersistentFlags().AddGoFlag(gf)
+ })
+}
+
+func processFlags() {
+ var err error
+ collection, err = collectionForType(collectionType)
+ if err != nil {
+ log.Fatal(err)
+ }
+}
+
+func main() {
+ if err := rootCmd.Execute(); err != nil {
+ os.Exit(-1)
+ }
+}
+
+type Variable struct {
+ // The name of the generated golang variable.
+ GoName string `json:"variableName"`
+
+ // The name of the collection variable.
+ Name string `json:"name"`
+
+ // FeatureStatus of the collection variable.
+ FeatureStatus string `json:"featureStatus"`
+
+ // Description of the collection variable.
+ Description string `json:"description"`
+
+ // Hide the existence of this collection variable when outputting usage
information.
+ Hidden bool `json:"hidden"`
+
+ // Mark this annotation as deprecated when generating usage information.
+ Deprecated bool `json:"deprecated"`
+
+ // Indicates the types of resources this collection variable can be
applied to.
+ Resources []string `json:"resources"`
+}
+
+type AnnotationConfiguration struct {
+ Variables []Variable `json:"annotations"`
+}
+
+type LabelConfiguration struct {
+ Variables []Variable `json:"labels"`
+}
+
+func getPackage() string {
+ path, _ := filepath.Abs(output)
+ return filepath.Base(filepath.Dir(path))
+}
+
+func generateVariableName(v Variable) string {
+ if len(v.GoName) > 0 {
+ return v.GoName
+ }
+
+ // Split the annotation name to separate the namespace/name portions.
+ parts := strings.Split(v.Name, "/")
+ ns := parts[0]
+ name := parts[1]
+
+ // First, process the namespace portion ...
+
+ // Strip .istio.io from the namespace portion of the annotation name.
+ ns = strings.TrimSuffix(ns, ".istio.io")
+
+ // Separate the words by spaces and capitalize each word.
+ ns = strings.ReplaceAll(ns, ".", " ")
+ // nolint: staticcheck
+ ns = strings.Title(ns)
+
+ // Reverse the namespace words so that they increase in specificity
from left to right.
+ nsParts := strings.Split(ns, " ")
+ ns = ""
+ for i := len(nsParts) - 1; i >= 0; i-- {
+ ns += nsParts[i]
+ }
+
+ // Now, process the name portion ...
+
+ // Separate the words with spaces and capitalize each word.
+ name = nameSeparator.ReplaceAllString(name, " ")
+ // nolint: staticcheck
+ name = strings.Title(name)
+
+ // Remove the spaces to generate a camel case variable name.
+ name = strings.ReplaceAll(name, " ", "")
+
+ // Concatenate the names together.
+ return ns + name
+}
+
+func getFeatureStatus(fs string) (FeatureStatus, error) {
+ // nolint: staticcheck
+ asTitle := strings.Title(fs)
+ switch FeatureStatus(asTitle) {
+ case Alpha:
+ return Alpha, nil
+ case Beta:
+ return Beta, nil
+ case Stable:
+ return Stable, nil
+ }
+ return "", fmt.Errorf("invalid feature status string: `%s`
(stings.Title=`%s`)", fs, asTitle)
+}
+
+func generateFeatureStatus(v Variable) string {
+ if len(v.FeatureStatus) > 0 {
+ fs, err := getFeatureStatus(v.FeatureStatus)
+ if err != nil {
+ log.Fatal(err)
+ }
+ return string(fs)
+ }
+
+ // If the name begins with the feature status, use it.
+ firstPart := strings.Split(v.Name, ".")
+ fs, err := getFeatureStatus(firstPart[0])
+ if err == nil {
+ return string(fs)
+ }
+
+ // Default to Alpha
+ return string(Alpha)
+}
+
+func processHTMLDescription(in string) string {
+ // In most cases, the description is a single line in Markdown format.
+ // Convert it to HTML with a Markdown parser, this will give us a
better looking output.
+ return string(mdToHTML([]byte(in)))
+}
+
+func processGoDescription(in string, indent int) string {
+ if strings.Contains(in, "\n") {
+ return lineWrap(in)
+ }
+ return wordWrap(in, indent)
+}
+
+func wordWrap(in string, indent int) string {
+ // We use double quotes (") around each line, so replace any double
quotes embedded
+ // in the string with back ticks (`).
+ in = strings.ReplaceAll(in, "\"", "`")
+
+ indentPrefix := strings.Repeat(" ", indent)
+ words := strings.Split(in, " ")
+
+ maxLineLength := 80
+
+ out := ""
+ line := ""
+ for len(words) > 0 {
+ // Take the next word.
+ word := words[0]
+ words = words[1:]
+
+ if indent+len(line)+len(word) > maxLineLength {
+ // Need to word wrap - emit the current line.
+ out += "\"" + line + " \""
+ line = ""
+
+ // Wrap to the start of the next line.
+ out += "+\n" + indentPrefix
+ }
+
+ // Add the word to the current line.
+ if len(line) > 0 {
+ line += " "
+ }
+ line += word
+ }
+
+ // Emit the final line
+ out += "\"" + line + "\""
+
+ return out
+}
+
+func lineWrap(in string) string {
+ // We use back tick (`) around the entire string, so replace any back
ticks embedded
+ // in the string with double quotes (").
+ in = strings.ReplaceAll(in, "`", "\"")
+
+ lines := strings.Split(in, "\n")
+ out := "`"
+ for i, line := range lines {
+ out += line
+ if i < len(lines)-1 {
+ out += "\n"
+ }
+ }
+ out += "`"
+ return out
+}
+
+func add(x, y int) int {
+ return x + y
+}
+
+func mdToHTML(md []byte) []byte {
+ // create markdown parser with extensions
+ extensions := parser.CommonExtensions | parser.AutoHeadingIDs |
parser.NoEmptyLineBeforeBlock
+ p := parser.NewWithExtensions(extensions)
+ doc := p.Parse(md)
+
+ // create HTML renderer with extensions
+ htmlFlags := html.CommonFlags | html.HrefTargetBlank
+ opts := html.RendererOptions{Flags: htmlFlags}
+ renderer := html.NewRenderer(opts)
+
+ return markdown.Render(doc, renderer)
+}