Skip to content

Commit

Permalink
Implement API and CRD for ztunnel component (istio-ecosystem#481)
Browse files Browse the repository at this point in the history
* Add SEP3 ambient mode first draft

Signed-off-by: Yuanlin Xu <yuanlin.xu@redhat.com>

* OSSM-8381: Implement API for ztunnel component

Signed-off-by: Yuanlin Xu <yuanlin.xu@redhat.com>

* review updates

Signed-off-by: Yuanlin Xu <yuanlin.xu@redhat.com>

* Temporary define ZTunnelConfig in types_extra

Signed-off-by: Yuanlin Xu <yuanlin.xu@redhat.com>

* fix bundle csv conflict

Signed-off-by: Yuanlin Xu <yuanlin.xu@redhat.com>

* review update

Signed-off-by: Yuanlin Xu <yuanlin.xu@redhat.com>

* update from make gen

Signed-off-by: Yuanlin Xu <yuanlin.xu@redhat.com>

* install ztunnel in default ns istio-cni

Signed-off-by: Yuanlin Xu <yuanlin.xu@redhat.com>

* update PROJECT

Signed-off-by: Yuanlin Xu <yuanlin.xu@redhat.com>

* review update

Signed-off-by: Yuanlin Xu <yuanlin.xu@redhat.com>

* move the SEP to a separate PR

Signed-off-by: Yuanlin Xu <yuanlin.xu@redhat.com>

* update from make gen

Signed-off-by: Yuanlin Xu <yuanlin.xu@redhat.com>

---------

Signed-off-by: Yuanlin Xu <yuanlin.xu@redhat.com>
  • Loading branch information
yxun authored Dec 4, 2024
1 parent bc6bc70 commit 3875a7c
Show file tree
Hide file tree
Showing 8 changed files with 12,032 additions and 0 deletions.
8 changes: 8 additions & 0 deletions PROJECT
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,12 @@ resources:
kind: IstioCNI
path: github.com/istio-ecosystem/sail-operator/api/v1alpha1
version: v1alpha1
- api:
crdVersion: v1
namespaced: false
controller: true
domain: sailoperator.io
kind: ZTunnel
path: github.com/istio-ecosystem/sail-operator/api/v1alpha1
version: v1alpha1
version: "3"
107 changes: 107 additions & 0 deletions api/v1alpha1/values_types_extra.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@

package v1alpha1

import (
k8sv1 "k8s.io/api/core/v1"
)

type SDSConfigToken struct {
Aud string `json:"aud,omitempty"`
}
Expand All @@ -25,3 +29,106 @@ type CNIValues struct {
// Part of the global configuration applicable to the Istio CNI component.
Global *CNIGlobalConfig `json:"global,omitempty"`
}

type ZTunnelValues struct {
// Configuration for the Istio ztunnel plugin.
ZTunnel *ZTunnelConfig `json:"ztunnel,omitempty"`

// Part of the global configuration applicable to the Istio ztunnel component.
Global *ZTunnelGlobalConfig `json:"global,omitempty"`
}

// Configuration for ztunnel.
type ZTunnelConfig struct {
// Hub to pull the container image from. Image will be `Hub/Image:Tag-Variant`.
Hub *string `json:"hub,omitempty"`
// The container image tag to pull. Image will be `Hub/Image:Tag-Variant`.
Tag *string `json:"tag,omitempty"`
// The container image variant to pull. Options are "debug" or "distroless". Unset will use the default for the given version.
Variant *string `json:"variant,omitempty"`
// Image name to pull from. Image will be `Hub/Image:Tag-Variant`.
// If Image contains a "/", it will replace the entire `image` in the pod.
Image *string `json:"image,omitempty"`
// Annotations to apply to all top level resources
Annotations map[string]string `json:"Annotations,omitempty"`
// Labels to apply to all top level resources
Labels map[string]string `json:"Labels,omitempty"`
// Additional volumeMounts to the ztunnel container
VolumeMounts []k8sv1.VolumeMount `json:"volumeMounts,omitempty"`
// Additional volumes to add to the ztunnel Pod.
Volumes []k8sv1.Volume `json:"volumes,omitempty"`
// Annotations added to each pod. The default annotations are required for scraping prometheus (in most environments).
PodAnnotations map[string]string `json:"podAnnotations,omitempty"`
// Additional labels to apply on the pod level.
PodLabels map[string]string `json:"podLabels,omitempty"`
// The k8s resource requests and limits for the ztunnel Pods.
Resources *k8sv1.ResourceRequirements `json:"resources,omitempty"`
// List of secret names to add to the service account as image pull secrets
// to use for pulling any images in pods that reference this ServiceAccount.
// Must be set for any cluster configured with private docker registry.
ImagePullSecrets []string `json:"imagePullSecrets,omitempty"`
// A `key: value` mapping of environment variables to add to the pod
Env map[string]string `json:"env,omitempty"`
// Specifies the image pull policy for the Istio images. one of Always, Never, IfNotPresent.
// Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated.
//
// More info: https://kubernetes.io/docs/concepts/containers/images#updating-images
// +kubebuilder:validation:Enum=Always;Never;IfNotPresent
ImagePullPolicy *k8sv1.PullPolicy `json:"imagePullPolicy,omitempty"`
// Settings for multicluster.
// The name of the cluster we are installing in. Note this is a user-defined name, which must be consistent
// with Istiod configuration.
MultiCluster *MultiClusterConfig `json:"multiCluster,omitempty"`
// meshConfig defines runtime configuration of components.
// For ztunnel, only defaultConfig is used, but this is nested under `meshConfig` for consistency with other components.
MeshConfig *MeshConfig `json:"meshConfig,omitempty"`
// Configures the revision this control plane is a part of
Revision *string `json:"revision,omitempty"`
// The address of the CA for CSR.
CaAddress *string `json:"caAddress,omitempty"`
// The customized XDS address to retrieve configuration.
XdsAddress *string `json:"xdsAddress,omitempty"`
// Specifies the default namespace for the Istio control plane components.
IstioNamespace *string `json:"istioNamespace,omitempty"`
// Same as `global.logging.level`, but will override it if set
Logging *GlobalLoggingConfig `json:"logging,omitempty"`
// Specifies whether istio components should output logs in json format by adding --log_as_json argument to each container.
LogAsJSON *bool `json:"logAsJSON,omitempty"`
}

// ZTunnelGlobalConfig is a subset of the Global Configuration used in the Istio ztunnel chart.
type ZTunnelGlobalConfig struct { // Default k8s resources settings for all Istio control plane components.
//
// See https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#resource-requests-and-limits-of-pod-and-container
//
// Deprecated: Marked as deprecated in pkg/apis/values_types.proto.
DefaultResources *k8sv1.ResourceRequirements `json:"defaultResources,omitempty"`

// Specifies the docker hub for Istio images.
Hub *string `json:"hub,omitempty"`
// Specifies the image pull policy for the Istio images. one of Always, Never, IfNotPresent.
// Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated.
//
// More info: https://kubernetes.io/docs/concepts/containers/images#updating-images
// +kubebuilder:validation:Enum=Always;Never;IfNotPresent
ImagePullPolicy *k8sv1.PullPolicy `json:"imagePullPolicy,omitempty"`
// ImagePullSecrets for the control plane ServiceAccount, list of secrets in the same namespace
// to use for pulling any images in pods that reference this ServiceAccount.
// Must be set for any cluster configured with private docker registry.
ImagePullSecrets []string `json:"imagePullSecrets,omitempty"`

// Specifies whether istio components should output logs in json format by adding --log_as_json argument to each container.
LogAsJSON *bool `json:"logAsJSON,omitempty"`
// Specifies the global logging level settings for the Istio control plane components.
Logging *GlobalLoggingConfig `json:"logging,omitempty"`

// Specifies the tag for the Istio docker images.
Tag *string `json:"tag,omitempty"`
// The variant of the Istio container images to use. Options are "debug" or "distroless". Unset will use the default for the given version.
Variant *string `json:"variant,omitempty"`

// Platform in which Istio is deployed. Possible values are: "openshift" and "gcp"
// An empty value means it is a vanilla Kubernetes distribution, therefore no special
// treatment will be considered.
Platform *string `json:"platform,omitempty"`
}
198 changes: 198 additions & 0 deletions api/v1alpha1/ztunnel_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
// Copyright Istio Authors
//
// 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 v1alpha1

import (
"time"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
ZTunnelKind = "ZTunnel"
)

// ZTunnelSpec defines the desired state of ZTunnel
type ZTunnelSpec struct {
// +sail:version
// Defines the version of Istio to install.
// Must be one of: v1.24.0 or latest.
// +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"}
// +kubebuilder:validation:Enum=v1.24.0;latest
// +kubebuilder:default=v1.24.0
Version string `json:"version"`

// +sail:profile
// The built-in installation configuration profile to use.
// The 'default' profile is 'ambient' and it is always applied.
// Must be one of: ambient, default, demo, empty, external, preview, remote, stable.
// +++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"}
// +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:hidden"}
// +kubebuilder:validation:Enum=ambient;default;demo;empty;external;openshift-ambient;openshift;preview;remote;stable
// +kubebuilder:default=ambient
Profile string `json:"profile,omitempty"`

// Namespace to which the Istio ztunnel component should be installed.
// +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:io.kubernetes:Namespace"}
// +kubebuilder:default=ztunnel
Namespace string `json:"namespace"`

// Defines the values to be passed to the Helm charts when installing Istio ztunnel.
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Helm Values"
Values *ZTunnelValues `json:"values,omitempty"`
}

// ZTunnelStatus defines the observed state of ZTunnel
type ZTunnelStatus struct {
// ObservedGeneration is the most recent generation observed for this
// ZTunnel object. It corresponds to the object's generation, which is
// updated on mutation by the API Server. The information in the status
// pertains to this particular generation of the object.
ObservedGeneration int64 `json:"observedGeneration,omitempty"`

// Represents the latest available observations of the object's current state.
Conditions []ZTunnelCondition `json:"conditions,omitempty"`

// Reports the current state of the object.
State ZTunnelConditionReason `json:"state,omitempty"`
}

// GetCondition returns the condition of the specified type
func (s *ZTunnelStatus) GetCondition(conditionType ZTunnelConditionType) ZTunnelCondition {
if s != nil {
for i := range s.Conditions {
if s.Conditions[i].Type == conditionType {
return s.Conditions[i]
}
}
}
return ZTunnelCondition{Type: conditionType, Status: metav1.ConditionUnknown}
}

// SetCondition sets a specific condition in the list of conditions
func (s *ZTunnelStatus) SetCondition(condition ZTunnelCondition) {
var now time.Time
if testTime == nil {
now = time.Now()
} else {
now = *testTime
}

// The lastTransitionTime only gets 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.
lastTransitionTime := metav1.NewTime(now.Truncate(time.Second))

for i, prevCondition := range s.Conditions {
if prevCondition.Type == condition.Type {
if prevCondition.Status != condition.Status {
condition.LastTransitionTime = lastTransitionTime
} else {
condition.LastTransitionTime = prevCondition.LastTransitionTime
}
s.Conditions[i] = condition
return
}
}

// If the condition does not exist, initialize the lastTransitionTime
condition.LastTransitionTime = lastTransitionTime
s.Conditions = append(s.Conditions, condition)
}

// ZTunnelCondition represents a specific observation of the ZTunnel object's state.
type ZTunnelCondition struct {
// The type of this condition.
Type ZTunnelConditionType `json:"type,omitempty"`

// The status of this condition. Can be True, False or Unknown.
Status metav1.ConditionStatus `json:"status,omitempty"`

// Unique, single-word, CamelCase reason for the condition's last transition.
Reason ZTunnelConditionReason `json:"reason,omitempty"`

// Human-readable message indicating details about the last transition.
Message string `json:"message,omitempty"`

// Last time the condition transitioned from one status to another.
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"`
}

// ZTunnelConditionType represents the type of the condition. Condition stages are:
// Installed, Reconciled, Ready
type ZTunnelConditionType string

// ZTunnelConditionReason represents a short message indicating how the condition came
// to be in its present state.
type ZTunnelConditionReason string

const (
// ZTunnelConditionReconciled signifies whether the controller has
// successfully reconciled the resources defined through the CR.
ZTunnelConditionReconciled ZTunnelConditionType = "Reconciled"

// ZTunnelReasonReconcileError indicates that the reconciliation of the resource has failed, but will be retried.
ZTunnelReasonReconcileError ZTunnelConditionReason = "ReconcileError"
)

const (
// ZTunnelConditionReady signifies whether the ztunnel DaemonSet is ready.
ZTunnelConditionReady ZTunnelConditionType = "Ready"

// ZTunnelDaemonSetNotReady indicates that the ztunnel DaemonSet is not ready.
ZTunnelDaemonSetNotReady ZTunnelConditionReason = "DaemonSetNotReady"

// ZTunnelReasonReadinessCheckFailed indicates that the DaemonSet readiness status could not be ascertained.
ZTunnelReasonReadinessCheckFailed ZTunnelConditionReason = "ReadinessCheckFailed"
)

const (
// ZTunnelReasonHealthy indicates that the control plane is fully reconciled and that all components are ready.
ZTunnelReasonHealthy ZTunnelConditionReason = "Healthy"
)

// +kubebuilder:object:root=true
// +kubebuilder:resource:scope=Cluster,categories=istio-io
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description="Whether the Istio ztunnel installation is ready to handle requests."
// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.state",description="The current state of this object."
// +kubebuilder:printcolumn:name="Version",type="string",JSONPath=".spec.version",description="The version of the Istio ztunnel installation."
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="The age of the object"
// +kubebuilder:validation:XValidation:rule="self.metadata.name == 'default'",message="metadata.name must be 'default'"

// ZTunnel represents a deployment of the Istio ztunnel component.
type ZTunnel struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

// +kubebuilder:default={version: "v1.24.0", namespace: "ztunnel", profile: "ambient"}
Spec ZTunnelSpec `json:"spec,omitempty"`

Status ZTunnelStatus `json:"status,omitempty"`
}

// +kubebuilder:object:root=true

// ZTunnelList contains a list of ZTunnel
type ZTunnelList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []ZTunnel `json:"items"`
}

func init() {
SchemeBuilder.Register(&ZTunnel{}, &ZTunnelList{})
}
Loading

0 comments on commit 3875a7c

Please sign in to comment.