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

Work with Istio out of the box #634

Merged
merged 16 commits into from
Nov 22, 2023
Merged
52 changes: 29 additions & 23 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ CERTIFICATION_VERSION ?= $(VERSION)
# The previous Operator version used to run the compatibility tests.
COMPATIBLE_VERSION ?= 3.3.1
# The selector to use to find Operator Pods of the COMPATIBLE_VERSION (do not put in double quotes!!)
COMPATIBLE_SELECTOR = control-plane=coherence
COMPATIBLE_SELECTOR ?= control-plane=coherence

# The GitHub project URL
PROJECT_URL = https://github.com/oracle/coherence-operator
Expand Down Expand Up @@ -1049,28 +1049,31 @@ run-prometheus-test: gotestsum
# These tests will use whichever k8s cluster the local environment is pointing to.
# ----------------------------------------------------------------------------------------------------------------------
.PHONY: compatibility-test
compatibility-test: export CGO_ENABLED = 0
compatibility-test: export OPERATOR_NAMESPACE := $(OPERATOR_NAMESPACE)
compatibility-test: export CLUSTER_NAMESPACE := $(CLUSTER_NAMESPACE)
compatibility-test: export BUILD_OUTPUT := $(BUILD_OUTPUT)
compatibility-test: export TEST_APPLICATION_IMAGE := $(TEST_APPLICATION_IMAGE)
compatibility-test: export TEST_APPLICATION_IMAGE_CLIENT := $(TEST_APPLICATION_IMAGE_CLIENT)
compatibility-test: export TEST_APPLICATION_IMAGE_HELIDON := $(TEST_APPLICATION_IMAGE_HELIDON)
compatibility-test: export TEST_APPLICATION_IMAGE_SPRING := $(TEST_APPLICATION_IMAGE_SPRING)
compatibility-test: export TEST_APPLICATION_IMAGE_SPRING_FAT := $(TEST_APPLICATION_IMAGE_SPRING_FAT)
compatibility-test: export TEST_APPLICATION_IMAGE_SPRING_CNBP := $(TEST_APPLICATION_IMAGE_SPRING_CNBP)
compatibility-test: export TEST_COHERENCE_IMAGE := $(TEST_COHERENCE_IMAGE)
compatibility-test: export IMAGE_PULL_SECRETS := $(IMAGE_PULL_SECRETS)
compatibility-test: export TEST_SSL_SECRET := $(TEST_SSL_SECRET)
compatibility-test: export TEST_IMAGE_PULL_POLICY := $(IMAGE_PULL_POLICY)
compatibility-test: export TEST_STORAGE_CLASS := $(TEST_STORAGE_CLASS)
compatibility-test: export VERSION := $(VERSION)
compatibility-test: export COMPATIBLE_VERSION := $(COMPATIBLE_VERSION)
compatibility-test: export COMPATIBLE_SELECTOR := $(COMPATIBLE_SELECTOR)
compatibility-test: export OPERATOR_IMAGE := $(OPERATOR_IMAGE)
compatibility-test: export COHERENCE_IMAGE := $(COHERENCE_IMAGE)
compatibility-test: export GO_TEST_FLAGS_E2E := $(strip $(GO_TEST_FLAGS_E2E))
compatibility-test: undeploy build-all-images $(BUILD_HELM)/coherence-operator-$(VERSION).tgz undeploy clean-namespace reset-namespace gotestsum ## Run the Operator backwards compatibility tests
compatibility-test: undeploy build-all-images $(BUILD_HELM)/coherence-operator-$(VERSION).tgz undeploy clean-namespace reset-namespace gotestsum just-compatibility-test ## Run the Operator backwards compatibility tests

.PHONY: just-compatibility-test
just-compatibility-test: export CGO_ENABLED = 0
just-compatibility-test: export OPERATOR_NAMESPACE := $(OPERATOR_NAMESPACE)
just-compatibility-test: export CLUSTER_NAMESPACE := $(CLUSTER_NAMESPACE)
just-compatibility-test: export BUILD_OUTPUT := $(BUILD_OUTPUT)
just-compatibility-test: export TEST_APPLICATION_IMAGE := $(TEST_APPLICATION_IMAGE)
just-compatibility-test: export TEST_APPLICATION_IMAGE_CLIENT := $(TEST_APPLICATION_IMAGE_CLIENT)
just-compatibility-test: export TEST_APPLICATION_IMAGE_HELIDON := $(TEST_APPLICATION_IMAGE_HELIDON)
just-compatibility-test: export TEST_APPLICATION_IMAGE_SPRING := $(TEST_APPLICATION_IMAGE_SPRING)
just-compatibility-test: export TEST_APPLICATION_IMAGE_SPRING_FAT := $(TEST_APPLICATION_IMAGE_SPRING_FAT)
just-compatibility-test: export TEST_APPLICATION_IMAGE_SPRING_CNBP := $(TEST_APPLICATION_IMAGE_SPRING_CNBP)
just-compatibility-test: export TEST_COHERENCE_IMAGE := $(TEST_COHERENCE_IMAGE)
just-compatibility-test: export IMAGE_PULL_SECRETS := $(IMAGE_PULL_SECRETS)
just-compatibility-test: export TEST_SSL_SECRET := $(TEST_SSL_SECRET)
just-compatibility-test: export TEST_IMAGE_PULL_POLICY := $(IMAGE_PULL_POLICY)
just-compatibility-test: export TEST_STORAGE_CLASS := $(TEST_STORAGE_CLASS)
just-compatibility-test: export VERSION := $(VERSION)
just-compatibility-test: export COMPATIBLE_VERSION := $(COMPATIBLE_VERSION)
just-compatibility-test: export COMPATIBLE_SELECTOR := $(COMPATIBLE_SELECTOR)
just-compatibility-test: export OPERATOR_IMAGE := $(OPERATOR_IMAGE)
just-compatibility-test: export COHERENCE_IMAGE := $(COHERENCE_IMAGE)
just-compatibility-test: export GO_TEST_FLAGS_E2E := $(strip $(GO_TEST_FLAGS_E2E))
just-compatibility-test: ## Run the Operator backwards compatibility tests WITHOUT building anything
helm repo add coherence https://oracle.github.io/coherence-operator/charts
helm repo update
$(GOTESTSUM) --format standard-verbose --junitfile $(TEST_LOGS_DIR)/operator-e2e-compatibility-test.xml \
Expand Down Expand Up @@ -2107,6 +2110,9 @@ install-istio: get-istio ## Install the latest version of Istio into k8s (or ove
kubectl apply -f ./hack/istio-strict.yaml
kubectl -n $(OPERATOR_NAMESPACE) apply -f ./hack/istio-operator.yaml
kubectl label namespace $(OPERATOR_NAMESPACE) istio-injection=enabled --overwrite=true
kubectl label namespace $(OPERATOR_NAMESPACE_CLIENT) istio-injection=enabled --overwrite=true
kubectl label namespace $(CLUSTER_NAMESPACE) istio-injection=enabled --overwrite=true
kubectl apply -f $(ISTIO_HOME)/samples/addons

# ----------------------------------------------------------------------------------------------------------------------
# Uninstall Istio
Expand Down
69 changes: 50 additions & 19 deletions api/v1/coherence_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1065,6 +1065,14 @@ type NamedPortSpec struct {
// port.
// +optional
ServiceMonitor *ServiceMonitorSpec `json:"serviceMonitor,omitempty"`
// ExposeOnSTS is a flag to indicate that this port should also be exposed on
// the StatefulSetHeadless service. This is useful in cases where a service mesh
// such as Istio is being used and ports such as the Extend or gRPC ports are
// accessed via the StatefulSet service.
// The default is `true` so all additional ports are exposed on the StatefulSet
// headless service.
// +optional
ExposeOnSTS *bool `json:"exposeOnSts,omitempty"`
}

// GetServiceName returns the name of the Service used to expose this port, or returns
Expand All @@ -1090,13 +1098,6 @@ func (in *NamedPortSpec) CreateService(deployment CoherenceResource) *corev1.Ser

name, _ := in.GetServiceName(deployment)

var portName string
if in.Service != nil && in.Service.PortName != nil {
portName = *in.Service.PortName
} else {
portName = in.Name
}

// The labels for the service
svcLabels := deployment.CreateCommonLabels()
svcLabels[LabelComponent] = LabelComponentPortService
Expand All @@ -1118,17 +1119,7 @@ func (in *NamedPortSpec) CreateService(deployment CoherenceResource) *corev1.Ser

// Add the port
serviceSpec.Ports = []corev1.ServicePort{
{
Name: portName,
Protocol: in.GetProtocol(),
Port: in.GetServicePort(deployment),
TargetPort: intstr.FromInt(int(in.GetPort(deployment))),
NodePort: in.GetNodePort(),
},
}

if in.AppProtocol != nil {
serviceSpec.Ports[0].AppProtocol = in.AppProtocol
in.createServicePort(deployment),
}

// Add the service selector
Expand All @@ -1148,6 +1139,31 @@ func (in *NamedPortSpec) CreateService(deployment CoherenceResource) *corev1.Ser
return &svc
}

func (in *NamedPortSpec) createServicePort(deployment CoherenceResource) corev1.ServicePort {
var portName string
if in.Service != nil && in.Service.PortName != nil {
portName = *in.Service.PortName
} else {
portName = in.Name
}

sp := corev1.ServicePort{
Name: portName,
Protocol: in.GetProtocol(),
Port: in.GetServicePort(deployment),
TargetPort: intstr.FromInt32(in.GetPort(deployment)),
NodePort: in.GetNodePort(),
}

if in.AppProtocol != nil {
sp.AppProtocol = in.AppProtocol
} else {
sp.AppProtocol = in.GetDefaultAppProtocol()
}

return sp
}

// CreateServiceMonitor creates the Prometheus ServiceMonitor to expose this port if enabled.
func (in *NamedPortSpec) CreateServiceMonitor(deployment CoherenceResource) *monitoringv1.ServiceMonitor {
if in == nil || !in.IsEnabled() {
Expand Down Expand Up @@ -1245,6 +1261,21 @@ func (in *NamedPortSpec) GetServicePort(d CoherenceResource) int32 {
}
}

func (in *NamedPortSpec) GetDefaultAppProtocol() *string {
switch {
case in == nil:
return nil
case strings.ToLower(in.Name) == PortNameMetrics:
// special case for well known port - metrics
return pointer.String(AppProtocolHttp)
case in.Port == 0 && strings.ToLower(in.Name) == PortNameManagement:
// special case for well known port - management
return pointer.String(AppProtocolHttp)
default:
return nil
}
}

func (in *NamedPortSpec) GetNodePort() int32 {
if in == nil || in.NodePort == nil {
return 0
Expand Down Expand Up @@ -2142,7 +2173,7 @@ func (in *ReadinessProbeSpec) UpdateProbeSpec(port int32, path string, probe *co
default:
probe.HTTPGet = &corev1.HTTPGetAction{
Path: path,
Port: intstr.FromInt(int(port)),
Port: intstr.FromInt32(port),
Scheme: corev1.URISchemeHTTP,
}
}
Expand Down
4 changes: 2 additions & 2 deletions api/v1/coherence_webhook_job_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ func TestJobCoherenceLocalPortIsNotSetOnUpdate(t *testing.T) {
func TestJobCoherenceLocalPortAdjustIsSet(t *testing.T) {
g := NewGomegaWithT(t)

lpa := intstr.FromInt(int(coh.DefaultUnicastPortAdjust))
lpa := intstr.FromInt32(coh.DefaultUnicastPortAdjust)
c := coh.CoherenceJob{}
c.Default()
g.Expect(c.Spec.Coherence).NotTo(BeNil())
Expand All @@ -145,7 +145,7 @@ func TestJobCoherenceLocalPortAdjustIsSet(t *testing.T) {
func TestJobCoherenceLocalPortAdjustIsNotOverridden(t *testing.T) {
g := NewGomegaWithT(t)

lpa := intstr.FromInt(9876)
lpa := intstr.FromInt32(9876)
c := coh.CoherenceJob{
Spec: coh.CoherenceJobResourceSpec{
CoherenceResourceSpec: coh.CoherenceResourceSpec{
Expand Down
4 changes: 2 additions & 2 deletions api/v1/coherence_webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func TestCoherenceLocalPortIsNotSetOnUpdate(t *testing.T) {
func TestCoherenceLocalPortAdjustIsSet(t *testing.T) {
g := NewGomegaWithT(t)

lpa := intstr.FromInt(int(coh.DefaultUnicastPortAdjust))
lpa := intstr.FromInt32(coh.DefaultUnicastPortAdjust)
c := coh.Coherence{}
c.Default()
g.Expect(c.Spec.Coherence).NotTo(BeNil())
Expand All @@ -144,7 +144,7 @@ func TestCoherenceLocalPortAdjustIsSet(t *testing.T) {
func TestCoherenceLocalPortAdjustIsNotOverridden(t *testing.T) {
g := NewGomegaWithT(t)

lpa := intstr.FromInt(9876)
lpa := intstr.FromInt32(9876)
c := coh.Coherence{
Spec: coh.CoherenceStatefulSetResourceSpec{
CoherenceResourceSpec: coh.CoherenceResourceSpec{
Expand Down
12 changes: 11 additions & 1 deletion api/v1/coherencejobresource_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ func (in *CoherenceJob) GetCoherenceClusterName() string {
if in == nil {
return ""
}

if in.Spec.Cluster == "" {
return in.Name
}
Expand Down Expand Up @@ -93,6 +92,17 @@ func (in *CoherenceJob) AddAnnotation(key, value string) {
}
}

func (in *CoherenceJob) AddAnnotationIfMissing(key, value string) {
if in != nil {
if in.Annotations == nil {
in.Annotations = make(map[string]string)
}
if _, found := in.Annotations[key]; !found {
in.Annotations[key] = value
}
}
}

// GetStatus returns this resource's CoherenceResourceSpec
func (in *CoherenceJob) GetStatus() *CoherenceResourceStatus {
return &in.Status
Expand Down
2 changes: 2 additions & 0 deletions api/v1/coherenceresource.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ type CoherenceResource interface {
GetStatus() *CoherenceResourceStatus
// AddAnnotation adds an annotation to this resource
AddAnnotation(key, value string)
// AddAnnotationIfMissing adds an annotation to this resource if it is not already present
AddAnnotationIfMissing(key, value string)
// GetAnnotations returns the annotations on this resource
GetAnnotations() map[string]string
// CreateKubernetesResources creates the kubernetes resources defined by this resource
Expand Down
18 changes: 18 additions & 0 deletions api/v1/coherenceresource_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,17 @@ func (in *Coherence) AddAnnotation(key, value string) {
}
}

func (in *Coherence) AddAnnotationIfMissing(key, value string) {
if in != nil {
if in.Annotations == nil {
in.Annotations = make(map[string]string)
}
if _, found := in.Annotations[key]; !found {
in.Annotations[key] = value
}
}
}

// GetNamespacedName returns the namespace/name key to look up this resource.
func (in *Coherence) GetNamespacedName() types.NamespacedName {
return types.NamespacedName{
Expand Down Expand Up @@ -321,7 +332,14 @@ func (in *Coherence) GetVersionAnnotation() (string, bool) {
// before the specified version, or is not set.
// The version parameter must be a valid SemVer value.
func (in *Coherence) IsBeforeVersion(version string) bool {
if version[0] != 'v' {
version = "v" + version
}

if actual, found := in.GetVersionAnnotation(); found {
if actual[0] != 'v' {
actual = "v" + actual
}
return semver.Compare(actual, version) < 0
}
return true
Expand Down
Loading