Skip to content
Open
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
5 changes: 5 additions & 0 deletions util-scripts/external-entities/demo/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM registry.fedoraproject.org/fedora:41

RUN dnf install -y which iproute bpftool procps iptables nc

COPY prepare-tap.sh /scripts/
9 changes: 9 additions & 0 deletions util-scripts/external-entities/demo/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
ifeq ($(TAG),)
TAG=$(shell git describe --tags --abbrev=10 --dirty)
endif

.PHONY:
build:
docker build -t external-connection .
docker tag external-connection quay.io/$(REPOSITORY)/external-connection:$(TAG)
docker push quay.io/$(REPOSITORY)/external-connection:$(TAG)
10 changes: 10 additions & 0 deletions util-scripts/external-entities/demo/collector-config-disabled.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: collector-config
namespace: stackrox
data:
runtime_config.yaml: |
networking:
externalIps:
enabled: DISABLED
10 changes: 10 additions & 0 deletions util-scripts/external-entities/demo/collector-config-enabled.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: collector-config
namespace: stackrox
data:
runtime_config.yaml: |
networking:
externalIps:
enabled: ENABLED
17 changes: 17 additions & 0 deletions util-scripts/external-entities/demo/create-cidr-block.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env bash
set -eou pipefail

ROX_ENDPOINT=${1:-localhost:8000}
cidr_block=${2:-8.8.8.0/24}
cidr_name=${3:-"testCIDR"}

clusters_json="$(curl --location --silent --request GET "https://${ROX_ENDPOINT}/v1/clusters" -k --header "Authorization: Bearer $ROX_API_TOKEN")"

cluster_id="$(echo "$clusters_json" | jq -r '.clusters[0].id')"

cidr_json='{"entity": {"cidr": "'"$cidr_block"'", "name": "'"$cidr_name"'", "id": ""}}'


create_cidr_block_response_json="$(curl --location --silent --request POST --data "$cidr_json" "https://${ROX_ENDPOINT}/v1/networkgraph/cluster/$cluster_id/externalentities" -k --header "Authorization: Bearer $ROX_API_TOKEN")"

echo "$create_cidr_block_response_json" | jq
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash
set -eou pipefail

export TARGET_IP=$1
export PORT=$2
export NAME=$3

envsubst < external-destination-source-stable-template.yml > deployment.yml
kubectl apply -f deployment.yml
9 changes: 9 additions & 0 deletions util-scripts/external-entities/demo/create-secret-for-qa.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash
set -eou pipefail

kubectl -n stackrox get secret stackrox -o yaml > stackrox-secret.yml
sed 's|stackrox|qa|' stackrox-secret.yml > qa-secret.yml
kubectl create -f qa-secret.yml

rm stackrox-secret.yml
rm qa-secret.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM registry.fedoraproject.org/fedora:41

RUN dnf install -y python pip

RUN pip install flask

COPY dynamic-connector.py /dynamic-connector.py

CMD python /dynamic-connector.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
ifeq ($(TAG),)
TAG=$(shell git describe --tags --abbrev=10 --dirty)
endif

.PHONY:
build:
docker build -t dynamic-connector .
docker tag dynamic-connector quay.io/$(REPOSITORY)/dynamic-connector:$(TAG)
docker push quay.io/$(REPOSITORY)/dynamic-connector:$(TAG)
16 changes: 16 additions & 0 deletions util-scripts/external-entities/demo/dynamic-connector/demo.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -eou pipefail

curl "http://127.0.0.1:8181/?action=open&ip=8.8.8.8&port=53"

# Check network graph

# Lock baseline

curl "http://127.0.0.1:8181/?action=open&ip=142.250.72.238&port=80"

# Check network graph and violations

curl "http://127.0.0.1:8181/?action=open&ip=1.1.1.1&port=53"

# Check network graph
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import threading
import time
from flask import Flask, request
import socket

app = Flask(__name__)

# Set of active targets (tuple of IP and port)
targets = set()
targets_lock = threading.Lock()

def connect_to_target(ip, port, timeout=1):
"""Connect to target via TCP socket"""
try:
with socket.create_connection((ip, int(port)), timeout=timeout):
print(f"[✓] Created connection {ip}:{port}")
except Exception as e:
print(f"[✗] Failed to connect {ip}:{port} - {e}")

def connector():
"""Background thread to continuously connect to targets"""
while True:
with targets_lock:
current_targets = list(targets)
for ip, port in current_targets:
connect_to_target(ip, port)
time.sleep(2)

@app.route('/')
def handle_request():
action = request.args.get('action')
ip = request.args.get('ip')
port = request.args.get('port')

if not all([action, ip, port]):
return "Missing required parameters: action, ip, port", 400

target = (ip, int(port))

with targets_lock:
if action == 'open':
targets.add(target)
return f"Opened {ip}:{port}", 200
elif action == 'close':
targets.discard(target)
return f"Closed {ip}:{port}", 200
else:
return f"Invalid action '{action}'", 400

if __name__ == '__main__':
threading.Thread(target=connector, daemon=True).start()
# Start the Flask server
app.run(host='127.0.0.1', port=8181)

Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
generation: 1
labels:
app: dynamic-connector
name: dynamic-connector
name: dynamic-connector
namespace: qa
spec:
minReadySeconds: 15
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: dynamic-connector
name: dynamic-connector
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: dynamic-connector
deployment: dynamic-connector
name: dynamic-connector
name: dynamic-connector
namespace: qa
spec:
imagePullSecrets:
- name: qa
containers:
- image: quay.io/jvirtane/dynamic-connector:4.8.x-909-gd5216e5572
imagePullPolicy: IfNotPresent
name: dynamic-connector
resources: {}
securityContext:
capabilities: {}
privileged: true
readOnlyRootFilesystem: false
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
12 changes: 12 additions & 0 deletions util-scripts/external-entities/demo/dynamic-connector/pre-demo.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -eou pipefail

kubectl delete ns qa || true

kubectl create ns qa

kubectl create -f dynamic-connector.yml

sleep 15

kubectl -n qa port-forward deploy/dynamic-connector 8181 > /dev/null 2>&1 &
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env bash
set -eou pipefail

kubectl create -f collector-config-enabled.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
generation: 1
labels:
app: external-destination-source-${NAME}
name: external-destination-source-${NAME}
name: external-destination-source-${NAME}
namespace: qa
spec:
minReadySeconds: 15
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: external-destination-source-${NAME}
name: external-destination-source-${NAME}
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: external-destination-source-${NAME}
deployment: external-destination-source-${NAME}
name: external-destination-source-${NAME}
name: external-destination-source-${NAME}
namespace: qa
spec:
imagePullSecrets:
- name: qa
containers:
- args:
- |
/scripts/prepare-tap.sh -a "${TARGET_IP}/32" -o
nc -lk "${TARGET_IP}" "${PORT}" &
sleep 2
while sleep 30; do nc -zv "${TARGET_IP}" "${PORT}"; done
command:
- /bin/bash
- -c
image: quay.io/${REPOSITORY}/external-connection:${TAG}
imagePullPolicy: IfNotPresent
name: external-destination-source
resources: {}
securityContext:
capabilities: {}
privileged: true
readOnlyRootFilesystem: false
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
generation: 1
labels:
app: external-destination-source
name: external-destination-source
name: external-destination-source
namespace: qa
spec:
minReadySeconds: 15
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: external-destination-source
name: external-destination-source
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: external-destination-source
deployment: external-destination-source
name: external-destination-source
name: external-destination-source
namespace: qa
spec:
imagePullSecrets:
- name: qa
containers:
- args:
- while sleep 30; do wget -S -T 2 http://www.google.com; done
command:
- /bin/sh
- -c
image: quay.io/rhacs-eng/qa-multi-arch:nginx-1-15-4-alpine
imagePullPolicy: IfNotPresent
name: external-destination-source
resources: {}
securityContext:
capabilities: {}
privileged: false
readOnlyRootFilesystem: false
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
15 changes: 15 additions & 0 deletions util-scripts/external-entities/demo/get-network-policy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env bash
set -eou pipefail

ROX_ENDPOINT=${1:-localhost:8000}

clusters_json="$(curl --location --silent --request GET "https://${ROX_ENDPOINT}/v1/clusters" -k --header "Authorization: Bearer $ROX_API_TOKEN")"

cluster_id="$(echo "$clusters_json" | jq -r '.clusters[0].id')"

query="Cluster%3Aremote%2BNamespace%3Aqa&includePorts=true"
network_policy_json="$(curl --location --silent --request GET "https://${ROX_ENDPOINT}/v1/networkpolicies/generate/${cluster_id}?deleteExisting=NONE&query=$query" -k --header "Authorization: Bearer $ROX_API_TOKEN")"

network_policy=$(echo "$network_policy_json" | jq -r '.modification.applyYaml')

printf "%b\n" "$network_policy"
20 changes: 20 additions & 0 deletions util-scripts/external-entities/demo/lock-baseline.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env bash
set -eou pipefail

ROX_ENDPOINT=${1:-localhost:8000}

deploymentname=${2:-external-destination-source-1}

json_deployments="$(curl --location --silent --request GET "https://${ROX_ENDPOINT}/v1/deployments" -k -H "Authorization: Bearer $ROX_API_TOKEN")"

json_deployments="$(echo "$json_deployments" | jq --arg deploymentname "$deploymentname" '{deployments: [.deployments[] | select(.name == $deploymentname)]}')"
deployment="$(echo "$json_deployments" | jq --arg deploymentname "$deploymentname" '{deployments: [.deployments[] | select(.name == $deploymentname)]}' | jq -r .deployments[0].id)"

echo "json_deployments= $deployment"

json_status="$(curl --location --silent --request GET "https://${ROX_ENDPOINT}/v1/networkbaseline/${deployment}/status/external" -k -H "Authorization: Bearer $ROX_API_TOKEN")"

echo "$json_status" | jq


json_status="$(curl --location --silent --request GET "https://${ROX_ENDPOINT}/v1/networkbaseline/${deployment}/lock" -k -H "Authorization: Bearer $ROX_API_TOKEN")"
Loading