Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .github/workflows/build-test-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
- main

env:
VERSION: 1.3.0
VERSION: 1.4.0
IMAGE_NAME: pubsubplus-eventbroker-operator
VAULT_ADDR: ${{ secrets.VAULT_ADDR }}
GCLOUD_PROJECT_ID_DEV: ${{ secrets.GCLOUD_PROJECT_ID }}
Expand Down Expand Up @@ -252,6 +252,11 @@ jobs:
uses: ./.github/workflows/test-broker-chaos-situation.yml
secrets: inherit

int-nodeport:
needs: build
uses: ./.github/workflows/test-nodeport.yml
secrets: inherit

taints-and-tolerations:
if: ${{ false }} # disable for now
needs: build
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/prep-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
release_tag:
description: 'Release tag'
required: true
default: '1.3.0'
default: '1.4.0'
prep_internal_release:
# Need to distinguish between internal and external releases
# Internal release: Will use default internal location for created images (ghcr.io) and will tag and push operator candidate there
Expand Down
118 changes: 118 additions & 0 deletions .github/workflows/test-nodeport.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
name: Integration Test for NodePort Service Type

on: workflow_call

jobs:
test:
name: Test
runs-on: ubuntu-latest

permissions:
contents: 'read'
id-token: 'write'
packages: 'read'

steps:
- name: Set env and tools
run: |
echo "TESTNAMESPACE=op-test-nodeport-$(date +%s)" >> $GITHUB_ENV

- name: Check out code
uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
fetch-depth: 0

- id: 'auth'
name: 'Authenticate to Google Cloud'
uses: 'google-github-actions/[email protected]'
with:
service_account: ${{ secrets.GCP_SERVICE_ACCOUNT }}
workload_identity_provider: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }}
access_token_lifetime: 600s

- name: Use the GKE Autopilot test cluster
uses: 'google-github-actions/[email protected]'
with:
cluster_name: 'dev-integrationtesting'
location: 'us-central1'

- name: Login to Github Packages
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Deploy Operator
run: |
sleep 20;
for i in {1..3}; do
kubectl cluster-info
kubectl get pods -n kube-system
echo "current-context:" $(kubectl config current-context)
echo "environment-kubeconfig:" ${KUBECONFIG}
kubectl get ns pubsubplus-operator-system || kubectl create ns pubsubplus-operator-system
if kubectl get deployment pubsubplus-eventbroker-operator -n pubsubplus-operator-system; then
echo "pubsubplus-eventbroker-operator is already deployed"
break
else
kubectl apply -f <(kubectl create secret generic regcred --from-file=.dockerconfigjson=${HOME}/.docker/config.json --type=kubernetes.io/dockerconfigjson -n pubsubplus-operator-system --dry-run=client -o yaml)
make deploy | grep 'created \| configured'
kubectl rollout status deployment pubsubplus-eventbroker-operator -n pubsubplus-operator-system --timeout=240s
if [ $? -eq 0 ]; then
break
else
echo "Rollout status check failed, retrying in 20 seconds..."
sleep 20
fi
fi
done

- name: Testing NodePort with Fixed Port Assignment
run: |
kubectl create ns $TESTNAMESPACE && kubectl config set-context --current --namespace=$TESTNAMESPACE
kubectl apply -f ci/manifests/eventbroker-nonha-nodeport.yaml | grep "test-nonha-nodeport created"
sleep 25 ; kubectl get all
for i in {1..3}; do
if kubectl wait pods --selector app.kubernetes.io/instance=test-nonha-nodeport --for condition=Ready --timeout=120s; then
echo "Pods are ready."
break
else
echo "Waiting for pods failed, retrying in 10 seconds..."
kubectl describe pods --selector app.kubernetes.io/instance=test-nonha-nodeport
sleep 10
fi
done

# Verify service type is NodePort
kubectl get service test-nonha-nodeport-pubsubplus -o jsonpath='{.spec.type}' | grep "NodePort"

# Verify nodePort values are set correctly
SEMP_NODEPORT=$(kubectl get service test-nonha-nodeport-pubsubplus -o jsonpath='{.spec.ports[?(@.name=="tcp-semp")].nodePort}')
SMF_NODEPORT=$(kubectl get service test-nonha-nodeport-pubsubplus -o jsonpath='{.spec.ports[?(@.name=="tcp-smf")].nodePort}')
WEB_NODEPORT=$(kubectl get service test-nonha-nodeport-pubsubplus -o jsonpath='{.spec.ports[?(@.name=="tcp-web")].nodePort}')

echo "SEMP NodePort: $SEMP_NODEPORT, Expected: 30080"
echo "SMF NodePort: $SMF_NODEPORT, Expected: 30555"
echo "WEB NodePort: $WEB_NODEPORT, Expected: 30008"

[ "$SEMP_NODEPORT" = "30080" ] && echo "SEMP NodePort test passed" || echo "SEMP NodePort test failed"
[ "$SMF_NODEPORT" = "30555" ] && echo "SMF NodePort test passed" || echo "SMF NodePort test failed"
[ "$WEB_NODEPORT" = "30008" ] && echo "WEB NodePort test passed" || echo "WEB NodePort test failed"

# Test connectivity through NodePort
NODE_IP=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="ExternalIP")].address}')
echo "Using node IP: $NODE_IP"

# Test SMF connectivity directly through NodePort
echo "Testing direct NodePort connection to $NODE_IP:$SMF_NODEPORT"
curl -O https://sftp.solace.com/download/SDKPERF_C_LINUX64
tar -xvf SDKPERF_C_LINUX64
pubSubTools/sdkperf_c -cip=tcp://$NODE_IP:$SMF_NODEPORT -mn=1000 -mr=0 -ptl=t1 -stl=t1 | grep "Total Messages"

kubectl delete eventbroker test-nonha-nodeport | grep deleted

- name: Delete broker deployment
run: |
kubectl delete ns $TESTNAMESPACE --ignore-not-found
6 changes: 3 additions & 3 deletions .github/workflows/vulncheck_periodic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
- cron: '0 */ * * *'

env:
VERSION: 1.3.0
VERSION: 1.4.0
IMAGE_NAME: pubsubplus-eventbroker-operator
VAULT_ADDR: ${{ secrets.VAULT_ADDR }}
GCLOUD_PROJECT_ID_DEV: ${{ secrets.GCLOUD_PROJECT_ID }}
Expand Down Expand Up @@ -65,7 +65,7 @@ jobs:
secrets: |
secret/data/development/gcp-gcr GCP_SERVICE_ACCOUNT | GCP_DEV_SERVICE_ACCOUNT
env:
VERSION: 1.3.0
VERSION: 1.4.0
IMAGE_NAME: pubsubplus-eventbroker-operator
VAULT_ADDR: ${{ secrets.VAULT_ADDR }}
GCLOUD_PROJECT_ID_DEV: ${{ secrets.GCLOUD_PROJECT_ID }}
Expand All @@ -85,7 +85,7 @@ jobs:
gcr.io/${{ env.GCLOUD_PROJECT_ID_DEV }}/${{ env.IMAGE_NAME }}:${{ env.VERSION }}
push: true
env:
VERSION: 1.3.0
VERSION: 1.4.0
IMAGE_NAME: pubsubplus-eventbroker-operator
VAULT_ADDR: ${{ secrets.VAULT_ADDR }}
GCLOUD_PROJECT_ID_DEV: ${{ secrets.GCLOUD_PROJECT_ID }}
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ FROM registry.access.redhat.com/ubi9/ubi-minimal:9.5-1745855087
LABEL name="solace/pubsubplus-eventbroker-operator"
LABEL maintainer="Solace Corporation"
LABEL vendor="Solace Corporation"
LABEL version="1.3.0"
LABEL release="1.3.0"
LABEL version="1.4.0"
LABEL release="1.4.0"
LABEL summary="Solace PubSub+ Event Broker Kubernetes Operator"
LABEL description="The Solace PubSub+ Event Broker Kubernetes Operator deploys and manages the lifecycle of PubSub+ Event Brokers"

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# To re-generate a bundle for another specific version without changing the standard setup, you can:
# - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2)
# - use environment variables to overwrite this value (e.g export VERSION=0.0.2)
VERSION ?= 1.3.0
VERSION ?= 1.4.0

# API_VERSION defines the API version for the PubSubPlusEventBroker CRD
API_VERSION ?= v1beta1
Expand Down
6 changes: 6 additions & 0 deletions api/v1beta1/eventbroker_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,12 @@ type BrokerPort struct {
//+kubebuilder:validation:Type:=number
// Port number to expose on the service
ServicePort int32 `json:"servicePort"`
//+optional
//+kubebuilder:validation:Minimum=30000
//+kubebuilder:validation:Maximum=32767
//+kubebuilder:validation:Type:=number
// NodePort specifies a fixed node port when service type is NodePort
NodePort int32 `json:"nodePort,omitempty"`
}

// Service defines parameters configure Service details for the Broker
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ metadata:
operators.operatorframework.io/project_layout: go.kubebuilder.io/v3
repository: https://github.com/SolaceProducts/pubsubplus-kubernetes-quickstart
support: Solace Products
name: pubsubplus-eventbroker-operator.v1.3.0
name: pubsubplus-eventbroker-operator.v1.4.0
namespace: placeholder
spec:
apiservicedefinitions: {}
Expand Down Expand Up @@ -296,7 +296,7 @@ spec:
valueFrom:
fieldRef:
fieldPath: metadata.annotations['olm.targetNamespaces']
image: docker.io/solace/pubsubplus-eventbroker-operator:1.3.0
image: docker.io/solace/pubsubplus-eventbroker-operator:1.4.0
imagePullPolicy: Always
livenessProbe:
httpGet:
Expand Down Expand Up @@ -411,4 +411,4 @@ spec:
provider:
name: Solace Corporation
url: www.solace.com
version: 1.3.0
version: 1.4.0
25 changes: 25 additions & 0 deletions ci/manifests/eventbroker-nonha-nodeport.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
apiVersion: pubsubplus.solace.com/v1beta1
kind: PubSubPlusEventBroker
metadata:
name: test-nonha-nodeport
spec:
developer: true
service:
type: NodePort
ports:
- name: tcp-semp
protocol: TCP
containerPort: 8080
servicePort: 8080
nodePort: 30080
- name: tcp-smf
protocol: TCP
containerPort: 55555
servicePort: 55555
nodePort: 30555
- name: tcp-web
protocol: TCP
containerPort: 8008
servicePort: 8008
nodePort: 30008
Original file line number Diff line number Diff line change
Expand Up @@ -1459,6 +1459,13 @@ spec:
description: Unique name for the port that can be referred
to by services.
type: string
nodePort:
description: NodePort specifies a fixed node port when service
type is NodePort
format: int32
maximum: 32767
minimum: 30000
type: number
protocol:
default: TCP
description: Protocol for port. Must be UDP, TCP, or SCTP.
Expand Down
2 changes: 1 addition & 1 deletion config/manager/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ kind: Kustomization
images:
- name: controller
newName: ghcr.io/solacedev/pubsubplus-eventbroker-operator
newTag: 1.3.0
newTag: 1.4.0
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ metadata:
certified: "true"
com.redhat.delivery.operator.bundle: "true"
com.redhat.openshift.versions: v4.10
containerImage: docker.io/solace/pubsubplus-eventbroker-operator:v1.3.0
containerImage: docker.io/solace/pubsubplus-eventbroker-operator:v1.4.0
createdAt: "2023-03-31T12:00:00.000Z"
description: The Solace PubSub+ Event Broker Operator deploys and manages the
lifecycle of PubSub+ Event Brokers
Expand Down
24 changes: 24 additions & 0 deletions config/samples/sample_nodeport.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: pubsubplus.solace.com/v1beta1
kind: PubSubPlusEventBroker
metadata:
name: node-port-example
spec:
developer: true
service:
type: NodePort
ports:
- name: tcp-semp
protocol: TCP
containerPort: 8080
servicePort: 8080
nodePort: 30080
- name: tcp-smf
protocol: TCP
containerPort: 55555
servicePort: 55555
nodePort: 30555
- name: tcp-web
protocol: TCP
containerPort: 8008
servicePort: 8008
nodePort: 30008
13 changes: 13 additions & 0 deletions controllers/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ func (r *PubSubPlusEventBrokerReconciler) updateServiceForEventBroker(service *c
Port: pbPort.ServicePort,
TargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: pbPort.ContainerPort},
}

// Use the helper function to assign NodePort if needed
assignNodePortIfNeeded(&ports[idx], *pbPort, getServiceType(m.Spec.Service))
}
service.Spec.Ports = ports
} else {
Expand All @@ -77,6 +80,9 @@ func (r *PubSubPlusEventBrokerReconciler) updateServiceForEventBroker(service *c
Port: pbPort.ServicePort,
TargetPort: intstr.IntOrString{Type: intstr.Int, IntVal: pbPort.ContainerPort},
}

// Use the helper function to assign NodePort if needed
assignNodePortIfNeeded(&ports[idx], *pbPort, getServiceType(m.Spec.Service))
}
service.Spec.Ports = ports
}
Expand All @@ -89,3 +95,10 @@ func getServiceType(ms eventbrokerv1beta1.Service) corev1.ServiceType {
}
return corev1.ServiceTypeLoadBalancer
}

// Helper function to assign NodePort if needed
func assignNodePortIfNeeded(servicePort *corev1.ServicePort, brokerPort eventbrokerv1beta1.BrokerPort, serviceType corev1.ServiceType) {
if serviceType == corev1.ServiceTypeNodePort && brokerPort.NodePort > 0 {
servicePort.NodePort = brokerPort.NodePort
}
}
Loading