Skip to content

Commit 3875a7c

Browse files
authored
Implement API and CRD for ztunnel component (openshift-service-mesh#481)
* Add SEP3 ambient mode first draft Signed-off-by: Yuanlin Xu <[email protected]> * OSSM-8381: Implement API for ztunnel component Signed-off-by: Yuanlin Xu <[email protected]> * review updates Signed-off-by: Yuanlin Xu <[email protected]> * Temporary define ZTunnelConfig in types_extra Signed-off-by: Yuanlin Xu <[email protected]> * fix bundle csv conflict Signed-off-by: Yuanlin Xu <[email protected]> * review update Signed-off-by: Yuanlin Xu <[email protected]> * update from make gen Signed-off-by: Yuanlin Xu <[email protected]> * install ztunnel in default ns istio-cni Signed-off-by: Yuanlin Xu <[email protected]> * update PROJECT Signed-off-by: Yuanlin Xu <[email protected]> * review update Signed-off-by: Yuanlin Xu <[email protected]> * move the SEP to a separate PR Signed-off-by: Yuanlin Xu <[email protected]> * update from make gen Signed-off-by: Yuanlin Xu <[email protected]> --------- Signed-off-by: Yuanlin Xu <[email protected]>
1 parent bc6bc70 commit 3875a7c

File tree

8 files changed

+12032
-0
lines changed

8 files changed

+12032
-0
lines changed

PROJECT

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,12 @@ resources:
4343
kind: IstioCNI
4444
path: github.com/istio-ecosystem/sail-operator/api/v1alpha1
4545
version: v1alpha1
46+
- api:
47+
crdVersion: v1
48+
namespaced: false
49+
controller: true
50+
domain: sailoperator.io
51+
kind: ZTunnel
52+
path: github.com/istio-ecosystem/sail-operator/api/v1alpha1
53+
version: v1alpha1
4654
version: "3"

api/v1alpha1/values_types_extra.go

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414

1515
package v1alpha1
1616

17+
import (
18+
k8sv1 "k8s.io/api/core/v1"
19+
)
20+
1721
type SDSConfigToken struct {
1822
Aud string `json:"aud,omitempty"`
1923
}
@@ -25,3 +29,106 @@ type CNIValues struct {
2529
// Part of the global configuration applicable to the Istio CNI component.
2630
Global *CNIGlobalConfig `json:"global,omitempty"`
2731
}
32+
33+
type ZTunnelValues struct {
34+
// Configuration for the Istio ztunnel plugin.
35+
ZTunnel *ZTunnelConfig `json:"ztunnel,omitempty"`
36+
37+
// Part of the global configuration applicable to the Istio ztunnel component.
38+
Global *ZTunnelGlobalConfig `json:"global,omitempty"`
39+
}
40+
41+
// Configuration for ztunnel.
42+
type ZTunnelConfig struct {
43+
// Hub to pull the container image from. Image will be `Hub/Image:Tag-Variant`.
44+
Hub *string `json:"hub,omitempty"`
45+
// The container image tag to pull. Image will be `Hub/Image:Tag-Variant`.
46+
Tag *string `json:"tag,omitempty"`
47+
// The container image variant to pull. Options are "debug" or "distroless". Unset will use the default for the given version.
48+
Variant *string `json:"variant,omitempty"`
49+
// Image name to pull from. Image will be `Hub/Image:Tag-Variant`.
50+
// If Image contains a "/", it will replace the entire `image` in the pod.
51+
Image *string `json:"image,omitempty"`
52+
// Annotations to apply to all top level resources
53+
Annotations map[string]string `json:"Annotations,omitempty"`
54+
// Labels to apply to all top level resources
55+
Labels map[string]string `json:"Labels,omitempty"`
56+
// Additional volumeMounts to the ztunnel container
57+
VolumeMounts []k8sv1.VolumeMount `json:"volumeMounts,omitempty"`
58+
// Additional volumes to add to the ztunnel Pod.
59+
Volumes []k8sv1.Volume `json:"volumes,omitempty"`
60+
// Annotations added to each pod. The default annotations are required for scraping prometheus (in most environments).
61+
PodAnnotations map[string]string `json:"podAnnotations,omitempty"`
62+
// Additional labels to apply on the pod level.
63+
PodLabels map[string]string `json:"podLabels,omitempty"`
64+
// The k8s resource requests and limits for the ztunnel Pods.
65+
Resources *k8sv1.ResourceRequirements `json:"resources,omitempty"`
66+
// List of secret names to add to the service account as image pull secrets
67+
// to use for pulling any images in pods that reference this ServiceAccount.
68+
// Must be set for any cluster configured with private docker registry.
69+
ImagePullSecrets []string `json:"imagePullSecrets,omitempty"`
70+
// A `key: value` mapping of environment variables to add to the pod
71+
Env map[string]string `json:"env,omitempty"`
72+
// Specifies the image pull policy for the Istio images. one of Always, Never, IfNotPresent.
73+
// Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated.
74+
//
75+
// More info: https://kubernetes.io/docs/concepts/containers/images#updating-images
76+
// +kubebuilder:validation:Enum=Always;Never;IfNotPresent
77+
ImagePullPolicy *k8sv1.PullPolicy `json:"imagePullPolicy,omitempty"`
78+
// Settings for multicluster.
79+
// The name of the cluster we are installing in. Note this is a user-defined name, which must be consistent
80+
// with Istiod configuration.
81+
MultiCluster *MultiClusterConfig `json:"multiCluster,omitempty"`
82+
// meshConfig defines runtime configuration of components.
83+
// For ztunnel, only defaultConfig is used, but this is nested under `meshConfig` for consistency with other components.
84+
MeshConfig *MeshConfig `json:"meshConfig,omitempty"`
85+
// Configures the revision this control plane is a part of
86+
Revision *string `json:"revision,omitempty"`
87+
// The address of the CA for CSR.
88+
CaAddress *string `json:"caAddress,omitempty"`
89+
// The customized XDS address to retrieve configuration.
90+
XdsAddress *string `json:"xdsAddress,omitempty"`
91+
// Specifies the default namespace for the Istio control plane components.
92+
IstioNamespace *string `json:"istioNamespace,omitempty"`
93+
// Same as `global.logging.level`, but will override it if set
94+
Logging *GlobalLoggingConfig `json:"logging,omitempty"`
95+
// Specifies whether istio components should output logs in json format by adding --log_as_json argument to each container.
96+
LogAsJSON *bool `json:"logAsJSON,omitempty"`
97+
}
98+
99+
// ZTunnelGlobalConfig is a subset of the Global Configuration used in the Istio ztunnel chart.
100+
type ZTunnelGlobalConfig struct { // Default k8s resources settings for all Istio control plane components.
101+
//
102+
// See https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#resource-requests-and-limits-of-pod-and-container
103+
//
104+
// Deprecated: Marked as deprecated in pkg/apis/values_types.proto.
105+
DefaultResources *k8sv1.ResourceRequirements `json:"defaultResources,omitempty"`
106+
107+
// Specifies the docker hub for Istio images.
108+
Hub *string `json:"hub,omitempty"`
109+
// Specifies the image pull policy for the Istio images. one of Always, Never, IfNotPresent.
110+
// Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated.
111+
//
112+
// More info: https://kubernetes.io/docs/concepts/containers/images#updating-images
113+
// +kubebuilder:validation:Enum=Always;Never;IfNotPresent
114+
ImagePullPolicy *k8sv1.PullPolicy `json:"imagePullPolicy,omitempty"`
115+
// ImagePullSecrets for the control plane ServiceAccount, list of secrets in the same namespace
116+
// to use for pulling any images in pods that reference this ServiceAccount.
117+
// Must be set for any cluster configured with private docker registry.
118+
ImagePullSecrets []string `json:"imagePullSecrets,omitempty"`
119+
120+
// Specifies whether istio components should output logs in json format by adding --log_as_json argument to each container.
121+
LogAsJSON *bool `json:"logAsJSON,omitempty"`
122+
// Specifies the global logging level settings for the Istio control plane components.
123+
Logging *GlobalLoggingConfig `json:"logging,omitempty"`
124+
125+
// Specifies the tag for the Istio docker images.
126+
Tag *string `json:"tag,omitempty"`
127+
// The variant of the Istio container images to use. Options are "debug" or "distroless". Unset will use the default for the given version.
128+
Variant *string `json:"variant,omitempty"`
129+
130+
// Platform in which Istio is deployed. Possible values are: "openshift" and "gcp"
131+
// An empty value means it is a vanilla Kubernetes distribution, therefore no special
132+
// treatment will be considered.
133+
Platform *string `json:"platform,omitempty"`
134+
}

api/v1alpha1/ztunnel_types.go

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
// Copyright Istio Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package v1alpha1
16+
17+
import (
18+
"time"
19+
20+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
21+
)
22+
23+
const (
24+
ZTunnelKind = "ZTunnel"
25+
)
26+
27+
// ZTunnelSpec defines the desired state of ZTunnel
28+
type ZTunnelSpec struct {
29+
// +sail:version
30+
// Defines the version of Istio to install.
31+
// Must be one of: v1.24.0 or latest.
32+
// +operator-sdk:csv:customresourcedefinitions:type=spec,order=1,displayName="Istio Version",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:General", "urn:alm:descriptor:com.tectonic.ui:select:v1.24.0", "urn:alm:descriptor:com.tectonic.ui:select:latest"}
33+
// +kubebuilder:validation:Enum=v1.24.0;latest
34+
// +kubebuilder:default=v1.24.0
35+
Version string `json:"version"`
36+
37+
// +sail:profile
38+
// The built-in installation configuration profile to use.
39+
// The 'default' profile is 'ambient' and it is always applied.
40+
// Must be one of: ambient, default, demo, empty, external, preview, remote, stable.
41+
// +++PROFILES-DROPDOWN-HIDDEN-UNTIL-WE-FULLY-IMPLEMENT-THEM+++operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Profile",xDescriptors={"urn:alm:descriptor:com.tectonic.ui:fieldGroup:General", "urn:alm:descriptor:com.tectonic.ui:select:ambient", "urn:alm:descriptor:com.tectonic.ui:select:default", "urn:alm:descriptor:com.tectonic.ui:select:demo", "urn:alm:descriptor:com.tectonic.ui:select:empty", "urn:alm:descriptor:com.tectonic.ui:select:external", "urn:alm:descriptor:com.tectonic.ui:select:minimal", "urn:alm:descriptor:com.tectonic.ui:select:preview", "urn:alm:descriptor:com.tectonic.ui:select:remote"}
42+
// +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:hidden"}
43+
// +kubebuilder:validation:Enum=ambient;default;demo;empty;external;openshift-ambient;openshift;preview;remote;stable
44+
// +kubebuilder:default=ambient
45+
Profile string `json:"profile,omitempty"`
46+
47+
// Namespace to which the Istio ztunnel component should be installed.
48+
// +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:io.kubernetes:Namespace"}
49+
// +kubebuilder:default=ztunnel
50+
Namespace string `json:"namespace"`
51+
52+
// Defines the values to be passed to the Helm charts when installing Istio ztunnel.
53+
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Helm Values"
54+
Values *ZTunnelValues `json:"values,omitempty"`
55+
}
56+
57+
// ZTunnelStatus defines the observed state of ZTunnel
58+
type ZTunnelStatus struct {
59+
// ObservedGeneration is the most recent generation observed for this
60+
// ZTunnel object. It corresponds to the object's generation, which is
61+
// updated on mutation by the API Server. The information in the status
62+
// pertains to this particular generation of the object.
63+
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
64+
65+
// Represents the latest available observations of the object's current state.
66+
Conditions []ZTunnelCondition `json:"conditions,omitempty"`
67+
68+
// Reports the current state of the object.
69+
State ZTunnelConditionReason `json:"state,omitempty"`
70+
}
71+
72+
// GetCondition returns the condition of the specified type
73+
func (s *ZTunnelStatus) GetCondition(conditionType ZTunnelConditionType) ZTunnelCondition {
74+
if s != nil {
75+
for i := range s.Conditions {
76+
if s.Conditions[i].Type == conditionType {
77+
return s.Conditions[i]
78+
}
79+
}
80+
}
81+
return ZTunnelCondition{Type: conditionType, Status: metav1.ConditionUnknown}
82+
}
83+
84+
// SetCondition sets a specific condition in the list of conditions
85+
func (s *ZTunnelStatus) SetCondition(condition ZTunnelCondition) {
86+
var now time.Time
87+
if testTime == nil {
88+
now = time.Now()
89+
} else {
90+
now = *testTime
91+
}
92+
93+
// The lastTransitionTime only gets serialized out to the second. This can
94+
// break update skipping, as the time in the resource returned from the client
95+
// may not match the time in our cached status during a reconcile. We truncate
96+
// here to save any problems down the line.
97+
lastTransitionTime := metav1.NewTime(now.Truncate(time.Second))
98+
99+
for i, prevCondition := range s.Conditions {
100+
if prevCondition.Type == condition.Type {
101+
if prevCondition.Status != condition.Status {
102+
condition.LastTransitionTime = lastTransitionTime
103+
} else {
104+
condition.LastTransitionTime = prevCondition.LastTransitionTime
105+
}
106+
s.Conditions[i] = condition
107+
return
108+
}
109+
}
110+
111+
// If the condition does not exist, initialize the lastTransitionTime
112+
condition.LastTransitionTime = lastTransitionTime
113+
s.Conditions = append(s.Conditions, condition)
114+
}
115+
116+
// ZTunnelCondition represents a specific observation of the ZTunnel object's state.
117+
type ZTunnelCondition struct {
118+
// The type of this condition.
119+
Type ZTunnelConditionType `json:"type,omitempty"`
120+
121+
// The status of this condition. Can be True, False or Unknown.
122+
Status metav1.ConditionStatus `json:"status,omitempty"`
123+
124+
// Unique, single-word, CamelCase reason for the condition's last transition.
125+
Reason ZTunnelConditionReason `json:"reason,omitempty"`
126+
127+
// Human-readable message indicating details about the last transition.
128+
Message string `json:"message,omitempty"`
129+
130+
// Last time the condition transitioned from one status to another.
131+
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"`
132+
}
133+
134+
// ZTunnelConditionType represents the type of the condition. Condition stages are:
135+
// Installed, Reconciled, Ready
136+
type ZTunnelConditionType string
137+
138+
// ZTunnelConditionReason represents a short message indicating how the condition came
139+
// to be in its present state.
140+
type ZTunnelConditionReason string
141+
142+
const (
143+
// ZTunnelConditionReconciled signifies whether the controller has
144+
// successfully reconciled the resources defined through the CR.
145+
ZTunnelConditionReconciled ZTunnelConditionType = "Reconciled"
146+
147+
// ZTunnelReasonReconcileError indicates that the reconciliation of the resource has failed, but will be retried.
148+
ZTunnelReasonReconcileError ZTunnelConditionReason = "ReconcileError"
149+
)
150+
151+
const (
152+
// ZTunnelConditionReady signifies whether the ztunnel DaemonSet is ready.
153+
ZTunnelConditionReady ZTunnelConditionType = "Ready"
154+
155+
// ZTunnelDaemonSetNotReady indicates that the ztunnel DaemonSet is not ready.
156+
ZTunnelDaemonSetNotReady ZTunnelConditionReason = "DaemonSetNotReady"
157+
158+
// ZTunnelReasonReadinessCheckFailed indicates that the DaemonSet readiness status could not be ascertained.
159+
ZTunnelReasonReadinessCheckFailed ZTunnelConditionReason = "ReadinessCheckFailed"
160+
)
161+
162+
const (
163+
// ZTunnelReasonHealthy indicates that the control plane is fully reconciled and that all components are ready.
164+
ZTunnelReasonHealthy ZTunnelConditionReason = "Healthy"
165+
)
166+
167+
// +kubebuilder:object:root=true
168+
// +kubebuilder:resource:scope=Cluster,categories=istio-io
169+
// +kubebuilder:subresource:status
170+
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description="Whether the Istio ztunnel installation is ready to handle requests."
171+
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.state",description="The current state of this object."
172+
// +kubebuilder:printcolumn:name="Version",type="string",JSONPath=".spec.version",description="The version of the Istio ztunnel installation."
173+
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="The age of the object"
174+
// +kubebuilder:validation:XValidation:rule="self.metadata.name == 'default'",message="metadata.name must be 'default'"
175+
176+
// ZTunnel represents a deployment of the Istio ztunnel component.
177+
type ZTunnel struct {
178+
metav1.TypeMeta `json:",inline"`
179+
metav1.ObjectMeta `json:"metadata,omitempty"`
180+
181+
// +kubebuilder:default={version: "v1.24.0", namespace: "ztunnel", profile: "ambient"}
182+
Spec ZTunnelSpec `json:"spec,omitempty"`
183+
184+
Status ZTunnelStatus `json:"status,omitempty"`
185+
}
186+
187+
// +kubebuilder:object:root=true
188+
189+
// ZTunnelList contains a list of ZTunnel
190+
type ZTunnelList struct {
191+
metav1.TypeMeta `json:",inline"`
192+
metav1.ListMeta `json:"metadata,omitempty"`
193+
Items []ZTunnel `json:"items"`
194+
}
195+
196+
func init() {
197+
SchemeBuilder.Register(&ZTunnel{}, &ZTunnelList{})
198+
}

0 commit comments

Comments
 (0)