From dcbcde071a95176e11730c7a9a0471408f63eaf1 Mon Sep 17 00:00:00 2001 From: rcernich Date: Wed, 18 Aug 2021 14:16:21 -0600 Subject: [PATCH] MAISTRA-2518 add conditions to federation status Signed-off-by: rcernich --- go.mod | 2 + go.sum | 2 - ...ration.maistra.io_exportedservicesets.yaml | 293 +++--- ...ration.maistra.io_importedservicesets.yaml | 235 +++-- ...ederation.maistra.io_servicemeshpeers.yaml | 415 ++++---- .../charts/base/files/gen-istio-cluster.yaml | 940 ++++++++++-------- pkg/servicemesh/federation/status/handler.go | 135 ++- .../federation/v1/exportedserviceset_types.go | 3 +- .../federation/v1/importedserviceset_types.go | 3 +- .../federation/v1/servicemeshpeer_types.go | 19 +- .../api/federation/v1/statusconditions.go | 142 +++ .../federation/v1/zz_generated.deepcopy.go | 41 + vendor/modules.txt | 3 +- 13 files changed, 1343 insertions(+), 890 deletions(-) create mode 100644 vendor/maistra.io/api/federation/v1/statusconditions.go diff --git a/go.mod b/go.mod index 610bb7d4fe6..266c458ce08 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,8 @@ module istio.io/istio go 1.15 +replace maistra.io/api => ../../maistra.io/api + // pin to v1.9.5 replace istio.io/api => github.com/istio/api v0.0.0-20210419172736-e076ff10ec38 diff --git a/go.sum b/go.sum index 3815c821e7b..12afb89f0ab 100644 --- a/go.sum +++ b/go.sum @@ -1440,8 +1440,6 @@ k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/ k8s.io/utils v0.0.0-20200912215256-4140de9c8800/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -maistra.io/api v0.0.0-20210726125459-3d5819d0bd1b h1:LLp9dJctk8s7WTgau8laV+29lc/lQ2cm5RIyZSDN3Cw= -maistra.io/api v0.0.0-20210726125459-3d5819d0bd1b/go.mod h1:lr+bFp/3PnYhRC/0IrDhCy7GfnQPhiOTW/CQ8qgTV9U= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/manifests/charts/base/crds/federation.maistra.io_exportedservicesets.yaml b/manifests/charts/base/crds/federation.maistra.io_exportedservicesets.yaml index 6ff179e6c2c..8e7ff74c6d3 100644 --- a/manifests/charts/base/crds/federation.maistra.io_exportedservicesets.yaml +++ b/manifests/charts/base/crds/federation.maistra.io_exportedservicesets.yaml @@ -1,6 +1,5 @@ ---- -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: @@ -14,150 +13,174 @@ spec: listKind: ExportedServiceSetList plural: exportedservicesets singular: exportedserviceset - preserveUnknownFields: false scope: Namespaced - subresources: - status: {} - validation: - openAPIV3Schema: - description: ExportedServiceSet is the Schema for configuring exported services. The name of the ExportedServiceSet resource must match the name of a ServiceMeshPeer resource defining the remote mesh to which the services will be exported. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec defines rules for matching services to be exported. - properties: - exportRules: - description: ExportRules are the rules that determine which services are exported from the mesh. The list is processed in order and the first spec in the list that applies to a service is the one that will be applied. This allows more specific selectors to be placed before more general selectors. - items: - properties: - labelSelector: - description: LabelSelector provides a mechanism for selecting services to export by using a label selector to match Service resources for export. - properties: - aliases: - description: 'Aliases is a map of aliases to apply to exported services. If a name is not found in the map, the original service name is exported. A ''*'' will match any name. The Aliases list will be processed in order, with the first match found being applied to the exported service. Examples: */foo->*/bar will match foo service in any namesapce, exporting it as bar from its original namespace. */foo->bar/bar will match foo service in any namespace, exporting it as bar/bar. foo/*->bar/* will match any service in foo namespace, exporting it from the bar namespace with its original name */*->bar/* will match any service and export it from the bar namespace with its original name. */*->*/* is the same as not specifying anything' - items: + versions: + - name: v1 + schema: + openAPIV3Schema: + description: ExportedServiceSet is the Schema for configuring exported services. The name of the ExportedServiceSet resource must match the name of a ServiceMeshPeer resource defining the remote mesh to which the services will be exported. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec defines rules for matching services to be exported. + properties: + exportRules: + description: ExportRules are the rules that determine which services are exported from the mesh. The list is processed in order and the first spec in the list that applies to a service is the one that will be applied. This allows more specific selectors to be placed before more general selectors. + items: + properties: + labelSelector: + description: LabelSelector provides a mechanism for selecting services to export by using a label selector to match Service resources for export. + properties: + aliases: + description: 'Aliases is a map of aliases to apply to exported services. If a name is not found in the map, the original service name is exported. A ''*'' will match any name. The Aliases list will be processed in order, with the first match found being applied to the exported service. Examples: */foo->*/bar will match foo service in any namesapce, exporting it as bar from its original namespace. */foo->bar/bar will match foo service in any namespace, exporting it as bar/bar. foo/*->bar/* will match any service in foo namespace, exporting it from the bar namespace with its original name */*->bar/* will match any service and export it from the bar namespace with its original name. */*->*/* is the same as not specifying anything' + items: + properties: + alias: + properties: + name: + type: string + namespace: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + type: array + namespace: + description: Namespace specifies to which namespace the selector applies. An empty value applies to all namespaces in the mesh. + type: string + selector: + description: Selector used to select Service resources in the namespace/mesh. An empty selector selects all services. properties: - alias: - properties: - name: - type: string - namespace: - type: string + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object + type: object + type: object + nameSelector: + description: NameSelector provides a simple name matcher for exporting services in the mesh. + properties: + alias: + properties: name: type: string namespace: type: string type: object - type: array - namespace: - description: Namespace specifies to which namespace the selector applies. An empty value applies to all namespaces in the mesh. - type: string - selector: - description: Selector used to select Service resources in the namespace/mesh. An empty selector selects all services. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. - properties: - key: - description: key is the label key that the selector applies to. - type: string - operator: - description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - type: object - nameSelector: - description: NameSelector provides a simple name matcher for exporting services in the mesh. - properties: - alias: - properties: - name: - type: string - namespace: - type: string - type: object - name: - type: string - namespace: - type: string - type: object - type: - description: Type of rule. One of Name or Label. - type: string - required: - - type - type: object - type: array - type: object - status: - properties: - exportedServices: - description: Exports provides details about the services exported by this mesh. - items: - description: PeerServiceMapping represents the name mapping between an exported service and its local counterpart. - properties: - exportedName: - description: ExportedName represents the fully qualified domain name (FQDN) of an exported service. For an exporting mesh, this is the name that is exported to the remote mesh. For an importing mesh, this would be the name of the service exported by the remote mesh. - type: string - localService: - description: LocalService represents the service in the local (i.e. this) mesh. For an exporting mesh, this would be the service being exported. For an importing mesh, this would be the imported service. - properties: - hostname: - description: Hostname represents fully qualified domain name (FQDN) used to access the service. - type: string - name: - description: Name represents the simple name of the service, e.g. the metadata.name field of a kubernetes Service. - type: string - namespace: - description: Namespace represents the namespace within which the service resides. - type: string - required: - - hostname - - name - - namespace - type: object - required: + name: + type: string + namespace: + type: string + type: object + type: + description: Type of rule. One of Name or Label. + type: string + required: + - type + type: object + type: array + type: object + status: + properties: + conditions: + description: Represents the latest available observations of a federation's current state. + items: + description: Condition describes the state of a federation at a certain point. + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: A human readable message indicating details about the transition. + type: string + reason: + description: The reason for the condition's last transition. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of federation condition. + type: string + required: + - status + - type + type: object + type: array + exportedServices: + description: Exports provides details about the services exported by this mesh. + items: + description: PeerServiceMapping represents the name mapping between an exported service and its local counterpart. + properties: + exportedName: + description: ExportedName represents the fully qualified domain name (FQDN) of an exported service. For an exporting mesh, this is the name that is exported to the remote mesh. For an importing mesh, this would be the name of the service exported by the remote mesh. + type: string + localService: + description: LocalService represents the service in the local (i.e. this) mesh. For an exporting mesh, this would be the service being exported. For an importing mesh, this would be the imported service. + properties: + hostname: + description: Hostname represents fully qualified domain name (FQDN) used to access the service. + type: string + name: + description: Name represents the simple name of the service, e.g. the metadata.name field of a kubernetes Service. + type: string + namespace: + description: Namespace represents the namespace within which the service resides. + type: string + required: + - hostname + - name + - namespace + type: object + required: + - exportedName + - localService + type: object + type: array + x-kubernetes-list-map-keys: - exportedName - - localService - type: object - type: array - x-kubernetes-list-map-keys: - - exportedName - x-kubernetes-list-type: map - required: - - exportedServices - type: object - type: object - version: v1 - versions: - - name: v1 + x-kubernetes-list-type: map + required: + - exportedServices + type: object + type: object served: true storage: true + subresources: + status: {} status: acceptedNames: kind: "" diff --git a/manifests/charts/base/crds/federation.maistra.io_importedservicesets.yaml b/manifests/charts/base/crds/federation.maistra.io_importedservicesets.yaml index 76d65c24ed5..0f2bf97ee6c 100644 --- a/manifests/charts/base/crds/federation.maistra.io_importedservicesets.yaml +++ b/manifests/charts/base/crds/federation.maistra.io_importedservicesets.yaml @@ -1,6 +1,5 @@ ---- -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: @@ -14,118 +13,142 @@ spec: listKind: ImportedServiceSetList plural: importedservicesets singular: importedserviceset - preserveUnknownFields: false scope: Namespaced - subresources: - status: {} - validation: - openAPIV3Schema: - description: ImportedServiceSet is the Schema for configuring imported services. The name of the ImportedServiceSet resource must match the name of a ServiceMeshPeer resource defining the remote mesh from which the services will be imported. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec defines rules for matching services to be imported. - properties: - domainSuffix: - description: 'DomainSuffix specifies the domain suffix to be applies to imported services. If no domain suffix is specified, imported services will be named as follows: ..svc.-imports.local If a domain suffix is specified, imported services will be named as follows: ..' - type: string - importRules: - description: ImportRules are the rules that determine which services are imported to the mesh. The list is processed in order and the first spec in the list that applies to a service is the one that will be applied. This allows more specific selectors to be placed before more general selectors. - items: + versions: + - name: v1 + schema: + openAPIV3Schema: + description: ImportedServiceSet is the Schema for configuring imported services. The name of the ImportedServiceSet resource must match the name of a ServiceMeshPeer resource defining the remote mesh from which the services will be imported. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec defines rules for matching services to be imported. + properties: + domainSuffix: + description: 'DomainSuffix specifies the domain suffix to be applies to imported services. If no domain suffix is specified, imported services will be named as follows: ..svc.-imports.local If a domain suffix is specified, imported services will be named as follows: ..' + type: string + importRules: + description: ImportRules are the rules that determine which services are imported to the mesh. The list is processed in order and the first spec in the list that applies to a service is the one that will be applied. This allows more specific selectors to be placed before more general selectors. + items: + properties: + domainSuffix: + description: DomainSuffix applies the specified suffix to services imported by this rule. The behavior is identical to that of ImportedServiceSetSpec.DomainSuffix. + type: string + importAsLocal: + description: ImportAsLocal imports the service as a local service in the mesh. For example, if an exported service, foo/bar is imported as some-ns/service, the service will be imported as service.some-ns.svc.cluster.local in the some-ns namespace. If a service of this name already exists in the mesh, the imported service's endpoints will be aggregated with any other workloads associated with the service. This setting overrides DomainSuffix. + type: boolean + nameSelector: + description: NameSelector provides a simple name matcher for importing services in the mesh. + properties: + alias: + properties: + name: + type: string + namespace: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + type: + description: Type of rule. Only Name type is supported. + type: string + required: + - type + type: object + type: array + locality: + description: Locality within which imported services should be associated. properties: - domainSuffix: - description: DomainSuffix applies the specified suffix to services imported by this rule. The behavior is identical to that of ImportedServiceSetSpec.DomainSuffix. + region: + description: Region within which imported services are located. type: string - importAsLocal: - description: ImportAsLocal imports the service as a local service in the mesh. For example, if an exported service, foo/bar is imported as some-ns/service, the service will be imported as service.some-ns.svc.cluster.local in the some-ns namespace. If a service of this name already exists in the mesh, the imported service's endpoints will be aggregated with any other workloads associated with the service. This setting overrides DomainSuffix. - type: boolean - nameSelector: - description: NameSelector provides a simple name matcher for importing services in the mesh. - properties: - alias: - properties: - name: - type: string - namespace: - type: string - type: object - name: - type: string - namespace: - type: string - type: object - type: - description: Type of rule. Only Name type is supported. + subzone: + description: Subzone within which imported services are located. If Subzone is specified, Zone must also be specified. type: string - required: - - type - type: object - type: array - locality: - description: Locality within which imported services should be associated. - properties: - region: - description: Region within which imported services are located. - type: string - subzone: - description: Subzone within which imported services are located. If Subzone is specified, Zone must also be specified. - type: string - zone: - description: Zone within which imported services are located. If Zone is specified, Region must also be specified. - type: string - type: object - type: object - status: - properties: - importedServices: - description: Imports provides details about the services imported by this mesh. - items: - description: PeerServiceMapping represents the name mapping between an exported service and its local counterpart. - properties: - exportedName: - description: ExportedName represents the fully qualified domain name (FQDN) of an exported service. For an exporting mesh, this is the name that is exported to the remote mesh. For an importing mesh, this would be the name of the service exported by the remote mesh. + zone: + description: Zone within which imported services are located. If Zone is specified, Region must also be specified. type: string - localService: - description: LocalService represents the service in the local (i.e. this) mesh. For an exporting mesh, this would be the service being exported. For an importing mesh, this would be the imported service. - properties: - hostname: - description: Hostname represents fully qualified domain name (FQDN) used to access the service. - type: string - name: - description: Name represents the simple name of the service, e.g. the metadata.name field of a kubernetes Service. - type: string - namespace: - description: Namespace represents the namespace within which the service resides. - type: string - required: - - hostname - - name - - namespace - type: object - required: - - exportedName - - localService type: object - type: array - x-kubernetes-list-map-keys: - - exportedName - x-kubernetes-list-type: map - required: - - importedServices - type: object - type: object - version: v1 - versions: - - name: v1 + type: object + status: + properties: + conditions: + description: Represents the latest available observations of a federation's current state. + items: + description: Condition describes the state of a federation at a certain point. + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: A human readable message indicating details about the transition. + type: string + reason: + description: The reason for the condition's last transition. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of federation condition. + type: string + required: + - status + - type + type: object + type: array + importedServices: + description: Imports provides details about the services imported by this mesh. + items: + description: PeerServiceMapping represents the name mapping between an exported service and its local counterpart. + properties: + exportedName: + description: ExportedName represents the fully qualified domain name (FQDN) of an exported service. For an exporting mesh, this is the name that is exported to the remote mesh. For an importing mesh, this would be the name of the service exported by the remote mesh. + type: string + localService: + description: LocalService represents the service in the local (i.e. this) mesh. For an exporting mesh, this would be the service being exported. For an importing mesh, this would be the imported service. + properties: + hostname: + description: Hostname represents fully qualified domain name (FQDN) used to access the service. + type: string + name: + description: Name represents the simple name of the service, e.g. the metadata.name field of a kubernetes Service. + type: string + namespace: + description: Namespace represents the namespace within which the service resides. + type: string + required: + - hostname + - name + - namespace + type: object + required: + - exportedName + - localService + type: object + type: array + x-kubernetes-list-map-keys: + - exportedName + x-kubernetes-list-type: map + required: + - importedServices + type: object + type: object served: true storage: true + subresources: + status: {} status: acceptedNames: kind: "" diff --git a/manifests/charts/base/crds/federation.maistra.io_servicemeshpeers.yaml b/manifests/charts/base/crds/federation.maistra.io_servicemeshpeers.yaml index d0d5cdc7e8e..f24bdff7cd7 100644 --- a/manifests/charts/base/crds/federation.maistra.io_servicemeshpeers.yaml +++ b/manifests/charts/base/crds/federation.maistra.io_servicemeshpeers.yaml @@ -1,6 +1,5 @@ ---- -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: @@ -16,105 +15,166 @@ spec: listKind: ServiceMeshPeerList plural: servicemeshpeers singular: servicemeshpeer - preserveUnknownFields: false scope: Namespaced - subresources: - status: {} - validation: - openAPIV3Schema: - description: ServiceMeshPeer is the Schema for joining two meshes together. The resource name will be used to identify the 'cluster' to which imported services belong. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: ServiceMeshPeerSpec configures details required to support federation with another service mesh. - properties: - gateways: - description: Gateways configures the gateways used to facilitate ingress and egress with the other mesh. - properties: - egress: - description: Gateway through which outbound federated service traffic will travel. This is not required if AllowDirectOutbound is set to true. - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - ingress: - description: Gateway through which inbound federated service traffic will travel. - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + versions: + - name: v1 + schema: + openAPIV3Schema: + description: ServiceMeshPeer is the Schema for joining two meshes together. The resource name will be used to identify the 'cluster' to which imported services belong. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ServiceMeshPeerSpec configures details required to support federation with another service mesh. + properties: + gateways: + description: Gateways configures the gateways used to facilitate ingress and egress with the other mesh. + properties: + egress: + description: Gateway through which outbound federated service traffic will travel. This is not required if AllowDirectOutbound is set to true. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + ingress: + description: Gateway through which inbound federated service traffic will travel. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + type: object + remote: + description: Remote configures details related to the remote mesh with which this mesh is federating. + properties: + addresses: + description: Addresses are the addresses to which discovery and service requests should be sent (i.e. the addresses of ingress gateways on the remote mesh). These may be specified as resolveable DNS names or IP addresses. + items: type: string - type: object - type: object - remote: - description: Remote configures details related to the remote mesh with which this mesh is federating. - properties: - addresses: - description: Addresses are the addresses to which discovery and service requests should be sent (i.e. the addresses of ingress gateways on the remote mesh). These may be specified as resolveable DNS names or IP addresses. - items: + type: array + discoveryPort: + description: DiscoveryPort is the port on which the addresses are handling discovery requests. Defaults to 8188, if unspecified. + format: int32 + type: integer + servicePort: + description: ServicePort is the port on which the addresses are handling service requests. Defaults to 15443, if unspecified. + format: int32 + type: integer + type: object + security: + description: Security configures details for securing communication with the other mesh. + properties: + certificateChain: + description: Name of ConfigMap containing certificate chain to be used to validate the remote. This is also used to validate certificates used by the remote services (both client and server certificates). The name of the entry should be root-cert.pem. If unspecified, it will look for a ConfigMap named -ca-root-cert, e.g. if this resource is named mesh1, it will look for a ConfigMap named mesh1-ca-root-cert. + properties: + apiGroup: + description: APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + clientID: + description: ClientID of the remote mesh. This is used to authenticate incoming requrests from the remote mesh's discovery client. type: string - type: array - discoveryPort: - description: DiscoveryPort is the port on which the addresses are handling discovery requests. Defaults to 8188, if unspecified. - format: int32 - type: integer - servicePort: - description: ServicePort is the port on which the addresses are handling service requests. Defaults to 15443, if unspecified. - format: int32 - type: integer - type: object - security: - description: Security configures details for securing communication with the other mesh. - properties: - certificateChain: - description: Name of ConfigMap containing certificate chain to be used to validate the remote. This is also used to validate certificates used by the remote services (both client and server certificates). The name of the entry should be root-cert.pem. If unspecified, it will look for a ConfigMap named -ca-root-cert, e.g. if this resource is named mesh1, it will look for a ConfigMap named mesh1-ca-root-cert. + trustDomain: + description: TrustDomain of remote mesh. + type: string + type: object + type: object + status: + description: ServiceMeshPeerStatus provides information related to the other mesh. + properties: + conditions: + description: Represents the latest available observations of a federation's current state. + items: + description: Condition describes the state of a federation at a certain point. properties: - apiGroup: - description: APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required. + lastTransitionTime: + description: Last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: A human readable message indicating details about the transition. + type: string + reason: + description: The reason for the condition's last transition. type: string - kind: - description: Kind is the type of resource being referenced + status: + description: Status of the condition, one of True, False, Unknown. type: string - name: - description: Name is the name of resource being referenced + type: + description: Type of federation condition. type: string required: - - kind - - name + - status + - type type: object - clientID: - description: ClientID of the remote mesh. This is used to authenticate incoming requrests from the remote mesh's discovery client. - type: string - trustDomain: - description: TrustDomain of remote mesh. - type: string - type: object - type: object - status: - description: ServiceMeshPeerStatus provides information related to the other mesh. - properties: - discoveryStatus: - description: DiscoveryStatus represents the discovery status of each pilot/istiod pod in the mesh. - properties: - active: - description: Active represents the pilot/istiod pods actively watching the other mesh for discovery. - items: - description: PodPeerDiscoveryStatus provides discovery details related to a specific pilot/istiod pod. - properties: - pod: - description: Pod is the pod name to which these details apply. This maps to a a pilot/istiod pod. - type: string - remotes: - description: Remotes represents details related to the inbound connections from remote meshes. - items: - description: DiscoveryRemoteStatus represents details related to an inbound connection from a remote mesh. + type: array + discoveryStatus: + description: DiscoveryStatus represents the discovery status of each pilot/istiod pod in the mesh. + properties: + active: + description: Active represents the pilot/istiod pods actively watching the other mesh for discovery. + items: + description: PodPeerDiscoveryStatus provides discovery details related to a specific pilot/istiod pod. + properties: + pod: + description: Pod is the pod name to which these details apply. This maps to a a pilot/istiod pod. + type: string + remotes: + description: Remotes represents details related to the inbound connections from remote meshes. + items: + description: DiscoveryRemoteStatus represents details related to an inbound connection from a remote mesh. + properties: + connected: + description: Connected identfies an active connection with the remote mesh. + type: boolean + lastConnected: + description: LastConnected represents the last time a connection with the remote mesh was successful. + format: date-time + type: string + lastDisconnect: + description: LastDisconnect represents the last time the connection with the remote mesh was disconnected. + format: date-time + type: string + lastDisconnectStatus: + description: LastDisconnectStatus is the status returned the last time the connection with the remote mesh was terminated. + type: string + lastEvent: + description: LastEvent represents the last time an event was received from the remote mesh. + format: date-time + type: string + lastFullSync: + description: LastFullSync represents the last time a full sync was performed with the remote mesh. + format: date-time + type: string + source: + description: Source represents the source of the remote watch. + type: string + required: + - connected + - source + type: object + type: array + x-kubernetes-list-map-keys: + - source + x-kubernetes-list-type: map + watch: + description: Watch represents details related to the outbound connection to the remote mesh. properties: connected: description: Connected identfies an active connection with the remote mesh. @@ -138,65 +198,65 @@ spec: description: LastFullSync represents the last time a full sync was performed with the remote mesh. format: date-time type: string - source: - description: Source represents the source of the remote watch. - type: string required: - connected - - source type: object - type: array - x-kubernetes-list-map-keys: - - source - x-kubernetes-list-type: map - watch: - description: Watch represents details related to the outbound connection to the remote mesh. - properties: - connected: - description: Connected identfies an active connection with the remote mesh. - type: boolean - lastConnected: - description: LastConnected represents the last time a connection with the remote mesh was successful. - format: date-time - type: string - lastDisconnect: - description: LastDisconnect represents the last time the connection with the remote mesh was disconnected. - format: date-time - type: string - lastDisconnectStatus: - description: LastDisconnectStatus is the status returned the last time the connection with the remote mesh was terminated. - type: string - lastEvent: - description: LastEvent represents the last time an event was received from the remote mesh. - format: date-time - type: string - lastFullSync: - description: LastFullSync represents the last time a full sync was performed with the remote mesh. - format: date-time - type: string - required: - - connected - type: object - required: + required: + - pod + type: object + nullable: true + type: array + x-kubernetes-list-map-keys: - pod - type: object - nullable: true - type: array - x-kubernetes-list-map-keys: - - pod - x-kubernetes-list-type: map - inactive: - description: Inactive represents the pilot/istiod pods not actively watching the other mesh for discovery. - items: - description: PodPeerDiscoveryStatus provides discovery details related to a specific pilot/istiod pod. - properties: - pod: - description: Pod is the pod name to which these details apply. This maps to a a pilot/istiod pod. - type: string - remotes: - description: Remotes represents details related to the inbound connections from remote meshes. - items: - description: DiscoveryRemoteStatus represents details related to an inbound connection from a remote mesh. + x-kubernetes-list-type: map + inactive: + description: Inactive represents the pilot/istiod pods not actively watching the other mesh for discovery. + items: + description: PodPeerDiscoveryStatus provides discovery details related to a specific pilot/istiod pod. + properties: + pod: + description: Pod is the pod name to which these details apply. This maps to a a pilot/istiod pod. + type: string + remotes: + description: Remotes represents details related to the inbound connections from remote meshes. + items: + description: DiscoveryRemoteStatus represents details related to an inbound connection from a remote mesh. + properties: + connected: + description: Connected identfies an active connection with the remote mesh. + type: boolean + lastConnected: + description: LastConnected represents the last time a connection with the remote mesh was successful. + format: date-time + type: string + lastDisconnect: + description: LastDisconnect represents the last time the connection with the remote mesh was disconnected. + format: date-time + type: string + lastDisconnectStatus: + description: LastDisconnectStatus is the status returned the last time the connection with the remote mesh was terminated. + type: string + lastEvent: + description: LastEvent represents the last time an event was received from the remote mesh. + format: date-time + type: string + lastFullSync: + description: LastFullSync represents the last time a full sync was performed with the remote mesh. + format: date-time + type: string + source: + description: Source represents the source of the remote watch. + type: string + required: + - connected + - source + type: object + type: array + x-kubernetes-list-map-keys: + - source + x-kubernetes-list-type: map + watch: + description: Watch represents details related to the outbound connection to the remote mesh. properties: connected: description: Connected identfies an active connection with the remote mesh. @@ -220,61 +280,24 @@ spec: description: LastFullSync represents the last time a full sync was performed with the remote mesh. format: date-time type: string - source: - description: Source represents the source of the remote watch. - type: string required: - connected - - source type: object - type: array - x-kubernetes-list-map-keys: - - source - x-kubernetes-list-type: map - watch: - description: Watch represents details related to the outbound connection to the remote mesh. - properties: - connected: - description: Connected identfies an active connection with the remote mesh. - type: boolean - lastConnected: - description: LastConnected represents the last time a connection with the remote mesh was successful. - format: date-time - type: string - lastDisconnect: - description: LastDisconnect represents the last time the connection with the remote mesh was disconnected. - format: date-time - type: string - lastDisconnectStatus: - description: LastDisconnectStatus is the status returned the last time the connection with the remote mesh was terminated. - type: string - lastEvent: - description: LastEvent represents the last time an event was received from the remote mesh. - format: date-time - type: string - lastFullSync: - description: LastFullSync represents the last time a full sync was performed with the remote mesh. - format: date-time - type: string - required: - - connected - type: object - required: + required: + - pod + type: object + nullable: true + type: array + x-kubernetes-list-map-keys: - pod - type: object - nullable: true - type: array - x-kubernetes-list-map-keys: - - pod - x-kubernetes-list-type: map - type: object - type: object - type: object - version: v1 - versions: - - name: v1 + x-kubernetes-list-type: map + type: object + type: object + type: object served: true storage: true + subresources: + status: {} status: acceptedNames: kind: "" diff --git a/manifests/charts/base/files/gen-istio-cluster.yaml b/manifests/charts/base/files/gen-istio-cluster.yaml index 22c8d1a5ecc..a9b0435b733 100644 --- a/manifests/charts/base/files/gen-istio-cluster.yaml +++ b/manifests/charts/base/files/gen-istio-cluster.yaml @@ -3523,7 +3523,7 @@ spec: # Source: crds/federation.maistra.io_exportedservicesets.yaml --- -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: @@ -3537,150 +3537,174 @@ spec: listKind: ExportedServiceSetList plural: exportedservicesets singular: exportedserviceset - preserveUnknownFields: false scope: Namespaced - subresources: - status: {} - validation: - openAPIV3Schema: - description: ExportedServiceSet is the Schema for configuring exported services. The name of the ExportedServiceSet resource must match the name of a ServiceMeshPeer resource defining the remote mesh to which the services will be exported. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec defines rules for matching services to be exported. - properties: - exportRules: - description: ExportRules are the rules that determine which services are exported from the mesh. The list is processed in order and the first spec in the list that applies to a service is the one that will be applied. This allows more specific selectors to be placed before more general selectors. - items: - properties: - labelSelector: - description: LabelSelector provides a mechanism for selecting services to export by using a label selector to match Service resources for export. - properties: - aliases: - description: 'Aliases is a map of aliases to apply to exported services. If a name is not found in the map, the original service name is exported. A ''*'' will match any name. The Aliases list will be processed in order, with the first match found being applied to the exported service. Examples: */foo->*/bar will match foo service in any namesapce, exporting it as bar from its original namespace. */foo->bar/bar will match foo service in any namespace, exporting it as bar/bar. foo/*->bar/* will match any service in foo namespace, exporting it from the bar namespace with its original name */*->bar/* will match any service and export it from the bar namespace with its original name. */*->*/* is the same as not specifying anything' - items: + versions: + - name: v1 + schema: + openAPIV3Schema: + description: ExportedServiceSet is the Schema for configuring exported services. The name of the ExportedServiceSet resource must match the name of a ServiceMeshPeer resource defining the remote mesh to which the services will be exported. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec defines rules for matching services to be exported. + properties: + exportRules: + description: ExportRules are the rules that determine which services are exported from the mesh. The list is processed in order and the first spec in the list that applies to a service is the one that will be applied. This allows more specific selectors to be placed before more general selectors. + items: + properties: + labelSelector: + description: LabelSelector provides a mechanism for selecting services to export by using a label selector to match Service resources for export. + properties: + aliases: + description: 'Aliases is a map of aliases to apply to exported services. If a name is not found in the map, the original service name is exported. A ''*'' will match any name. The Aliases list will be processed in order, with the first match found being applied to the exported service. Examples: */foo->*/bar will match foo service in any namesapce, exporting it as bar from its original namespace. */foo->bar/bar will match foo service in any namespace, exporting it as bar/bar. foo/*->bar/* will match any service in foo namespace, exporting it from the bar namespace with its original name */*->bar/* will match any service and export it from the bar namespace with its original name. */*->*/* is the same as not specifying anything' + items: + properties: + alias: + properties: + name: + type: string + namespace: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + type: array + namespace: + description: Namespace specifies to which namespace the selector applies. An empty value applies to all namespaces in the mesh. + type: string + selector: + description: Selector used to select Service resources in the namespace/mesh. An empty selector selects all services. properties: - alias: - properties: - name: - type: string - namespace: - type: string + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. type: object + type: object + type: object + nameSelector: + description: NameSelector provides a simple name matcher for exporting services in the mesh. + properties: + alias: + properties: name: type: string namespace: type: string type: object - type: array - namespace: - description: Namespace specifies to which namespace the selector applies. An empty value applies to all namespaces in the mesh. - type: string - selector: - description: Selector used to select Service resources in the namespace/mesh. An empty selector selects all services. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. - properties: - key: - description: key is the label key that the selector applies to. - type: string - operator: - description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - type: object - nameSelector: - description: NameSelector provides a simple name matcher for exporting services in the mesh. - properties: - alias: - properties: - name: - type: string - namespace: - type: string - type: object - name: - type: string - namespace: - type: string - type: object - type: - description: Type of rule. One of Name or Label. - type: string - required: - - type - type: object - type: array - type: object - status: - properties: - exportedServices: - description: Exports provides details about the services exported by this mesh. - items: - description: PeerServiceMapping represents the name mapping between an exported service and its local counterpart. - properties: - exportedName: - description: ExportedName represents the fully qualified domain name (FQDN) of an exported service. For an exporting mesh, this is the name that is exported to the remote mesh. For an importing mesh, this would be the name of the service exported by the remote mesh. - type: string - localService: - description: LocalService represents the service in the local (i.e. this) mesh. For an exporting mesh, this would be the service being exported. For an importing mesh, this would be the imported service. - properties: - hostname: - description: Hostname represents fully qualified domain name (FQDN) used to access the service. - type: string - name: - description: Name represents the simple name of the service, e.g. the metadata.name field of a kubernetes Service. - type: string - namespace: - description: Namespace represents the namespace within which the service resides. - type: string - required: - - hostname - - name - - namespace - type: object - required: + name: + type: string + namespace: + type: string + type: object + type: + description: Type of rule. One of Name or Label. + type: string + required: + - type + type: object + type: array + type: object + status: + properties: + conditions: + description: Represents the latest available observations of a federation's current state. + items: + description: Condition describes the state of a federation at a certain point. + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: A human readable message indicating details about the transition. + type: string + reason: + description: The reason for the condition's last transition. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of federation condition. + type: string + required: + - status + - type + type: object + type: array + exportedServices: + description: Exports provides details about the services exported by this mesh. + items: + description: PeerServiceMapping represents the name mapping between an exported service and its local counterpart. + properties: + exportedName: + description: ExportedName represents the fully qualified domain name (FQDN) of an exported service. For an exporting mesh, this is the name that is exported to the remote mesh. For an importing mesh, this would be the name of the service exported by the remote mesh. + type: string + localService: + description: LocalService represents the service in the local (i.e. this) mesh. For an exporting mesh, this would be the service being exported. For an importing mesh, this would be the imported service. + properties: + hostname: + description: Hostname represents fully qualified domain name (FQDN) used to access the service. + type: string + name: + description: Name represents the simple name of the service, e.g. the metadata.name field of a kubernetes Service. + type: string + namespace: + description: Namespace represents the namespace within which the service resides. + type: string + required: + - hostname + - name + - namespace + type: object + required: + - exportedName + - localService + type: object + type: array + x-kubernetes-list-map-keys: - exportedName - - localService - type: object - type: array - x-kubernetes-list-map-keys: - - exportedName - x-kubernetes-list-type: map - required: - - exportedServices - type: object - type: object - version: v1 - versions: - - name: v1 + x-kubernetes-list-type: map + required: + - exportedServices + type: object + type: object served: true storage: true + subresources: + status: {} status: acceptedNames: kind: "" @@ -3692,7 +3716,7 @@ status: # Source: crds/federation.maistra.io_importedservicesets.yaml --- -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: @@ -3706,118 +3730,142 @@ spec: listKind: ImportedServiceSetList plural: importedservicesets singular: importedserviceset - preserveUnknownFields: false scope: Namespaced - subresources: - status: {} - validation: - openAPIV3Schema: - description: ImportedServiceSet is the Schema for configuring imported services. The name of the ImportedServiceSet resource must match the name of a ServiceMeshPeer resource defining the remote mesh from which the services will be imported. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec defines rules for matching services to be imported. - properties: - domainSuffix: - description: 'DomainSuffix specifies the domain suffix to be applies to imported services. If no domain suffix is specified, imported services will be named as follows: ..svc.-imports.local If a domain suffix is specified, imported services will be named as follows: ..' - type: string - importRules: - description: ImportRules are the rules that determine which services are imported to the mesh. The list is processed in order and the first spec in the list that applies to a service is the one that will be applied. This allows more specific selectors to be placed before more general selectors. - items: + versions: + - name: v1 + schema: + openAPIV3Schema: + description: ImportedServiceSet is the Schema for configuring imported services. The name of the ImportedServiceSet resource must match the name of a ServiceMeshPeer resource defining the remote mesh from which the services will be imported. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec defines rules for matching services to be imported. + properties: + domainSuffix: + description: 'DomainSuffix specifies the domain suffix to be applies to imported services. If no domain suffix is specified, imported services will be named as follows: ..svc.-imports.local If a domain suffix is specified, imported services will be named as follows: ..' + type: string + importRules: + description: ImportRules are the rules that determine which services are imported to the mesh. The list is processed in order and the first spec in the list that applies to a service is the one that will be applied. This allows more specific selectors to be placed before more general selectors. + items: + properties: + domainSuffix: + description: DomainSuffix applies the specified suffix to services imported by this rule. The behavior is identical to that of ImportedServiceSetSpec.DomainSuffix. + type: string + importAsLocal: + description: ImportAsLocal imports the service as a local service in the mesh. For example, if an exported service, foo/bar is imported as some-ns/service, the service will be imported as service.some-ns.svc.cluster.local in the some-ns namespace. If a service of this name already exists in the mesh, the imported service's endpoints will be aggregated with any other workloads associated with the service. This setting overrides DomainSuffix. + type: boolean + nameSelector: + description: NameSelector provides a simple name matcher for importing services in the mesh. + properties: + alias: + properties: + name: + type: string + namespace: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + type: + description: Type of rule. Only Name type is supported. + type: string + required: + - type + type: object + type: array + locality: + description: Locality within which imported services should be associated. properties: - domainSuffix: - description: DomainSuffix applies the specified suffix to services imported by this rule. The behavior is identical to that of ImportedServiceSetSpec.DomainSuffix. + region: + description: Region within which imported services are located. type: string - importAsLocal: - description: ImportAsLocal imports the service as a local service in the mesh. For example, if an exported service, foo/bar is imported as some-ns/service, the service will be imported as service.some-ns.svc.cluster.local in the some-ns namespace. If a service of this name already exists in the mesh, the imported service's endpoints will be aggregated with any other workloads associated with the service. This setting overrides DomainSuffix. - type: boolean - nameSelector: - description: NameSelector provides a simple name matcher for importing services in the mesh. - properties: - alias: - properties: - name: - type: string - namespace: - type: string - type: object - name: - type: string - namespace: - type: string - type: object - type: - description: Type of rule. Only Name type is supported. + subzone: + description: Subzone within which imported services are located. If Subzone is specified, Zone must also be specified. type: string - required: - - type - type: object - type: array - locality: - description: Locality within which imported services should be associated. - properties: - region: - description: Region within which imported services are located. - type: string - subzone: - description: Subzone within which imported services are located. If Subzone is specified, Zone must also be specified. - type: string - zone: - description: Zone within which imported services are located. If Zone is specified, Region must also be specified. - type: string - type: object - type: object - status: - properties: - importedServices: - description: Imports provides details about the services imported by this mesh. - items: - description: PeerServiceMapping represents the name mapping between an exported service and its local counterpart. - properties: - exportedName: - description: ExportedName represents the fully qualified domain name (FQDN) of an exported service. For an exporting mesh, this is the name that is exported to the remote mesh. For an importing mesh, this would be the name of the service exported by the remote mesh. + zone: + description: Zone within which imported services are located. If Zone is specified, Region must also be specified. type: string - localService: - description: LocalService represents the service in the local (i.e. this) mesh. For an exporting mesh, this would be the service being exported. For an importing mesh, this would be the imported service. - properties: - hostname: - description: Hostname represents fully qualified domain name (FQDN) used to access the service. - type: string - name: - description: Name represents the simple name of the service, e.g. the metadata.name field of a kubernetes Service. - type: string - namespace: - description: Namespace represents the namespace within which the service resides. - type: string - required: - - hostname - - name - - namespace - type: object - required: - - exportedName - - localService type: object - type: array - x-kubernetes-list-map-keys: - - exportedName - x-kubernetes-list-type: map - required: - - importedServices - type: object - type: object - version: v1 - versions: - - name: v1 + type: object + status: + properties: + conditions: + description: Represents the latest available observations of a federation's current state. + items: + description: Condition describes the state of a federation at a certain point. + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: A human readable message indicating details about the transition. + type: string + reason: + description: The reason for the condition's last transition. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of federation condition. + type: string + required: + - status + - type + type: object + type: array + importedServices: + description: Imports provides details about the services imported by this mesh. + items: + description: PeerServiceMapping represents the name mapping between an exported service and its local counterpart. + properties: + exportedName: + description: ExportedName represents the fully qualified domain name (FQDN) of an exported service. For an exporting mesh, this is the name that is exported to the remote mesh. For an importing mesh, this would be the name of the service exported by the remote mesh. + type: string + localService: + description: LocalService represents the service in the local (i.e. this) mesh. For an exporting mesh, this would be the service being exported. For an importing mesh, this would be the imported service. + properties: + hostname: + description: Hostname represents fully qualified domain name (FQDN) used to access the service. + type: string + name: + description: Name represents the simple name of the service, e.g. the metadata.name field of a kubernetes Service. + type: string + namespace: + description: Namespace represents the namespace within which the service resides. + type: string + required: + - hostname + - name + - namespace + type: object + required: + - exportedName + - localService + type: object + type: array + x-kubernetes-list-map-keys: + - exportedName + x-kubernetes-list-type: map + required: + - importedServices + type: object + type: object served: true storage: true + subresources: + status: {} status: acceptedNames: kind: "" @@ -3829,7 +3877,7 @@ status: # Source: crds/federation.maistra.io_servicemeshpeers.yaml --- -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: @@ -3845,105 +3893,166 @@ spec: listKind: ServiceMeshPeerList plural: servicemeshpeers singular: servicemeshpeer - preserveUnknownFields: false scope: Namespaced - subresources: - status: {} - validation: - openAPIV3Schema: - description: ServiceMeshPeer is the Schema for joining two meshes together. The resource name will be used to identify the 'cluster' to which imported services belong. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: ServiceMeshPeerSpec configures details required to support federation with another service mesh. - properties: - gateways: - description: Gateways configures the gateways used to facilitate ingress and egress with the other mesh. - properties: - egress: - description: Gateway through which outbound federated service traffic will travel. This is not required if AllowDirectOutbound is set to true. - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - ingress: - description: Gateway through which inbound federated service traffic will travel. - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + versions: + - name: v1 + schema: + openAPIV3Schema: + description: ServiceMeshPeer is the Schema for joining two meshes together. The resource name will be used to identify the 'cluster' to which imported services belong. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ServiceMeshPeerSpec configures details required to support federation with another service mesh. + properties: + gateways: + description: Gateways configures the gateways used to facilitate ingress and egress with the other mesh. + properties: + egress: + description: Gateway through which outbound federated service traffic will travel. This is not required if AllowDirectOutbound is set to true. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + ingress: + description: Gateway through which inbound federated service traffic will travel. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + type: object + remote: + description: Remote configures details related to the remote mesh with which this mesh is federating. + properties: + addresses: + description: Addresses are the addresses to which discovery and service requests should be sent (i.e. the addresses of ingress gateways on the remote mesh). These may be specified as resolveable DNS names or IP addresses. + items: type: string - type: object - type: object - remote: - description: Remote configures details related to the remote mesh with which this mesh is federating. - properties: - addresses: - description: Addresses are the addresses to which discovery and service requests should be sent (i.e. the addresses of ingress gateways on the remote mesh). These may be specified as resolveable DNS names or IP addresses. - items: + type: array + discoveryPort: + description: DiscoveryPort is the port on which the addresses are handling discovery requests. Defaults to 8188, if unspecified. + format: int32 + type: integer + servicePort: + description: ServicePort is the port on which the addresses are handling service requests. Defaults to 15443, if unspecified. + format: int32 + type: integer + type: object + security: + description: Security configures details for securing communication with the other mesh. + properties: + certificateChain: + description: Name of ConfigMap containing certificate chain to be used to validate the remote. This is also used to validate certificates used by the remote services (both client and server certificates). The name of the entry should be root-cert.pem. If unspecified, it will look for a ConfigMap named -ca-root-cert, e.g. if this resource is named mesh1, it will look for a ConfigMap named mesh1-ca-root-cert. + properties: + apiGroup: + description: APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + clientID: + description: ClientID of the remote mesh. This is used to authenticate incoming requrests from the remote mesh's discovery client. type: string - type: array - discoveryPort: - description: DiscoveryPort is the port on which the addresses are handling discovery requests. Defaults to 8188, if unspecified. - format: int32 - type: integer - servicePort: - description: ServicePort is the port on which the addresses are handling service requests. Defaults to 15443, if unspecified. - format: int32 - type: integer - type: object - security: - description: Security configures details for securing communication with the other mesh. - properties: - certificateChain: - description: Name of ConfigMap containing certificate chain to be used to validate the remote. This is also used to validate certificates used by the remote services (both client and server certificates). The name of the entry should be root-cert.pem. If unspecified, it will look for a ConfigMap named -ca-root-cert, e.g. if this resource is named mesh1, it will look for a ConfigMap named mesh1-ca-root-cert. + trustDomain: + description: TrustDomain of remote mesh. + type: string + type: object + type: object + status: + description: ServiceMeshPeerStatus provides information related to the other mesh. + properties: + conditions: + description: Represents the latest available observations of a federation's current state. + items: + description: Condition describes the state of a federation at a certain point. properties: - apiGroup: - description: APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required. + lastTransitionTime: + description: Last time the condition transitioned from one status to another. + format: date-time type: string - kind: - description: Kind is the type of resource being referenced + message: + description: A human readable message indicating details about the transition. type: string - name: - description: Name is the name of resource being referenced + reason: + description: The reason for the condition's last transition. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of federation condition. type: string required: - - kind - - name + - status + - type type: object - clientID: - description: ClientID of the remote mesh. This is used to authenticate incoming requrests from the remote mesh's discovery client. - type: string - trustDomain: - description: TrustDomain of remote mesh. - type: string - type: object - type: object - status: - description: ServiceMeshPeerStatus provides information related to the other mesh. - properties: - discoveryStatus: - description: DiscoveryStatus represents the discovery status of each pilot/istiod pod in the mesh. - properties: - active: - description: Active represents the pilot/istiod pods actively watching the other mesh for discovery. - items: - description: PodPeerDiscoveryStatus provides discovery details related to a specific pilot/istiod pod. - properties: - pod: - description: Pod is the pod name to which these details apply. This maps to a a pilot/istiod pod. - type: string - remotes: - description: Remotes represents details related to the inbound connections from remote meshes. - items: - description: DiscoveryRemoteStatus represents details related to an inbound connection from a remote mesh. + type: array + discoveryStatus: + description: DiscoveryStatus represents the discovery status of each pilot/istiod pod in the mesh. + properties: + active: + description: Active represents the pilot/istiod pods actively watching the other mesh for discovery. + items: + description: PodPeerDiscoveryStatus provides discovery details related to a specific pilot/istiod pod. + properties: + pod: + description: Pod is the pod name to which these details apply. This maps to a a pilot/istiod pod. + type: string + remotes: + description: Remotes represents details related to the inbound connections from remote meshes. + items: + description: DiscoveryRemoteStatus represents details related to an inbound connection from a remote mesh. + properties: + connected: + description: Connected identfies an active connection with the remote mesh. + type: boolean + lastConnected: + description: LastConnected represents the last time a connection with the remote mesh was successful. + format: date-time + type: string + lastDisconnect: + description: LastDisconnect represents the last time the connection with the remote mesh was disconnected. + format: date-time + type: string + lastDisconnectStatus: + description: LastDisconnectStatus is the status returned the last time the connection with the remote mesh was terminated. + type: string + lastEvent: + description: LastEvent represents the last time an event was received from the remote mesh. + format: date-time + type: string + lastFullSync: + description: LastFullSync represents the last time a full sync was performed with the remote mesh. + format: date-time + type: string + source: + description: Source represents the source of the remote watch. + type: string + required: + - connected + - source + type: object + type: array + x-kubernetes-list-map-keys: + - source + x-kubernetes-list-type: map + watch: + description: Watch represents details related to the outbound connection to the remote mesh. properties: connected: description: Connected identfies an active connection with the remote mesh. @@ -3967,65 +4076,65 @@ spec: description: LastFullSync represents the last time a full sync was performed with the remote mesh. format: date-time type: string - source: - description: Source represents the source of the remote watch. - type: string required: - connected - - source type: object - type: array - x-kubernetes-list-map-keys: - - source - x-kubernetes-list-type: map - watch: - description: Watch represents details related to the outbound connection to the remote mesh. - properties: - connected: - description: Connected identfies an active connection with the remote mesh. - type: boolean - lastConnected: - description: LastConnected represents the last time a connection with the remote mesh was successful. - format: date-time - type: string - lastDisconnect: - description: LastDisconnect represents the last time the connection with the remote mesh was disconnected. - format: date-time - type: string - lastDisconnectStatus: - description: LastDisconnectStatus is the status returned the last time the connection with the remote mesh was terminated. - type: string - lastEvent: - description: LastEvent represents the last time an event was received from the remote mesh. - format: date-time - type: string - lastFullSync: - description: LastFullSync represents the last time a full sync was performed with the remote mesh. - format: date-time - type: string - required: - - connected - type: object - required: + required: + - pod + type: object + nullable: true + type: array + x-kubernetes-list-map-keys: - pod - type: object - nullable: true - type: array - x-kubernetes-list-map-keys: - - pod - x-kubernetes-list-type: map - inactive: - description: Inactive represents the pilot/istiod pods not actively watching the other mesh for discovery. - items: - description: PodPeerDiscoveryStatus provides discovery details related to a specific pilot/istiod pod. - properties: - pod: - description: Pod is the pod name to which these details apply. This maps to a a pilot/istiod pod. - type: string - remotes: - description: Remotes represents details related to the inbound connections from remote meshes. - items: - description: DiscoveryRemoteStatus represents details related to an inbound connection from a remote mesh. + x-kubernetes-list-type: map + inactive: + description: Inactive represents the pilot/istiod pods not actively watching the other mesh for discovery. + items: + description: PodPeerDiscoveryStatus provides discovery details related to a specific pilot/istiod pod. + properties: + pod: + description: Pod is the pod name to which these details apply. This maps to a a pilot/istiod pod. + type: string + remotes: + description: Remotes represents details related to the inbound connections from remote meshes. + items: + description: DiscoveryRemoteStatus represents details related to an inbound connection from a remote mesh. + properties: + connected: + description: Connected identfies an active connection with the remote mesh. + type: boolean + lastConnected: + description: LastConnected represents the last time a connection with the remote mesh was successful. + format: date-time + type: string + lastDisconnect: + description: LastDisconnect represents the last time the connection with the remote mesh was disconnected. + format: date-time + type: string + lastDisconnectStatus: + description: LastDisconnectStatus is the status returned the last time the connection with the remote mesh was terminated. + type: string + lastEvent: + description: LastEvent represents the last time an event was received from the remote mesh. + format: date-time + type: string + lastFullSync: + description: LastFullSync represents the last time a full sync was performed with the remote mesh. + format: date-time + type: string + source: + description: Source represents the source of the remote watch. + type: string + required: + - connected + - source + type: object + type: array + x-kubernetes-list-map-keys: + - source + x-kubernetes-list-type: map + watch: + description: Watch represents details related to the outbound connection to the remote mesh. properties: connected: description: Connected identfies an active connection with the remote mesh. @@ -4049,61 +4158,24 @@ spec: description: LastFullSync represents the last time a full sync was performed with the remote mesh. format: date-time type: string - source: - description: Source represents the source of the remote watch. - type: string required: - connected - - source type: object - type: array - x-kubernetes-list-map-keys: - - source - x-kubernetes-list-type: map - watch: - description: Watch represents details related to the outbound connection to the remote mesh. - properties: - connected: - description: Connected identfies an active connection with the remote mesh. - type: boolean - lastConnected: - description: LastConnected represents the last time a connection with the remote mesh was successful. - format: date-time - type: string - lastDisconnect: - description: LastDisconnect represents the last time the connection with the remote mesh was disconnected. - format: date-time - type: string - lastDisconnectStatus: - description: LastDisconnectStatus is the status returned the last time the connection with the remote mesh was terminated. - type: string - lastEvent: - description: LastEvent represents the last time an event was received from the remote mesh. - format: date-time - type: string - lastFullSync: - description: LastFullSync represents the last time a full sync was performed with the remote mesh. - format: date-time - type: string - required: - - connected - type: object - required: + required: + - pod + type: object + nullable: true + type: array + x-kubernetes-list-map-keys: - pod - type: object - nullable: true - type: array - x-kubernetes-list-map-keys: - - pod - x-kubernetes-list-type: map - type: object - type: object - type: object - version: v1 - versions: - - name: v1 + x-kubernetes-list-type: map + type: object + type: object + type: object served: true storage: true + subresources: + status: {} status: acceptedNames: kind: "" diff --git a/pkg/servicemesh/federation/status/handler.go b/pkg/servicemesh/federation/status/handler.go index b378291268a..416d896bd27 100644 --- a/pkg/servicemesh/federation/status/handler.go +++ b/pkg/servicemesh/federation/status/handler.go @@ -17,12 +17,14 @@ package status import ( "context" "encoding/json" + "fmt" "reflect" "sort" "strings" "sync" "time" + corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -395,7 +397,7 @@ func (h *handler) Flush() error { // see if we need to update the export status if h.exportsDirty { - var exports []v1.PeerServiceMapping + exports := []v1.PeerServiceMapping{} for _, mapping := range h.exports { exports = append(exports, mapping) } @@ -416,7 +418,7 @@ func (h *handler) Flush() error { // see if we need to update the import status if h.importsDirty { - var imports []v1.PeerServiceMapping + imports := []v1.PeerServiceMapping{} for _, mapping := range h.imports { imports = append(imports, mapping) } @@ -448,7 +450,7 @@ func (h *handler) Flush() error { return err } oldStatus := mf.Status.DeepCopy() - newStatus := &v1.ServiceMeshPeerStatus{} + newStatus := &v1.ServiceMeshPeerStatus{StatusConditions: *oldStatus.StatusConditions.DeepCopy()} newStatus.DiscoveryStatus = oldStatus.DeepCopy().DiscoveryStatus if h.discoveryStatus.Watch.Connected { @@ -472,14 +474,14 @@ func (h *handler) Flush() error { } } + h.updateConditions(newStatus) + // XXX: the created patch does not merge properly and can cause duplicate entries in discovery status patch, err := h.createPatch(&v1.ServiceMeshPeer{Status: *newStatus}, &v1.ServiceMeshPeer{Status: *oldStatus}, peerStatusPatchMetadata) if err != nil { return err } - h.logger.Debugf("status patch:\n%s\n", string(patch)) - if len(patch) == 0 || string(patch) == "{}" { // nothing to patch h.logger.Debugf("no status updates for ServiceMeshPeer %s", h.mesh) @@ -494,6 +496,78 @@ func (h *handler) Flush() error { return utilerrors.NewAggregate(allErrors) } +func (h *handler) updateConditions(status *v1.ServiceMeshPeerStatus) { + connected, degradedMessage, servingCount, ready := func() (bool, string, int, bool) { + activeConnections := len(status.DiscoveryStatus.Active) + inactiveConnections := len(status.DiscoveryStatus.Inactive) + var degradedMessage string + if inactiveConnections > 0 { + degradedMessage = fmt.Sprintf("%d of %d connections are inactive", inactiveConnections, inactiveConnections+activeConnections) + } + servingCount := 0 + for _, details := range status.DiscoveryStatus.Active { + for _, remote := range details.Remotes { + if remote.Connected { + servingCount++ + } + } + } + for _, details := range status.DiscoveryStatus.Inactive { + for _, remote := range details.Remotes { + if remote.Connected { + servingCount++ + } + } + } + return inactiveConnections == 0, degradedMessage, servingCount, degradedMessage == "" + }() + + connectedCondition := v1.Condition{Type: v1.ConnectedServiceMeshPeerCondition} + if connected { + connectedCondition.Reason = "Connected" + connectedCondition.Status = corev1.ConditionTrue + } else { + connectedCondition.Reason = "NotConnected" + connectedCondition.Status = corev1.ConditionFalse + } + + degradedCondition := v1.Condition{Type: v1.DegradedServiceMeshPeerCondition} + if degradedMessage == "" || !connected { + degradedCondition.Reason = v1.NotDegradedConditionReason + degradedCondition.Status = corev1.ConditionFalse + degradedCondition.Message = "" + } else { + degradedCondition.Reason = v1.DegradedConditionReason + degradedCondition.Status = corev1.ConditionTrue + degradedCondition.Message = degradedMessage + } + + servingCondition := v1.Condition{Type: v1.ServingServiceMeshPeerCondition} + if servingCount == 0 { + servingCondition.Reason = v1.NotServingConditionReason + servingCondition.Message = fmt.Sprintf("no connections from peer '%s'", h.mesh.Name) + servingCondition.Status = corev1.ConditionFalse + } else { + servingCondition.Reason = v1.ServingConditionReason + servingCondition.Message = fmt.Sprintf("servicing %d connections from peer '%s'", servingCount, h.mesh.Name) + servingCondition.Status = corev1.ConditionTrue + } + + readyCondition := v1.Condition{Type: v1.ReadyServiceMeshPeerCondition, Message: degradedMessage} + if ready { + readyCondition.Reason = v1.ReadyConditionReason + readyCondition.Status = corev1.ConditionTrue + } else { + readyCondition.Reason = v1.NotReadyConditionReason + readyCondition.Status = corev1.ConditionFalse + } + + status.SetCondition(readyCondition) + status.SetCondition(connectedCondition) + status.SetCondition(degradedCondition) + status.SetCondition(servingCondition) +} + func (h *handler) patchExports() error { exportSet, err := h.manager.rm.ExportsInformer().Lister().ExportedServiceSets(h.mesh.Namespace).Get(h.mesh.Name) if err != nil { @@ -504,7 +578,22 @@ func (h *handler) patchExports() error { return err } - patch, err := h.createPatch(&v1.ExportedServiceSet{Status: v1.ExportedServiceSetStatus{ExportedServices: h.exportsStatus}}, + newStatus := exportSet.Status.DeepCopy() + condition := v1.Condition{Type: v1.ExportingExportedServiceSetCondition} + if len(h.exportsStatus) > 0 { + condition.Status = corev1.ConditionTrue + condition.Reason = v1.ExportingConditionReason + } else { + condition.Status = corev1.ConditionFalse + if len(exportSet.Spec.ExportRules) > 0 { + condition.Reason = v1.NoRulesMatchedConditionReason + } else { + condition.Reason = v1.NoRulesDefinedConditionReason + } + } + newStatus.SetCondition(condition) + newStatus.ExportedServices = h.exportsStatus + patch, err := h.createPatch(&v1.ExportedServiceSet{Status: *newStatus}, &v1.ExportedServiceSet{Status: exportSet.DeepCopy().Status}, exportStatusPatchMetadata) if err != nil { return err @@ -535,7 +624,36 @@ func (h *handler) patchImports() error { return err } - patch, err := h.createPatch(&v1.ImportedServiceSet{Status: v1.ImportedServiceSetStatus{ImportedServices: h.importsStatus}}, + newStatus := importSet.Status.DeepCopy() + condition := v1.Condition{Type: v1.ImportingImportedServiceSetCondition} + hasImportsAvailable, isImportingServices := func() (bool, bool) { + importsAvailable := false + for _, service := range h.importsStatus { + importsAvailable = true + if service.LocalService.Name != "" { + return importsAvailable, true + } + } + return importsAvailable, false + }() + if isImportingServices { + condition.Status = corev1.ConditionTrue + condition.Reason = v1.ImportingConditionReason + } else { + condition.Status = corev1.ConditionFalse + if hasImportsAvailable { + if len(importSet.Spec.ImportRules) > 0 { + condition.Reason = v1.NoRulesMatchedConditionReason + } else { + condition.Reason = v1.NoRulesDefinedConditionReason + } + } else { + condition.Reason = v1.NoExportedServicesConditionReason + } + } + newStatus.SetCondition(condition) + newStatus.ImportedServices = h.importsStatus + patch, err := h.createPatch(&v1.ImportedServiceSet{Status: *newStatus}, &v1.ImportedServiceSet{Status: importSet.DeepCopy().Status}, importStatusPatchMetadata) if err != nil { return err @@ -573,6 +691,9 @@ func (h *handler) createPatch(newObj, oldObj interface{}, metadata strategicpatc if err != nil { return nil, err } + + h.logger.Debugf("status patch:\n%s\n", string(patch)) + return patch, nil } diff --git a/vendor/maistra.io/api/federation/v1/exportedserviceset_types.go b/vendor/maistra.io/api/federation/v1/exportedserviceset_types.go index acebe858e20..b84bc848d24 100644 --- a/vendor/maistra.io/api/federation/v1/exportedserviceset_types.go +++ b/vendor/maistra.io/api/federation/v1/exportedserviceset_types.go @@ -68,11 +68,12 @@ type ExportedServiceRule struct { } type ExportedServiceSetStatus struct { + StatusConditions `json:",inline"` // Exports provides details about the services exported by this mesh. // +required // +listType=map // +listMapKey=exportedName // +patchMergeKey=exportedName // +patchStrategy=merge,retainKeys - ExportedServices []PeerServiceMapping `json:"exportedServices"` + ExportedServices []PeerServiceMapping `json:"exportedServices" patchStrategy:"merge,retainKeys" patchMergeKey:"exportedName"` } diff --git a/vendor/maistra.io/api/federation/v1/importedserviceset_types.go b/vendor/maistra.io/api/federation/v1/importedserviceset_types.go index 2f43b11de03..5e145e7cf35 100644 --- a/vendor/maistra.io/api/federation/v1/importedserviceset_types.go +++ b/vendor/maistra.io/api/federation/v1/importedserviceset_types.go @@ -98,11 +98,12 @@ type ImportedServiceLocality struct { } type ImportedServiceSetStatus struct { + StatusConditions `json:",inline"` // Imports provides details about the services imported by this mesh. // +required // +listType=map // +listMapKey=exportedName // +patchMergeKey=exportedName // +patchStrategy=merge,retainKeys - ImportedServices []PeerServiceMapping `json:"importedServices"` + ImportedServices []PeerServiceMapping `json:"importedServices" patchStrategy:"merge,retainKeys" patchMergeKey:"exportedName"` } diff --git a/vendor/maistra.io/api/federation/v1/servicemeshpeer_types.go b/vendor/maistra.io/api/federation/v1/servicemeshpeer_types.go index 4bd4b43bd95..7ce13e66344 100644 --- a/vendor/maistra.io/api/federation/v1/servicemeshpeer_types.go +++ b/vendor/maistra.io/api/federation/v1/servicemeshpeer_types.go @@ -120,6 +120,7 @@ type ServiceMeshPeerRemote struct { // ServiceMeshPeerStatus provides information related to the other mesh. type ServiceMeshPeerStatus struct { + StatusConditions `json:",inline"` // DiscoveryStatus represents the discovery status of each pilot/istiod pod // in the mesh. // +optional @@ -139,7 +140,7 @@ type ServiceMeshPeerDiscoveryStatus struct { // +listMapKey=pod // +patchMergeKey=pod // +patchStrategy=merge,retainKeys - Active []PodPeerDiscoveryStatus `json:"active,omitempty"` + Active []PodPeerDiscoveryStatus `json:"active,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"pod"` // Inactive represents the pilot/istiod pods not actively watching the other // mesh for discovery. // +optional @@ -148,7 +149,7 @@ type ServiceMeshPeerDiscoveryStatus struct { // +listMapKey=pod // +patchMergeKey=pod // +patchStrategy=merge,retainKeys - Inactive []PodPeerDiscoveryStatus `json:"inactive,omitempty"` + Inactive []PodPeerDiscoveryStatus `json:"inactive,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"pod"` } // PodPeerDiscoveryStatus provides discovery details related to a specific @@ -156,7 +157,8 @@ type ServiceMeshPeerDiscoveryStatus struct { type PodPeerDiscoveryStatus struct { // PeerDiscoveryStatus provides details about the connection to the remote mesh. // +required - PeerDiscoveryStatus `json:",inline"` + // +patchStrategy=merge,retainKeys + PeerDiscoveryStatus `json:",inline" patchStrategy:"merge,retainKeys"` // Pod is the pod name to which these details apply. This maps to a // a pilot/istiod pod. // +required @@ -173,17 +175,19 @@ type PeerDiscoveryStatus struct { // +listMapKey=source // +patchMergeKey=source // +patchStrategy=merge,retainKeys - Remotes []DiscoveryRemoteStatus `json:"remotes,omitempty"` + Remotes []DiscoveryRemoteStatus `json:"remotes,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"source"` // Watch represents details related to the outbound connection to the // remote mesh. // +required - Watch DiscoveryWatchStatus `json:"watch,omitempty"` + // +patchStrategy=merge,retainKeys + Watch DiscoveryWatchStatus `json:"watch,omitempty" patchStrategy:"merge,retainKeys` } // DiscoveryRemoteStatus represents details related to an inbound connection // from a remote mesh. type DiscoveryRemoteStatus struct { - DiscoveryConnectionStatus `json:",inline"` + // +patchStrategy=merge,retainKeys + DiscoveryConnectionStatus `json:",inline" patchStrategy:"merge,retainKeys"` // Source represents the source of the remote watch. // +required Source string `json:"source"` @@ -192,7 +196,8 @@ type DiscoveryRemoteStatus struct { // DiscoveryWatchStatus represents details related to the outbound connection // to the remote mesh. type DiscoveryWatchStatus struct { - DiscoveryConnectionStatus `json:",inline"` + // +patchStrategy=merge,retainKeys + DiscoveryConnectionStatus `json:",inline" patchStrategy:"merge,retainKeys"` } // DiscoveryConnectionStatus represents details related to connections with diff --git a/vendor/maistra.io/api/federation/v1/statusconditions.go b/vendor/maistra.io/api/federation/v1/statusconditions.go new file mode 100644 index 00000000000..3268588fcd9 --- /dev/null +++ b/vendor/maistra.io/api/federation/v1/statusconditions.go @@ -0,0 +1,142 @@ +// Copyright Red Hat, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1 + +import ( + "time" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type StatusConditions struct { + // Represents the latest available observations of a federation's current state. + // +optional + // +patchMergeKey=type + // +patchStrategy=merge + Conditions []Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` +} + +type ConditionType string + +const ( + // Connected indicates that one or more instances of istiod are currently + // connected to the remote mesh. + ConnectedServiceMeshPeerCondition ConditionType = "Connected" + // Degraded indicates that one or more instances of istiod are currently + // not connected to the remote mesh. + DegradedServiceMeshPeerCondition ConditionType = "Degraded" + // Serving indicates that one or more instances of istiod is currently + // serving discovery information to a remote mesh. + ServingServiceMeshPeerCondition ConditionType = "Serving" + // Ready indicates that all instances of istiod are connected to the remote + // mesh. + ReadyServiceMeshPeerCondition ConditionType = "Ready" + // Exporting indicates that the mesh is exporting services to the remote + // mesh. + ExportingExportedServiceSetCondition ConditionType = "Exporting" + // Importing indicates that the mesh is importing services from the remote + // mesh. + ImportingImportedServiceSetCondition ConditionType = "Importing" +) + +const ( + ConnectedConditionReason = "Connected" + NotConnectedConditionReason = "NotConnected" + DegradedConditionReason = "Degraded" + NotDegradedConditionReason = "NotDegraded" + ServingConditionReason = "Serving" + NotServingConditionReason = "NotServing" + ReadyConditionReason = "Ready" + NotReadyConditionReason = "NotReady" + ExportingConditionReason = "Exporting" + NoRulesMatchedConditionReason = "NoRulesMatched" + NoRulesDefinedConditionReason = "NoRulesDefined" + ImportingConditionReason = "Importing" + NoExportedServicesConditionReason = "NoExportedServices" +) + +// Condition describes the state of a federation at a certain point. +type Condition struct { + // Type of federation condition. + Type ConditionType `json:"type"` + // Status of the condition, one of True, False, Unknown. + Status corev1.ConditionStatus `json:"status"` + // Last time the condition transitioned from one status to another. + // +optional + LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"` + // The reason for the condition's last transition. + // +optional + Reason string `json:"reason,omitempty"` + // A human readable message indicating details about the transition. + // +optional + Message string `json:"message,omitempty"` +} + +// GetCondition removes a condition for the list of conditions +func (s *StatusConditions) GetCondition(conditionType ConditionType) Condition { + if s == nil { + return Condition{Type: conditionType, Status: corev1.ConditionUnknown} + } + for i := range s.Conditions { + if s.Conditions[i].Type == conditionType { + return s.Conditions[i] + } + } + return Condition{Type: conditionType, Status: corev1.ConditionUnknown} +} + +// SetCondition sets a specific condition in the list of conditions +func (s *StatusConditions) SetCondition(condition Condition) *StatusConditions { + if s == nil { + return nil + } + // These only get serialized out to the second. This can break update + // skipping, as the time in the resource returned from the client may not + // match the time in our cached status during a reconcile. We truncate here + // to save any problems down the line. + now := metav1.NewTime(time.Now().Truncate(time.Second)) + for i, prevCondition := range s.Conditions { + if prevCondition.Type == condition.Type { + if prevCondition.Status != condition.Status { + condition.LastTransitionTime = now + } else { + condition.LastTransitionTime = prevCondition.LastTransitionTime + } + s.Conditions[i] = condition + return s + } + } + + // If the condition does not exist, + // initialize the lastTransitionTime + condition.LastTransitionTime = now + s.Conditions = append(s.Conditions, condition) + return s +} + +// RemoveCondition removes a condition for the list of conditions +func (s *StatusConditions) RemoveCondition(conditionType ConditionType) *StatusConditions { + if s == nil { + return nil + } + for i := range s.Conditions { + if s.Conditions[i].Type == conditionType { + s.Conditions = append(s.Conditions[:i], s.Conditions[i+1:]...) + return s + } + } + return s +} diff --git a/vendor/maistra.io/api/federation/v1/zz_generated.deepcopy.go b/vendor/maistra.io/api/federation/v1/zz_generated.deepcopy.go index ede9ebfc9e3..bb1bb523efc 100644 --- a/vendor/maistra.io/api/federation/v1/zz_generated.deepcopy.go +++ b/vendor/maistra.io/api/federation/v1/zz_generated.deepcopy.go @@ -22,6 +22,22 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Condition) DeepCopyInto(out *Condition) { + *out = *in + in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition. +func (in *Condition) DeepCopy() *Condition { + if in == nil { + return nil + } + out := new(Condition) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DiscoveryConnectionStatus) DeepCopyInto(out *DiscoveryConnectionStatus) { *out = *in @@ -182,6 +198,7 @@ func (in *ExportedServiceSetSpec) DeepCopy() *ExportedServiceSetSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ExportedServiceSetStatus) DeepCopyInto(out *ExportedServiceSetStatus) { *out = *in + in.StatusConditions.DeepCopyInto(&out.StatusConditions) if in.ExportedServices != nil { in, out := &in.ExportedServices, &out.ExportedServices *out = make([]PeerServiceMapping, len(*in)) @@ -323,6 +340,7 @@ func (in *ImportedServiceSetSpec) DeepCopy() *ImportedServiceSetSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ImportedServiceSetStatus) DeepCopyInto(out *ImportedServiceSetStatus) { *out = *in + in.StatusConditions.DeepCopyInto(&out.StatusConditions) if in.ImportedServices != nil { in, out := &in.ImportedServices, &out.ImportedServices *out = make([]PeerServiceMapping, len(*in)) @@ -595,6 +613,7 @@ func (in *ServiceMeshPeerSpec) DeepCopy() *ServiceMeshPeerSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ServiceMeshPeerStatus) DeepCopyInto(out *ServiceMeshPeerStatus) { *out = *in + in.StatusConditions.DeepCopyInto(&out.StatusConditions) in.DiscoveryStatus.DeepCopyInto(&out.DiscoveryStatus) } @@ -643,3 +662,25 @@ func (in *ServiceNameMapping) DeepCopy() *ServiceNameMapping { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StatusConditions) DeepCopyInto(out *StatusConditions) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatusConditions. +func (in *StatusConditions) DeepCopy() *StatusConditions { + if in == nil { + return nil + } + out := new(StatusConditions) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 9eab099dddd..a54200758aa 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1751,7 +1751,7 @@ k8s.io/utils/exec k8s.io/utils/integer k8s.io/utils/pointer k8s.io/utils/trace -# maistra.io/api v0.0.0-20210726125459-3d5819d0bd1b +# maistra.io/api v0.0.0-20210726125459-3d5819d0bd1b => ../../maistra.io/api ## explicit maistra.io/api/client/informers/externalversions maistra.io/api/client/informers/externalversions/core @@ -1867,6 +1867,7 @@ sigs.k8s.io/structured-merge-diff/v4/value # sigs.k8s.io/yaml v1.2.0 ## explicit sigs.k8s.io/yaml +# maistra.io/api => ../../maistra.io/api # istio.io/api => github.com/istio/api v0.0.0-20210419172736-e076ff10ec38 # github.com/spf13/viper => github.com/istio/viper v1.3.3-0.20190515210538-2789fed3109c # github.com/chzyer/logex => github.com/chzyer/logex v1.1.11-0.20170329064859-445be9e134b2