Unverified Commit 15462b74 authored by julienmancuso's avatar julienmancuso Committed by GitHub
Browse files

feat: make ingress configurable in operator (#717)

parent e6399307
...@@ -22,6 +22,8 @@ dynamo-operator: ...@@ -22,6 +22,8 @@ dynamo-operator:
enabled: true enabled: true
natsAddr: "nats://${RELEASE_NAME}-nats:4222" natsAddr: "nats://${RELEASE_NAME}-nats:4222"
etcdAddr: "${RELEASE_NAME}-etcd:2379" etcdAddr: "${RELEASE_NAME}-etcd:2379"
istioVirtualServiceEnabled: false
ingressControllerClassName: ""
namespaceRestriction: namespaceRestriction:
enabled: true enabled: true
targetNamespace: ${NAMESPACE} targetNamespace: ${NAMESPACE}
......
...@@ -23,7 +23,7 @@ version: 25.2.0-rc3 ...@@ -23,7 +23,7 @@ version: 25.2.0-rc3
home: https://nvidia.com home: https://nvidia.com
dependencies: dependencies:
- name: dynamo-operator - name: dynamo-operator
version: 0.1.2 version: 0.1.3
repository: file://components/operator repository: file://components/operator
condition: dynamo-operator.enabled condition: dynamo-operator.enabled
- name: dynamo-api-store - name: dynamo-api-store
......
...@@ -27,7 +27,7 @@ type: application ...@@ -27,7 +27,7 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes # This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version. # to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/) # Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.2 version: 0.1.3
# This is the version number of the application being deployed. This version number should be # This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to # incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using. # follow Semantic Versioning. They should reflect the version the application is using.
......
...@@ -72,6 +72,12 @@ spec: ...@@ -72,6 +72,12 @@ spec:
{{- if .Values.etcdAddr }} {{- if .Values.etcdAddr }}
- --etcdAddr={{ .Values.etcdAddr }} - --etcdAddr={{ .Values.etcdAddr }}
{{- end }} {{- end }}
{{- if .Values.istioVirtualServiceEnabled }}
- --istio-virtual-service-enabled
{{- end }}
{{- if .Values.ingressControllerClassName }}
- --ingress-controller-class-name={{ .Values.ingressControllerClassName }}
{{- end }}
command: command:
- /manager - /manager
env: env:
......
...@@ -277,6 +277,7 @@ rules: ...@@ -277,6 +277,7 @@ rules:
- patch - patch
- update - update
- watch - watch
{{- if .Values.istioVirtualServiceEnabled }}
- apiGroups: - apiGroups:
- networking.istio.io - networking.istio.io
resources: resources:
...@@ -289,6 +290,7 @@ rules: ...@@ -289,6 +290,7 @@ rules:
- patch - patch
- update - update
- watch - watch
{{- end }}
- apiGroups: - apiGroups:
- networking.k8s.io - networking.k8s.io
resources: resources:
......
...@@ -70,6 +70,8 @@ func main() { ...@@ -70,6 +70,8 @@ func main() {
var leaderElectionID string var leaderElectionID string
var natsAddr string var natsAddr string
var etcdAddr string var etcdAddr string
var istioVirtualServiceEnabled bool
var ingressControllerClassName string
flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
flag.BoolVar(&enableLeaderElection, "leader-elect", false, flag.BoolVar(&enableLeaderElection, "leader-elect", false,
...@@ -85,6 +87,10 @@ func main() { ...@@ -85,6 +87,10 @@ func main() {
"Id to use for the leader election.") "Id to use for the leader election.")
flag.StringVar(&natsAddr, "natsAddr", "", "address of the NATS server") flag.StringVar(&natsAddr, "natsAddr", "", "address of the NATS server")
flag.StringVar(&etcdAddr, "etcdAddr", "", "address of the etcd server") flag.StringVar(&etcdAddr, "etcdAddr", "", "address of the etcd server")
flag.BoolVar(&istioVirtualServiceEnabled, "istio-virtual-service-enabled", false,
"If set, the istio virtual service will be enabled for the ingress")
flag.StringVar(&ingressControllerClassName, "ingress-controller-class-name", "",
"The name of the ingress controller class to use")
opts := zap.Options{ opts := zap.Options{
Development: true, Development: true,
} }
...@@ -165,13 +171,15 @@ func main() { ...@@ -165,13 +171,15 @@ func main() {
os.Exit(1) os.Exit(1)
} }
if err = (&controller.DynamoNimDeploymentReconciler{ if err = (&controller.DynamoNimDeploymentReconciler{
Client: mgr.GetClient(), Client: mgr.GetClient(),
Scheme: mgr.GetScheme(), Scheme: mgr.GetScheme(),
Recorder: mgr.GetEventRecorderFor("yatai-deployment"), Recorder: mgr.GetEventRecorderFor("yatai-deployment"),
Config: ctrlConfig, Config: ctrlConfig,
NatsAddr: natsAddr, NatsAddr: natsAddr,
EtcdAddr: etcdAddr, EtcdAddr: etcdAddr,
EtcdStorage: etcd.NewStorage(cli), EtcdStorage: etcd.NewStorage(cli),
IstioVirtualServiceEnabled: istioVirtualServiceEnabled,
IngressControllerClassName: ingressControllerClassName,
}).SetupWithManager(mgr); err != nil { }).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "DynamoNimDeployment") setupLog.Error(err, "unable to create controller", "controller", "DynamoNimDeployment")
os.Exit(1) os.Exit(1)
......
...@@ -8,6 +8,7 @@ require ( ...@@ -8,6 +8,7 @@ require (
dario.cat/mergo v1.0.1 dario.cat/mergo v1.0.1
emperror.dev/errors v0.8.1 emperror.dev/errors v0.8.1
github.com/apparentlymart/go-shquot v0.0.1 github.com/apparentlymart/go-shquot v0.0.1
github.com/bsm/gomega v1.27.10
github.com/cisco-open/k8s-objectmatcher v1.9.0 github.com/cisco-open/k8s-objectmatcher v1.9.0
github.com/ettle/strcase v0.2.0 github.com/ettle/strcase v0.2.0
github.com/huandu/xstrings v1.4.0 github.com/huandu/xstrings v1.4.0
......
...@@ -6,6 +6,8 @@ github.com/apparentlymart/go-shquot v0.0.1 h1:MGV8lwxF4zw75lN7e0MGs7o6AFYn7L6AZa ...@@ -6,6 +6,8 @@ github.com/apparentlymart/go-shquot v0.0.1 h1:MGV8lwxF4zw75lN7e0MGs7o6AFYn7L6AZa
github.com/apparentlymart/go-shquot v0.0.1/go.mod h1:lw58XsE5IgUXZ9h0cxnypdx31p9mPFIVEQ9P3c7MlrU= github.com/apparentlymart/go-shquot v0.0.1/go.mod h1:lw58XsE5IgUXZ9h0cxnypdx31p9mPFIVEQ9P3c7MlrU=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cisco-open/k8s-objectmatcher v1.9.0 h1:/sfuO0BD09fpynZjXsqeZrh28Juc4VEwc2P6Ov/Q6fM= github.com/cisco-open/k8s-objectmatcher v1.9.0 h1:/sfuO0BD09fpynZjXsqeZrh28Juc4VEwc2P6Ov/Q6fM=
......
...@@ -85,7 +85,7 @@ const ( ...@@ -85,7 +85,7 @@ const (
ContainerPortNameHTTPProxy = "http-proxy" ContainerPortNameHTTPProxy = "http-proxy"
ServicePortNameHTTPNonProxy = "http-non-proxy" ServicePortNameHTTPNonProxy = "http-non-proxy"
HeaderNameDebug = "X-Yatai-Debug" HeaderNameDebug = "X-Yatai-Debug"
kDefaultIngressSuffix = "local" DefaultIngressSuffix = "local"
) )
var ServicePortHTTPNonProxy = commonconsts.BentoServicePort + 1 var ServicePortHTTPNonProxy = commonconsts.BentoServicePort + 1
...@@ -93,12 +93,14 @@ var ServicePortHTTPNonProxy = commonconsts.BentoServicePort + 1 ...@@ -93,12 +93,14 @@ var ServicePortHTTPNonProxy = commonconsts.BentoServicePort + 1
// DynamoNimDeploymentReconciler reconciles a DynamoNimDeployment object // DynamoNimDeploymentReconciler reconciles a DynamoNimDeployment object
type DynamoNimDeploymentReconciler struct { type DynamoNimDeploymentReconciler struct {
client.Client client.Client
Scheme *runtime.Scheme Scheme *runtime.Scheme
Recorder record.EventRecorder Recorder record.EventRecorder
Config controller_common.Config Config controller_common.Config
NatsAddr string NatsAddr string
EtcdAddr string EtcdAddr string
EtcdStorage etcdStorage EtcdStorage etcdStorage
IngressControllerClassName string
IstioVirtualServiceEnabled bool
} }
// +kubebuilder:rbac:groups=nvidia.com,resources=dynamonimdeployments,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=nvidia.com,resources=dynamonimdeployments,verbs=get;list;watch;create;update;patch;delete
...@@ -380,10 +382,10 @@ func (r *DynamoNimDeploymentReconciler) Reconcile(ctx context.Context, req ctrl. ...@@ -380,10 +382,10 @@ func (r *DynamoNimDeploymentReconciler) Reconcile(ctx context.Context, req ctrl.
} }
// create or update api-server ingresses // create or update api-server ingresses
modified_, _, err = createOrUpdateResource(ctx, r, generateResourceOption{ modified_, err = r.createOrUpdateOrDeleteIngress(ctx, generateResourceOption{
dynamoNimDeployment: dynamoNimDeployment, dynamoNimDeployment: dynamoNimDeployment,
dynamoNim: dynamoNimCR, dynamoNim: dynamoNimCR,
}, r.generateVirtualService) })
if err != nil { if err != nil {
return return
} }
...@@ -635,6 +637,13 @@ func createOrUpdateResource[T client.Object](ctx context.Context, r *DynamoNimDe ...@@ -635,6 +637,13 @@ func createOrUpdateResource[T client.Object](ctx context.Context, r *DynamoNimDe
return return
} }
err = ctrl.SetControllerReference(opt.dynamoNimDeployment, resource, r.Scheme)
if err != nil {
logs.Error(err, "Failed to set controller reference.")
r.Recorder.Eventf(opt.dynamoNimDeployment, corev1.EventTypeWarning, "SetControllerReference", "Failed to set controller reference for %s %s: %s", resourceType, resourceNamespace, err)
return
}
r.Recorder.Eventf(opt.dynamoNimDeployment, corev1.EventTypeNormal, fmt.Sprintf("Create%s", resourceType), "Creating a new %s %s", resourceType, resourceNamespace) r.Recorder.Eventf(opt.dynamoNimDeployment, corev1.EventTypeNormal, fmt.Sprintf("Create%s", resourceType), "Creating a new %s %s", resourceType, resourceNamespace)
err = r.Create(ctx, resource) err = r.Create(ctx, resource)
if err != nil { if err != nil {
...@@ -785,18 +794,69 @@ func (r *DynamoNimDeploymentReconciler) createOrUpdateOrDeleteServices(ctx conte ...@@ -785,18 +794,69 @@ func (r *DynamoNimDeploymentReconciler) createOrUpdateOrDeleteServices(ctx conte
return return
} }
func (r *DynamoNimDeploymentReconciler) generateVirtualService(ctx context.Context, opt generateResourceOption) (*networkingv1beta1.VirtualService, bool, error) { func (r *DynamoNimDeploymentReconciler) createOrUpdateOrDeleteIngress(ctx context.Context, opt generateResourceOption) (modified bool, err error) {
modified, _, err = createOrUpdateResource(ctx, r, opt, r.generateIngress)
if err != nil {
return
}
modified_, _, err := createOrUpdateResource(ctx, r, opt, r.generateVirtualService)
if err != nil {
return
}
modified = modified || modified_
return
}
func (r *DynamoNimDeploymentReconciler) generateIngress(ctx context.Context, opt generateResourceOption) (*networkingv1.Ingress, bool, error) {
log := log.FromContext(ctx) log := log.FromContext(ctx)
log.Info("Starting generateVirtualService") log.Info("Starting generateIngress")
ingress := &networkingv1.Ingress{
ObjectMeta: metav1.ObjectMeta{
Name: opt.dynamoNimDeployment.Name,
Namespace: opt.dynamoNimDeployment.Namespace,
},
}
vsName := opt.dynamoNimDeployment.Name if !opt.dynamoNimDeployment.Spec.Ingress.Enabled || r.IngressControllerClassName == "" {
if opt.dynamoNimDeployment.Spec.Ingress.HostPrefix != nil { log.Info("Ingress is not enabled")
vsName = *opt.dynamoNimDeployment.Spec.Ingress.HostPrefix + vsName return ingress, true, nil
} }
ingressSuffix, found := os.LookupEnv("DYNAMO_INGRESS_SUFFIX")
if !found || ingressSuffix == "" { ingress.Spec = networkingv1.IngressSpec{
ingressSuffix = kDefaultIngressSuffix IngressClassName: &r.IngressControllerClassName,
Rules: []networkingv1.IngressRule{
{
Host: getIngressHost(opt.dynamoNimDeployment),
IngressRuleValue: networkingv1.IngressRuleValue{
HTTP: &networkingv1.HTTPIngressRuleValue{
Paths: []networkingv1.HTTPIngressPath{
{
Path: "/",
PathType: &[]networkingv1.PathType{networkingv1.PathTypePrefix}[0],
Backend: networkingv1.IngressBackend{
Service: &networkingv1.IngressServiceBackend{
Name: opt.dynamoNimDeployment.Name,
Port: networkingv1.ServiceBackendPort{
Number: 3000,
},
},
},
},
},
},
},
},
},
} }
return ingress, false, nil
}
func (r *DynamoNimDeploymentReconciler) generateVirtualService(ctx context.Context, opt generateResourceOption) (*networkingv1beta1.VirtualService, bool, error) {
log := log.FromContext(ctx)
log.Info("Starting generateVirtualService")
vs := &networkingv1beta1.VirtualService{ vs := &networkingv1beta1.VirtualService{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: opt.dynamoNimDeployment.Name, Name: opt.dynamoNimDeployment.Name,
...@@ -804,7 +864,7 @@ func (r *DynamoNimDeploymentReconciler) generateVirtualService(ctx context.Conte ...@@ -804,7 +864,7 @@ func (r *DynamoNimDeploymentReconciler) generateVirtualService(ctx context.Conte
}, },
} }
vsEnabled := opt.dynamoNimDeployment.Spec.Ingress.Enabled && opt.dynamoNimDeployment.Spec.Ingress.UseVirtualService != nil && *opt.dynamoNimDeployment.Spec.Ingress.UseVirtualService vsEnabled := opt.dynamoNimDeployment.Spec.Ingress.Enabled && r.IstioVirtualServiceEnabled
if !vsEnabled { if !vsEnabled {
log.Info("VirtualService is not enabled") log.Info("VirtualService is not enabled")
return vs, true, nil return vs, true, nil
...@@ -812,7 +872,7 @@ func (r *DynamoNimDeploymentReconciler) generateVirtualService(ctx context.Conte ...@@ -812,7 +872,7 @@ func (r *DynamoNimDeploymentReconciler) generateVirtualService(ctx context.Conte
vs.Spec = istioNetworking.VirtualService{ vs.Spec = istioNetworking.VirtualService{
Hosts: []string{ Hosts: []string{
fmt.Sprintf("%s.%s", vsName, ingressSuffix), getIngressHost(opt.dynamoNimDeployment),
}, },
Gateways: []string{"istio-system/ingress-alb"}, Gateways: []string{"istio-system/ingress-alb"},
Http: []*istioNetworking.HTTPRoute{ Http: []*istioNetworking.HTTPRoute{
...@@ -986,11 +1046,6 @@ func (r *DynamoNimDeploymentReconciler) generateDeployment(ctx context.Context, ...@@ -986,11 +1046,6 @@ func (r *DynamoNimDeploymentReconciler) generateDeployment(ctx context.Context,
Strategy: strategy, Strategy: strategy,
} }
err = ctrl.SetControllerReference(opt.dynamoNimDeployment, kubeDeployment, r.Scheme)
if err != nil {
err = errors.Wrapf(err, "set deployment %s controller reference", kubeDeployment.Name)
}
return return
} }
...@@ -1003,6 +1058,18 @@ type generateResourceOption struct { ...@@ -1003,6 +1058,18 @@ type generateResourceOption struct {
isGenericService bool isGenericService bool
} }
func getIngressHost(dynamoNimDeployment *v1alpha1.DynamoNimDeployment) string {
vsName := dynamoNimDeployment.Name
if dynamoNimDeployment.Spec.Ingress.HostPrefix != nil {
vsName = *dynamoNimDeployment.Spec.Ingress.HostPrefix + vsName
}
ingressSuffix, found := os.LookupEnv("DYNAMO_INGRESS_SUFFIX")
if !found || ingressSuffix == "" {
ingressSuffix = DefaultIngressSuffix
}
return fmt.Sprintf("%s.%s", vsName, ingressSuffix)
}
func (r *DynamoNimDeploymentReconciler) generateHPA(ctx context.Context, opt generateResourceOption) (*autoscalingv2.HorizontalPodAutoscaler, bool, error) { func (r *DynamoNimDeploymentReconciler) generateHPA(ctx context.Context, opt generateResourceOption) (*autoscalingv2.HorizontalPodAutoscaler, bool, error) {
labels := r.getKubeLabels(opt.dynamoNimDeployment, opt.dynamoNim) labels := r.getKubeLabels(opt.dynamoNimDeployment, opt.dynamoNim)
...@@ -1057,12 +1124,7 @@ func (r *DynamoNimDeploymentReconciler) generateHPA(ctx context.Context, opt gen ...@@ -1057,12 +1124,7 @@ func (r *DynamoNimDeploymentReconciler) generateHPA(ctx context.Context, opt gen
} }
} }
err := ctrl.SetControllerReference(opt.dynamoNimDeployment, kubeHpa, r.Scheme) return kubeHpa, false, nil
if err != nil {
return nil, false, errors.Wrapf(err, "set hpa %s controller reference", kubeName)
}
return kubeHpa, false, err
} }
func getDynamoNimRepositoryNameAndDynamoNimVersion(dynamoNim *v1alpha1.DynamoNim) (repositoryName string, version string) { func getDynamoNimRepositoryNameAndDynamoNimVersion(dynamoNim *v1alpha1.DynamoNim) (repositoryName string, version string) {
...@@ -2001,12 +2063,6 @@ func (r *DynamoNimDeploymentReconciler) generateService(ctx context.Context, opt ...@@ -2001,12 +2063,6 @@ func (r *DynamoNimDeploymentReconciler) generateService(ctx context.Context, opt
kubeService.ObjectMeta.Labels = labels kubeService.ObjectMeta.Labels = labels
kubeService.Spec = spec kubeService.Spec = spec
err = ctrl.SetControllerReference(opt.dynamoNimDeployment, kubeService, r.Scheme)
if err != nil {
err = errors.Wrapf(err, "set controller reference for service %s", kubeService.Name)
return
}
return return
} }
...@@ -2040,7 +2096,6 @@ func (r *DynamoNimDeploymentReconciler) SetupWithManager(mgr ctrl.Manager) error ...@@ -2040,7 +2096,6 @@ func (r *DynamoNimDeploymentReconciler) SetupWithManager(mgr ctrl.Manager) error
GenericFunc: func(ge event.GenericEvent) bool { return true }, GenericFunc: func(ge event.GenericEvent) bool { return true },
})). })).
Owns(&corev1.Service{}, builder.WithPredicates(predicate.GenerationChangedPredicate{})). Owns(&corev1.Service{}, builder.WithPredicates(predicate.GenerationChangedPredicate{})).
Owns(&networkingv1beta1.VirtualService{}, builder.WithPredicates(predicate.GenerationChangedPredicate{})).
Owns(&networkingv1.Ingress{}, builder.WithPredicates(predicate.GenerationChangedPredicate{})). Owns(&networkingv1.Ingress{}, builder.WithPredicates(predicate.GenerationChangedPredicate{})).
Owns(&corev1.PersistentVolumeClaim{}, builder.WithPredicates(predicate.GenerationChangedPredicate{})). Owns(&corev1.PersistentVolumeClaim{}, builder.WithPredicates(predicate.GenerationChangedPredicate{})).
Watches(&v1alpha1.DynamoNimRequest{}, handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, dynamoNimRequest client.Object) []reconcile.Request { Watches(&v1alpha1.DynamoNimRequest{}, handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, dynamoNimRequest client.Object) []reconcile.Request {
...@@ -2106,6 +2161,9 @@ func (r *DynamoNimDeploymentReconciler) SetupWithManager(mgr ctrl.Manager) error ...@@ -2106,6 +2161,9 @@ func (r *DynamoNimDeploymentReconciler) SetupWithManager(mgr ctrl.Manager) error
return reqs return reqs
})) }))
if r.IstioVirtualServiceEnabled {
m.Owns(&networkingv1beta1.VirtualService{}, builder.WithPredicates(predicate.GenerationChangedPredicate{}))
}
m.Owns(&autoscalingv2.HorizontalPodAutoscaler{}) m.Owns(&autoscalingv2.HorizontalPodAutoscaler{})
return m.Complete(r) return m.Complete(r)
} }
...@@ -25,8 +25,12 @@ import ( ...@@ -25,8 +25,12 @@ import (
"testing" "testing"
"github.com/ai-dynamo/dynamo/deploy/dynamo/operator/api/v1alpha1" "github.com/ai-dynamo/dynamo/deploy/dynamo/operator/api/v1alpha1"
"github.com/bsm/gomega"
istioNetworking "istio.io/api/networking/v1beta1"
networkingv1beta1 "istio.io/client-go/pkg/apis/networking/v1beta1"
appsv1 "k8s.io/api/apps/v1" appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
) )
...@@ -229,3 +233,264 @@ func TestDynamoNimDeploymentReconciler_FinalizeResource(t *testing.T) { ...@@ -229,3 +233,264 @@ func TestDynamoNimDeploymentReconciler_FinalizeResource(t *testing.T) {
}) })
} }
} }
func TestDynamoNimDeploymentReconciler_generateIngress(t *testing.T) {
type fields struct {
IngressControllerClassName string
IstioVirtualServiceEnabled bool
}
type args struct {
ctx context.Context
opt generateResourceOption
}
tests := []struct {
name string
fields fields
args args
want *networkingv1.Ingress
want1 bool
wantErr bool
}{
{
name: "generate ingress",
fields: fields{
IngressControllerClassName: "nginx",
IstioVirtualServiceEnabled: false,
},
args: args{
ctx: context.Background(),
opt: generateResourceOption{
dynamoNimDeployment: &v1alpha1.DynamoNimDeployment{
ObjectMeta: metav1.ObjectMeta{
Name: "service1",
Namespace: "default",
},
Spec: v1alpha1.DynamoNimDeploymentSpec{
DynamoNimDeploymentSharedSpec: v1alpha1.DynamoNimDeploymentSharedSpec{
ServiceName: "service1",
DynamoNamespace: &[]string{"default"}[0],
Ingress: v1alpha1.IngressSpec{
Enabled: true,
},
},
},
},
},
},
want: &networkingv1.Ingress{
ObjectMeta: metav1.ObjectMeta{
Name: "service1",
Namespace: "default",
},
Spec: networkingv1.IngressSpec{
IngressClassName: &[]string{"nginx"}[0],
Rules: []networkingv1.IngressRule{
{
Host: "service1.local",
IngressRuleValue: networkingv1.IngressRuleValue{
HTTP: &networkingv1.HTTPIngressRuleValue{
Paths: []networkingv1.HTTPIngressPath{
{
Path: "/",
PathType: &[]networkingv1.PathType{networkingv1.PathTypePrefix}[0],
Backend: networkingv1.IngressBackend{
Service: &networkingv1.IngressServiceBackend{
Name: "service1",
Port: networkingv1.ServiceBackendPort{Number: 3000},
},
},
},
},
},
},
},
},
},
},
want1: false,
wantErr: false,
},
{
name: "generate ingress, disabled",
fields: fields{
IngressControllerClassName: "nginx",
IstioVirtualServiceEnabled: false,
},
args: args{
ctx: context.Background(),
opt: generateResourceOption{
dynamoNimDeployment: &v1alpha1.DynamoNimDeployment{
ObjectMeta: metav1.ObjectMeta{
Name: "service1",
Namespace: "default",
},
Spec: v1alpha1.DynamoNimDeploymentSpec{
DynamoNimDeploymentSharedSpec: v1alpha1.DynamoNimDeploymentSharedSpec{
ServiceName: "service1",
DynamoNamespace: &[]string{"default"}[0],
Ingress: v1alpha1.IngressSpec{
Enabled: false,
},
},
},
},
},
},
want: &networkingv1.Ingress{
ObjectMeta: metav1.ObjectMeta{
Name: "service1",
Namespace: "default",
},
},
want1: true,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
g := gomega.NewGomegaWithT(t)
r := &DynamoNimDeploymentReconciler{
IngressControllerClassName: tt.fields.IngressControllerClassName,
IstioVirtualServiceEnabled: tt.fields.IstioVirtualServiceEnabled,
}
got, got1, err := r.generateIngress(tt.args.ctx, tt.args.opt)
if (err != nil) != tt.wantErr {
t.Errorf("DynamoNimDeploymentReconciler.generateIngress() error = %v, wantErr %v", err, tt.wantErr)
return
}
g.Expect(got).To(gomega.Equal(tt.want))
g.Expect(got1).To(gomega.Equal(tt.want1))
})
}
}
func TestDynamoNimDeploymentReconciler_generateVirtualService(t *testing.T) {
type fields struct {
IngressControllerClassName string
IstioVirtualServiceEnabled bool
}
type args struct {
ctx context.Context
opt generateResourceOption
}
tests := []struct {
name string
fields fields
args args
want *networkingv1beta1.VirtualService
want1 bool
wantErr bool
}{
{
name: "generate virtual service, disabled in operator config",
fields: fields{
IngressControllerClassName: "",
IstioVirtualServiceEnabled: false,
},
args: args{
ctx: context.Background(),
opt: generateResourceOption{
dynamoNimDeployment: &v1alpha1.DynamoNimDeployment{
ObjectMeta: metav1.ObjectMeta{
Name: "service1",
Namespace: "default",
},
Spec: v1alpha1.DynamoNimDeploymentSpec{
DynamoNimDeploymentSharedSpec: v1alpha1.DynamoNimDeploymentSharedSpec{
ServiceName: "service1",
DynamoNamespace: &[]string{"default"}[0],
Ingress: v1alpha1.IngressSpec{
Enabled: true,
},
},
},
},
},
},
want: &networkingv1beta1.VirtualService{
ObjectMeta: metav1.ObjectMeta{
Name: "service1",
Namespace: "default",
},
},
want1: true,
wantErr: false,
},
{
name: "generate virtual service, enabled in operator config",
fields: fields{
IngressControllerClassName: "",
IstioVirtualServiceEnabled: true,
},
args: args{
ctx: context.Background(),
opt: generateResourceOption{
dynamoNimDeployment: &v1alpha1.DynamoNimDeployment{
ObjectMeta: metav1.ObjectMeta{
Name: "service1",
Namespace: "default",
},
Spec: v1alpha1.DynamoNimDeploymentSpec{
DynamoNimDeploymentSharedSpec: v1alpha1.DynamoNimDeploymentSharedSpec{
ServiceName: "service1",
DynamoNamespace: &[]string{"default"}[0],
Ingress: v1alpha1.IngressSpec{
Enabled: true,
},
},
},
},
},
},
want: &networkingv1beta1.VirtualService{
ObjectMeta: metav1.ObjectMeta{
Name: "service1",
Namespace: "default",
},
Spec: istioNetworking.VirtualService{
Hosts: []string{"service1.local"},
Gateways: []string{"istio-system/ingress-alb"},
Http: []*istioNetworking.HTTPRoute{
{
Match: []*istioNetworking.HTTPMatchRequest{
{
Uri: &istioNetworking.StringMatch{
MatchType: &istioNetworking.StringMatch_Prefix{Prefix: "/"},
},
},
},
Route: []*istioNetworking.HTTPRouteDestination{
{
Destination: &istioNetworking.Destination{
Host: "service1",
Port: &istioNetworking.PortSelector{
Number: 3000,
},
},
},
},
},
},
},
},
want1: false,
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
g := gomega.NewGomegaWithT(t)
r := &DynamoNimDeploymentReconciler{
IngressControllerClassName: tt.fields.IngressControllerClassName,
IstioVirtualServiceEnabled: tt.fields.IstioVirtualServiceEnabled,
}
got, got1, err := r.generateVirtualService(tt.args.ctx, tt.args.opt)
if (err != nil) != tt.wantErr {
t.Errorf("DynamoNimDeploymentReconciler.generateVirtualService() error = %v, wantErr %v", err, tt.wantErr)
return
}
g.Expect(got).To(gomega.Equal(tt.want))
g.Expect(got1).To(gomega.Equal(tt.want1))
})
}
}
...@@ -256,7 +256,6 @@ func GenerateDynamoNIMDeployments(ctx context.Context, parentDynamoDeployment *v ...@@ -256,7 +256,6 @@ func GenerateDynamoNIMDeployments(ctx context.Context, parentDynamoDeployment *v
if config.EntryService == service.Name { if config.EntryService == service.Name {
// enable virtual service for the entry service // enable virtual service for the entry service
deployment.Spec.Ingress.Enabled = true deployment.Spec.Ingress.Enabled = true
deployment.Spec.Ingress.UseVirtualService = &deployment.Spec.Ingress.Enabled
} }
} }
if service.Config.Resources != nil { if service.Config.Resources != nil {
......
...@@ -228,8 +228,7 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) { ...@@ -228,8 +228,7 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) {
}, },
}, },
Ingress: v1alpha1.IngressSpec{ Ingress: v1alpha1.IngressSpec{
Enabled: true, Enabled: true,
UseVirtualService: &[]bool{true}[0],
}, },
}, },
}, },
...@@ -336,8 +335,7 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) { ...@@ -336,8 +335,7 @@ func TestGenerateDynamoNIMDeployments(t *testing.T) {
}, },
}, },
Ingress: v1alpha1.IngressSpec{ Ingress: v1alpha1.IngressSpec{
Enabled: true, Enabled: true,
UseVirtualService: &[]bool{true}[0],
}, },
}, },
}, },
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment