Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend Istio CR with Egress Gateway #1178

Merged
merged 12 commits into from
Dec 18, 2024
3 changes: 3 additions & 0 deletions api/v1alpha2/conditions.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ var conditionReasons = map[ConditionReason]conditionMeta{

ConditionReasonIngressGatewayRestartSucceeded: {Type: ConditionTypeReady, Status: metav1.ConditionFalse, Message: ConditionReasonIngressGatewayRestartSucceededMessage},
ConditionReasonIngressGatewayRestartFailed: {Type: ConditionTypeReady, Status: metav1.ConditionFalse, Message: ConditionReasonIngressGatewayRestartFailedMessage},

ConditionReasonEgressGatewayRestartSucceeded: {Type: ConditionTypeReady, Status: metav1.ConditionFalse, Message: ConditionReasonEgressGatewayRestartSucceededMessage},
ConditionReasonEgressGatewayRestartFailed: {Type: ConditionTypeReady, Status: metav1.ConditionFalse, Message: ConditionReasonEgressGatewayRestartFailedMessage},
}

type conditionMeta struct {
Expand Down
26 changes: 25 additions & 1 deletion api/v1alpha2/istio_merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ func (i *Istio) mergeResources(op iopv1alpha1.IstioOperator) (iopv1alpha1.IstioO
if i.Spec.Components == nil {
return op, nil
}

if i.Spec.Components.IngressGateway != nil {
if op.Spec.Components == nil {
op.Spec.Components = &v1alpha1.IstioComponentSetSpec{}
Expand All @@ -226,15 +227,38 @@ func (i *Istio) mergeResources(op iopv1alpha1.IstioOperator) (iopv1alpha1.IstioO
if op.Spec.Components.IngressGateways[0].K8S == nil {
op.Spec.Components.IngressGateways[0].K8S = &v1alpha1.KubernetesResourcesSpec{}
}

if i.Spec.Components.IngressGateway.K8s != nil {
err := mergeK8sConfig(op.Spec.Components.IngressGateways[0].K8S, *i.Spec.Components.IngressGateway.K8s)
if err != nil {
return op, err
}
}
}

if i.Spec.Components.EgressGateway != nil {
if op.Spec.Components == nil {
op.Spec.Components = &v1alpha1.IstioComponentSetSpec{}
}
if len(op.Spec.Components.EgressGateways) == 0 {
op.Spec.Components.EgressGateways = append(op.Spec.Components.EgressGateways, &v1alpha1.GatewaySpec{})
}
if op.Spec.Components.EgressGateways[0].K8S == nil {
op.Spec.Components.EgressGateways[0].K8S = &v1alpha1.KubernetesResourcesSpec{}
}
if i.Spec.Components.EgressGateway.K8s != nil {
err := mergeK8sConfig(op.Spec.Components.EgressGateways[0].K8S, *i.Spec.Components.EgressGateway.K8s)
if err != nil {
return op, err
}
}
if i.Spec.Components.EgressGateway.Enabled != nil {
if op.Spec.Components.EgressGateways[0].Enabled == nil {
op.Spec.Components.EgressGateways[0].Enabled = &wrapperspb.BoolValue{}
}
op.Spec.Components.EgressGateways[0].Enabled.Value = *i.Spec.Components.EgressGateway.Enabled
}
}

if i.Spec.Components.Pilot != nil {
if op.Spec.Components == nil {
op.Spec.Components = &v1alpha1.IstioComponentSetSpec{}
Expand Down
10 changes: 10 additions & 0 deletions api/v1alpha2/istio_structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ type Components struct {
Cni *CniComponent `json:"cni,omitempty"`
// Proxy defines component configuration for Istio proxy sidecar
Proxy *ProxyComponent `json:"proxy,omitempty"`
// +kubebuilder:validation:Optional
EgressGateway *EgressGateway `json:"egressGateway,omitempty"`
}

// KubernetesResourcesConfig is a subset of https://istio.io/latest/docs/reference/config/istio.operator.v1alpha1/#KubernetesResourcesSpec
Expand Down Expand Up @@ -112,3 +114,11 @@ type ResourceClaims struct {
// +kubebuilder:validation:Pattern=`^[0-9]+(((\.[0-9]+)?(E|P|T|G|M|k|Ei|Pi|Ti|Gi|Mi|Ki|m)?)|(e[0-9]+))$`
Memory *string `json:"memory,omitempty"`
}

// EgressGateway defines configuration for Istio egressGateway
type EgressGateway struct {
// +kubebuilder:validation:Optional
K8s *KubernetesResourcesConfig `json:"k8s"`
// +kubebuilder:validation:Optional
Enabled *bool `json:"enabled,omitempty"`
}
6 changes: 6 additions & 0 deletions api/v1alpha2/istio_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ const (
ConditionReasonIngressGatewayRestartSucceededMessage = "Istio Ingress Gateway restart succeeded"
ConditionReasonIngressGatewayRestartFailed ConditionReason = "IngressGatewayRestartFailed"
ConditionReasonIngressGatewayRestartFailedMessage = "Istio Ingress Gateway restart failed"

// egress gateway
ConditionReasonEgressGatewayRestartSucceeded ConditionReason = "EgressGatewayRestartSucceeded"
ConditionReasonEgressGatewayRestartSucceededMessage = "Istio Egress Gateway restart succeeded"
ConditionReasonEgressGatewayRestartFailed ConditionReason = "EgressGatewayRestartFailed"
ConditionReasonEgressGatewayRestartFailedMessage = "Istio Egress Gateway restart failed"
)

type ReasonWithMessage struct {
Expand Down
79 changes: 79 additions & 0 deletions api/v1alpha2/merge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,85 @@ var _ = Describe("Merge", func() {
})
})

Context("EgressGateway", func() {
Context("When Istio CR has 500m configured for CPU and 500Mi for memory limits", func() {
It("should set CPU limits to 500m and 500Mi for memory in IOP", func() {
//given
iop := iopv1alpha1.IstioOperator{
Spec: &operatorv1alpha1.IstioOperatorSpec{},
}
cpuLimit := "500m"
memoryLimit := "500Mi"
enabled := true

istioCR := Istio{Spec: IstioSpec{Components: &Components{
EgressGateway: &EgressGateway{
Enabled: &enabled,
K8s: &KubernetesResourcesConfig{
Resources: &Resources{
Limits: &ResourceClaims{
Cpu: &cpuLimit,
Memory: &memoryLimit,
},
},
},
}}}}

// when
out, err := istioCR.MergeInto(iop)

// then
Expect(err).ShouldNot(HaveOccurred())

iopCpuLimit := out.Spec.Components.EgressGateways[0].K8S.Resources.Limits["cpu"]
Expect(iopCpuLimit).To(Equal(cpuLimit))

iopMemoryLimit := out.Spec.Components.EgressGateways[0].K8S.Resources.Limits["memory"]
Expect(iopMemoryLimit).To(Equal(iopMemoryLimit))
werdes72 marked this conversation as resolved.
Show resolved Hide resolved
})
werdes72 marked this conversation as resolved.
Show resolved Hide resolved
})

Context("When Istio CR has 500m configured for CPU and 500Mi for memory requests", func() {
It("should set CPU requests to 500m and 500Mi for memory in IOP", func() {
//given
iop := iopv1alpha1.IstioOperator{
Spec: &operatorv1alpha1.IstioOperatorSpec{},
}
cpuRequests := "500m"
memoryRequests := "500Mi"
enabled := true

istioCR := Istio{Spec: IstioSpec{Components: &Components{
EgressGateway: &EgressGateway{
Enabled: &enabled,
K8s: &KubernetesResourcesConfig{
Resources: &Resources{
Requests: &ResourceClaims{
Cpu: &cpuRequests,
Memory: &memoryRequests,
},
},
},
}}}}

// when
out, err := istioCR.MergeInto(iop)

// then
Expect(err).ShouldNot(HaveOccurred())

iopCpuRequests := out.Spec.Components.EgressGateways[0].K8S.Resources.Requests["cpu"]
Expect(iopCpuRequests).To(Equal(cpuRequests))

iopMemoryRequests := out.Spec.Components.EgressGateways[0].K8S.Resources.Requests["memory"]
Expect(iopMemoryRequests).To(Equal(memoryRequests))

iopEnabled := out.Spec.Components.EgressGateways[0].Enabled.GetValue()
Expect(iopEnabled).To(Equal(enabled))
})
})
})

Context("Strategy", func() {
It("should update RollingUpdate when it is present in Istio CR", func() {
//given
Expand Down
30 changes: 30 additions & 0 deletions api/v1alpha2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

80 changes: 80 additions & 0 deletions config/crd/bases/operator.kyma-project.io_istios.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1022,6 +1022,86 @@ spec:
required:
- k8s
type: object
egressGateway:
description: EgressGateway defines configuration for Istio egressGateway
properties:
enabled:
type: boolean
k8s:
description: KubernetesResourcesConfig is a subset of https://istio.io/latest/docs/reference/config/istio.operator.v1alpha1/#KubernetesResourcesSpec
properties:
hpaSpec:
description: HPASpec defines configuration for HorizontalPodAutoscaler
properties:
maxReplicas:
format: int32
maximum: 2147483647
minimum: 0
type: integer
minReplicas:
format: int32
maximum: 2147483647
minimum: 0
type: integer
type: object
resources:
description: 'Resources define Kubernetes resources configuration:
https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
properties:
limits:
properties:
cpu:
pattern: ^([0-9]+m?|[0-9]\.[0-9]{1,3})$
type: string
memory:
pattern: ^[0-9]+(((\.[0-9]+)?(E|P|T|G|M|k|Ei|Pi|Ti|Gi|Mi|Ki|m)?)|(e[0-9]+))$
type: string
type: object
requests:
properties:
cpu:
pattern: ^([0-9]+m?|[0-9]\.[0-9]{1,3})$
type: string
memory:
pattern: ^[0-9]+(((\.[0-9]+)?(E|P|T|G|M|k|Ei|Pi|Ti|Gi|Mi|Ki|m)?)|(e[0-9]+))$
type: string
type: object
type: object
strategy:
description: Strategy defines rolling update strategy
properties:
rollingUpdate:
description: 'RollingUpdate defines configuration
for rolling updates: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#rolling-update-deployment'
properties:
maxSurge:
anyOf:
- type: integer
- type: string
pattern: ^[0-9]+%?$
x-kubernetes-int-or-string: true
x-kubernetes-validations:
- message: must not be negative, more than 2147483647
or an empty string
rule: '(type(self) == int ? self >= 0 && self
<= 2147483647: self.size() >= 0)'
maxUnavailable:
anyOf:
- type: integer
- type: string
pattern: ^((100|[0-9]{1,2})%|[0-9]+)$
x-kubernetes-int-or-string: true
x-kubernetes-validations:
- message: must not be negative, more than 2147483647
or an empty string
rule: '(type(self) == int ? self >= 0 && self
<= 2147483647: self.size() >= 0)'
type: object
required:
- rollingUpdate
type: object
type: object
type: object
ingressGateway:
description: IngressGateway defines component configurations for
Istio Ingress Gateway
Expand Down
1 change: 1 addition & 0 deletions controllers/istio_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ func NewController(mgr manager.Manager, reconciliationInterval time.Duration) *I
statusHandler := status.NewStatusHandler(mgr.GetClient())
restarters := []restarter.Restarter{
restarter.NewIngressGatewayRestarter(mgr.GetClient(), []filter.IngressGatewayPredicate{}, statusHandler),
restarter.NewEgressGatewayRestarter(mgr.GetClient(), []filter.EgressGatewayPredicate{}, statusHandler),
restarter.NewSidecarsRestarter(mgr.GetLogger(), mgr.GetClient(), &merger, sidecars.NewProxyResetter(), statusHandler),
}

Expand Down
Loading
Loading