diff --git a/.claude/settings.json b/.claude/settings.json
new file mode 100644
index 0000000..44a2983
--- /dev/null
+++ b/.claude/settings.json
@@ -0,0 +1,31 @@
+{
+ "permissions": {
+ "allow": [
+ "Bash(git commit:*)",
+ "Bash(git mv:*)",
+ "Bash(git checkout:*)",
+ "Bash(git add:*)",
+ "Bash(tree:*)",
+ "Bash(find:*)",
+ "Bash(grep:*)",
+ "Bash(go build:*)",
+ "Bash(go mod tidy:*)",
+ "Bash(go list:*)",
+ "Bash(go vet:*)",
+ "Bash(gofmt:*)",
+ "WebSearch"
+ ]
+ },
+ "extraKnownMarketplaces": {
+ "datum-claude-code-plugins": {
+ "source": {
+ "source": "github",
+ "repo": "datum-cloud/claude-code-plugins"
+ }
+ }
+ },
+ "enabledPlugins": {
+ "datum-platform@datum-claude-code-plugins": true,
+ "datum-gtm@datum-claude-code-plugins": true
+ }
+}
diff --git a/.devcontainer/README.md b/.devcontainer/README.md
new file mode 100644
index 0000000..89d1764
--- /dev/null
+++ b/.devcontainer/README.md
@@ -0,0 +1,222 @@
+# Galactic Development Container
+
+This devcontainer provides a complete development environment for the Galactic multi-cloud networking solution.
+
+## Features
+
+### Languages & Runtimes
+- **Go 1.24.2** - For operator, agent, and CNI development
+- **Python 3.13** - For the galactic-router
+
+### Kubernetes Tools
+- **kubectl** - Kubernetes CLI
+- **kind** - Kubernetes in Docker for local clusters
+- **kustomize v5.6.0** - Kubernetes configuration management
+- **controller-gen v0.18.0** - Code generation for Kubernetes controllers
+- **setup-envtest** - Test environment for controller-runtime
+
+### Go Development Tools
+- **gopls** - Go language server
+- **delve** - Go debugger
+- **golangci-lint v2.1.6** - Go linter
+
+### Network Tools
+- **iproute2** - Advanced network configuration (ip, ss, etc.)
+- **iptables** - Firewall management
+- **tcpdump** - Network packet analyzer
+- **iputils-ping** - Network connectivity testing
+- **net-tools** - Classic network tools (ifconfig, netstat, etc.)
+- **dnsutils** - DNS utilities (dig, nslookup)
+- **bridge-utils** - Bridge configuration
+- **ethtool** - Network interface settings
+- **conntrack** - Connection tracking
+
+### Build & Development Tools
+- **Docker-in-Docker** - For building containers and running Kind clusters
+- **protoc 25.1** - Protocol Buffer compiler
+- **protoc-gen-go** - Go code generation for protobuf
+- **protoc-gen-go-grpc** - gRPC code generation for Go
+- **make** - Build automation
+- **gcc/build-essential** - C compiler for CGO dependencies
+- **jq** - JSON processor
+- **git** - Version control
+
+## VS Code Extensions
+
+The devcontainer includes the following extensions:
+- **Go** - Official Go extension
+- **Python** - Official Python extension
+- **Pylance** - Python language server
+- **Kubernetes** - Kubernetes resource management
+- **YAML** - YAML language support
+- **Docker** - Docker container management
+- **GitLens** - Enhanced Git integration
+- **Markdown Lint** - Markdown linting
+- **Even Better TOML** - TOML language support
+
+## Configuration
+
+### Go Settings
+- Auto-format on save with `gofmt`
+- Organize imports on save
+- golangci-lint integration
+- gopls with semantic tokens and useful code lenses
+- Test environment set to `GOOS=linux`
+
+### Python Settings
+- Auto-format on save
+- Organize imports on save
+- flake8 linting enabled
+- Python 3.13 interpreter
+
+### Forwarded Ports
+- **8080** - Metrics endpoint
+- **8081** - Health check endpoint
+- **9443** - Webhook server
+
+## Capabilities
+
+The devcontainer runs with elevated privileges to support network operations:
+- `--privileged` - Full device access
+- `--cap-add=NET_ADMIN` - Network administration
+- `--cap-add=SYS_ADMIN` - System administration
+
+These are required for:
+- Creating network namespaces
+- Configuring VRFs (Virtual Routing and Forwarding)
+- Managing SRv6 routes
+- Testing CNI plugins
+
+## Post-Create Setup
+
+The `post-create.sh` script automatically:
+1. Installs Go development tools (gopls, delve, golangci-lint)
+2. Installs Kubernetes tools (controller-gen, kustomize, setup-envtest, kind)
+3. Installs Protocol Buffer compiler and Go plugins
+4. Installs network diagnostic tools
+5. Sets up the Python environment for galactic-router
+6. Generates Kubernetes manifests and DeepCopy methods
+7. Configures git safe directory
+
+## Getting Started
+
+After the container starts and post-create completes:
+
+```bash
+# Build the galactic binary
+make build
+
+# Run unit tests
+make test
+
+# Run E2E tests (creates a Kind cluster)
+make test-e2e
+
+# Run the operator locally
+make run-operator
+
+# Run the agent locally
+make run-agent
+
+# Develop the Python router
+cd router
+behave
+
+# Lint Go code
+make lint
+
+# Format Go code
+make fmt
+```
+
+## Testing
+
+### Unit Tests
+```bash
+make test
+```
+
+### E2E Tests
+```bash
+# Automatically creates/tears down Kind cluster
+make test-e2e
+
+# Or manually manage the cluster
+make setup-test-e2e
+go test ./test/e2e/ -v -ginkgo.v
+make cleanup-test-e2e
+```
+
+### Python Tests
+```bash
+cd router
+behave # Run BDD tests
+flake8 # Lint Python code
+```
+
+## Network Development
+
+The devcontainer includes all tools needed for network programming:
+
+```bash
+# View network interfaces
+ip link show
+
+# View routing tables
+ip route show
+
+# View SRv6 segments
+ip -6 route show
+
+# Capture traffic
+tcpdump -i any
+
+# Test connectivity
+ping -c 3 8.8.8.8
+```
+
+## Docker-in-Docker
+
+Build and test containers inside the devcontainer:
+
+```bash
+# Build the galactic image
+make docker-build
+
+# Create a Kind cluster
+kind create cluster --name galactic-dev
+
+# Load image into Kind
+kind load docker-image ghcr.io/datum-cloud/galactic:latest --name galactic-dev
+```
+
+## Troubleshooting
+
+### Post-create script fails
+Check the logs in the VS Code Output panel under "Dev Containers". Common issues:
+- Network connectivity for downloading tools
+- Permissions for installing system packages
+
+### Network tools don't work
+Ensure the container is running with `--privileged` and the necessary capabilities. Check `runArgs` in `devcontainer.json`.
+
+### Kind cluster creation fails
+Ensure Docker-in-Docker is running:
+```bash
+docker ps
+```
+
+If not, restart the devcontainer.
+
+### Go modules not resolving
+```bash
+go mod download
+go mod tidy
+```
+
+### Python packages not installing
+```bash
+cd router
+pip install --upgrade pip
+pip install -e .[test]
+```
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
new file mode 100644
index 0000000..6c27c2b
--- /dev/null
+++ b/.devcontainer/devcontainer.json
@@ -0,0 +1,140 @@
+{
+ "name": "galactic",
+ "image": "mcr.microsoft.com/devcontainers/base:ubuntu-24.04",
+ "features": {
+ "ghcr.io/devcontainers/features/go:1": {
+ "version": "1.24.2"
+ },
+ "ghcr.io/devcontainers/features/python:1": {
+ "version": "3.13",
+ "installTools": true
+ },
+ "ghcr.io/devcontainers/features/docker-in-docker:2": {
+ "version": "latest",
+ "enableNonRootDocker": "true",
+ "moby": "true"
+ },
+ "ghcr.io/devcontainers/features/kubectl-helm-minikube:1": {
+ "version": "latest",
+ "helm": "none",
+ "minikube": "none"
+ },
+ "ghcr.io/devcontainers/features/common-utils:2": {
+ "installZsh": true,
+ "installOhMyZsh": true,
+ "upgradePackages": true,
+ "username": "vscode",
+ "userUid": "1000",
+ "userGid": "1000"
+ },
+ "ghcr.io/devcontainers/features/git:1": {
+ "version": "latest"
+ },
+ "ghcr.io/devcontainers/features/node:1": {
+ "version": "lts"
+ }
+ },
+ "customizations": {
+ "vscode": {
+ "extensions": [
+ "golang.go",
+ "ms-python.python",
+ "ms-python.vscode-pylance",
+ "ms-kubernetes-tools.vscode-kubernetes-tools",
+ "redhat.vscode-yaml",
+ "ms-azuretools.vscode-docker",
+ "eamodio.gitlens",
+ "davidanson.vscode-markdownlint",
+ "tamasfe.even-better-toml"
+ ],
+ "settings": {
+ "go.toolsManagement.autoUpdate": true,
+ "go.useLanguageServer": true,
+ "go.lintTool": "golangci-lint",
+ "go.lintFlags": [
+ "--fast"
+ ],
+ "go.formatTool": "gofmt",
+ "go.testEnvVars": {
+ "GOOS": "linux"
+ },
+ "go.buildFlags": [],
+ "go.testFlags": [
+ "-v"
+ ],
+ "[go]": {
+ "editor.formatOnSave": true,
+ "editor.codeActionsOnSave": {
+ "source.organizeImports": "explicit"
+ }
+ },
+ "gopls": {
+ "formatting.gofumpt": true,
+ "ui.semanticTokens": true,
+ "ui.codelenses": {
+ "gc_details": false,
+ "regenerate_cgo": false,
+ "generate": true,
+ "test": true,
+ "tidy": true,
+ "upgrade_dependency": true,
+ "vendor": true
+ }
+ },
+ "python.defaultInterpreterPath": "/usr/local/bin/python3",
+ "python.linting.enabled": true,
+ "python.linting.flake8Enabled": true,
+ "python.linting.flake8Path": "/usr/local/bin/flake8",
+ "python.formatting.provider": "none",
+ "[python]": {
+ "editor.formatOnSave": true,
+ "editor.defaultFormatter": "ms-python.python",
+ "editor.codeActionsOnSave": {
+ "source.organizeImports": "explicit"
+ }
+ },
+ "files.watcherExclude": {
+ "**/bin/**": true,
+ "**/dist/**": true,
+ "**/.git/objects/**": true,
+ "**/.git/subtree-cache/**": true,
+ "**/node_modules/**": true
+ },
+ "files.exclude": {
+ "**/.git": false
+ },
+ "terminal.integrated.defaultProfile.linux": "bash"
+ }
+ }
+ },
+ "forwardPorts": [8080, 8081, 9443],
+ "portsAttributes": {
+ "8080": {
+ "label": "Metrics",
+ "onAutoForward": "notify"
+ },
+ "8081": {
+ "label": "Health",
+ "onAutoForward": "notify"
+ },
+ "9443": {
+ "label": "Webhook",
+ "onAutoForward": "notify"
+ }
+ },
+ "remoteUser": "vscode",
+ "containerEnv": {
+ "GOOS": "linux",
+ "CGO_ENABLED": "1"
+ },
+ "mounts": [
+ "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind",
+ "source=${localEnv:HOME}${localEnv:USERPROFILE}/.gitconfig,target=/home/vscode/.gitconfig,type=bind,consistency=cached"
+ ],
+ "postCreateCommand": "bash .devcontainer/post-create.sh",
+ "runArgs": [
+ "--privileged",
+ "--cap-add=NET_ADMIN",
+ "--cap-add=SYS_ADMIN"
+ ]
+}
diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh
new file mode 100755
index 0000000..d541058
--- /dev/null
+++ b/.devcontainer/post-create.sh
@@ -0,0 +1,95 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+echo "Starting post-create setup for Galactic development environment..."
+
+# Set up Go tools
+echo "Installing Go development tools..."
+go install golang.org/x/tools/gopls@latest
+go install github.com/go-delve/delve/cmd/dlv@latest
+go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.1.6
+
+# Install controller-gen, kustomize, and other Kubernetes tools
+echo "Installing Kubernetes development tools..."
+cd /workspaces/galactic
+make controller-gen kustomize setup-envtest
+
+# Install kind for local Kubernetes testing
+echo "Installing Kind..."
+GO111MODULE=on go install sigs.k8s.io/kind@latest
+
+# Install protoc (Protocol Buffer compiler)
+echo "Installing protoc..."
+PROTOC_VERSION="25.1"
+curl -LO "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-linux-x86_64.zip"
+sudo unzip -o protoc-${PROTOC_VERSION}-linux-x86_64.zip -d /usr/local bin/protoc
+sudo unzip -o protoc-${PROTOC_VERSION}-linux-x86_64.zip -d /usr/local 'include/*'
+rm -f protoc-${PROTOC_VERSION}-linux-x86_64.zip
+
+# Install protoc-gen-go for Go protobuf generation
+echo "Installing protoc-gen-go..."
+go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
+go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
+
+# Install network tools
+echo "Installing network tools..."
+sudo apt-get update
+sudo apt-get install -y \
+ iproute2 \
+ iptables \
+ tcpdump \
+ iputils-ping \
+ net-tools \
+ dnsutils \
+ bridge-utils \
+ ethtool \
+ conntrack \
+ jq \
+ make \
+ gcc \
+ build-essential
+
+# Set up Python environment for galactic-router
+echo "Setting up Python environment for galactic-router..."
+cd /workspaces/galactic/router
+pip install --upgrade pip setuptools wheel
+pip install -e .[test]
+
+# Generate Kubernetes manifests and code
+echo "Generating Kubernetes manifests and DeepCopy methods..."
+cd /workspaces/galactic
+make manifests generate
+
+# Set up git safe directory
+echo "Configuring git safe directory..."
+git config --global --add safe.directory /workspaces/galactic
+
+# Install Claude Code CLI
+echo "Installing Claude Code..."
+curl -fsSL https://claude.ai/install.sh | bash
+
+# Verify installations
+echo ""
+echo "Verifying installations..."
+echo "Go version: $(go version)"
+echo "Python version: $(python3 --version)"
+echo "kubectl version: $(kubectl version --client --short 2>/dev/null || echo 'kubectl installed')"
+echo "kind version: $(kind version)"
+echo "kustomize version: $(kustomize version --short 2>/dev/null || echo 'kustomize installed')"
+echo "protoc version: $(protoc --version)"
+echo "Docker version: $(docker --version)"
+echo "golangci-lint version: $(golangci-lint version 2>/dev/null || echo 'golangci-lint installed')"
+echo "delve version: $(dlv version)"
+echo "gopls version: $(gopls version)"
+
+echo ""
+echo "Post-create setup completed successfully!"
+echo ""
+echo "You can now:"
+echo " - Build the galactic binary: make build"
+echo " - Run tests: make test"
+echo " - Run E2E tests: make test-e2e"
+echo " - Run the operator: make run-operator"
+echo " - Run the agent: make run-agent"
+echo " - Develop the router: cd router && behave"
+echo ""
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..e7b4d93
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,34 @@
+version: 2
+updates:
+ # Go modules
+ - package-ecosystem: gomod
+ directory: /
+ schedule:
+ interval: weekly
+ groups:
+ kubernetes:
+ patterns:
+ - "k8s.io/*"
+ - "sigs.k8s.io/*"
+ all-others:
+ update-types:
+ - minor
+ - patch
+
+ # GitHub Actions
+ - package-ecosystem: github-actions
+ directory: /
+ schedule:
+ interval: weekly
+
+ # Python (router)
+ - package-ecosystem: pip
+ directory: /router
+ schedule:
+ interval: weekly
+
+ # Docker
+ - package-ecosystem: docker
+ directory: /build
+ schedule:
+ interval: weekly
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..9396a83
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,195 @@
+name: CI
+
+on:
+ push:
+ branches: [main]
+ pull_request:
+ branches: [main]
+
+env:
+ GO_VERSION: '1.24'
+ PYTHON_VERSION: '3.13'
+
+jobs:
+ # Tier 1: Fast checks (every PR)
+ lint:
+ name: Lint
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - uses: actions/setup-go@v5
+ with:
+ go-version: ${{ env.GO_VERSION }}
+
+ - name: Run golangci-lint
+ uses: golangci/golangci-lint-action@v7
+ with:
+ version: v2.1.6
+ args: --timeout=5m
+
+ test-unit:
+ name: Unit Tests
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - uses: actions/setup-go@v5
+ with:
+ go-version: ${{ env.GO_VERSION }}
+
+ - name: Run unit tests
+ run: |
+ go test -v -race -coverprofile=coverage.out \
+ ./internal/operator/identifier/... \
+ ./internal/operator/cniconfig/... \
+ ./pkg/common/util/...
+
+ - name: Upload coverage
+ uses: codecov/codecov-action@v4
+ with:
+ files: coverage.out
+ fail_ci_if_error: false
+
+ test-operator:
+ name: Operator Tests
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - uses: actions/setup-go@v5
+ with:
+ go-version: ${{ env.GO_VERSION }}
+
+ - name: Generate manifests
+ run: make manifests generate
+
+ - name: Install envtest
+ run: go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
+
+ - name: Run operator tests
+ run: |
+ KUBEBUILDER_ASSETS=$(setup-envtest use 1.31.0 -p path)
+ export KUBEBUILDER_ASSETS
+ echo "KUBEBUILDER_ASSETS=$KUBEBUILDER_ASSETS"
+ go test -v -race -coverprofile=coverage-operator.out ./internal/operator/...
+
+ - name: Upload coverage
+ uses: codecov/codecov-action@v4
+ with:
+ files: coverage-operator.out
+ fail_ci_if_error: false
+
+ test-router:
+ name: Router Tests
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - uses: actions/setup-python@v5
+ with:
+ python-version: ${{ env.PYTHON_VERSION }}
+
+ - name: Install dependencies
+ working-directory: router
+ run: pip install -e .[test]
+
+ - name: Lint
+ working-directory: router
+ run: flake8 .
+
+ - name: Run BDD tests
+ working-directory: router
+ run: behave
+
+ build:
+ name: Build
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - uses: actions/setup-go@v5
+ with:
+ go-version: ${{ env.GO_VERSION }}
+
+ - name: Generate manifests
+ run: make manifests generate
+
+ - name: Build binary
+ run: make build
+
+ - name: Verify binary
+ run: |
+ file bin/galactic
+ ./bin/galactic version
+
+ docker-build:
+ name: Docker Build
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - uses: docker/setup-buildx-action@v3
+
+ - name: Build image
+ uses: docker/build-push-action@v6
+ with:
+ context: .
+ file: build/Dockerfile
+ push: false
+ tags: ghcr.io/datum-cloud/galactic:${{ github.sha }}
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
+
+ # Tier 2: Integration tests (main branch and releases)
+ test-e2e:
+ name: E2E Tests
+ runs-on: ubuntu-latest
+ needs: [lint, test-unit, test-operator, test-router, build]
+ if: github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')
+ steps:
+ - uses: actions/checkout@v4
+
+ - uses: actions/setup-go@v5
+ with:
+ go-version: ${{ env.GO_VERSION }}
+
+ - name: Install Kind
+ run: |
+ go install sigs.k8s.io/kind@latest
+ kind version
+
+ - name: Create Kind cluster
+ run: |
+ kind create cluster --name galactic-e2e --wait 5m
+ kubectl cluster-info
+
+ - name: Build and load image
+ run: |
+ make docker-build IMG=galactic:e2e
+ kind load docker-image galactic:e2e --name galactic-e2e
+
+ - name: Install CRDs
+ run: make install
+
+ - name: Deploy operator
+ run: |
+ make deploy IMG=galactic:e2e
+ kubectl -n galactic-system wait --for=condition=available deployment/galactic-controller-manager --timeout=120s
+
+ - name: Verify CRDs
+ run: |
+ kubectl get crd vpcs.galactic.datumapis.com
+ kubectl get crd vpcattachments.galactic.datumapis.com
+
+ - name: Create test resources
+ run: |
+ kubectl apply -f config/samples/galactic_v1alpha_vpc.yaml
+ kubectl apply -f config/samples/galactic_v1alpha_vpcattachment.yaml
+ sleep 5
+ kubectl get vpc
+ kubectl get vpcattachment
+
+ - name: Cleanup
+ if: always()
+ run: kind delete cluster --name galactic-e2e
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..6537a3d
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,74 @@
+name: Release
+
+on:
+ push:
+ tags:
+ - 'v*'
+
+env:
+ REGISTRY: ghcr.io
+ IMAGE_NAME: ${{ github.repository }}
+
+jobs:
+ release:
+ name: Build and Push
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ packages: write
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - uses: actions/setup-go@v5
+ with:
+ go-version: '1.24'
+
+ - name: Generate manifests
+ run: make manifests generate
+
+ - name: Log in to Container Registry
+ uses: docker/login-action@v3
+ with:
+ registry: ${{ env.REGISTRY }}
+ username: ${{ github.actor }}
+ password: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Extract metadata
+ id: meta
+ uses: docker/metadata-action@v5
+ with:
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
+ tags: |
+ type=semver,pattern={{version}}
+ type=semver,pattern={{major}}.{{minor}}
+ type=semver,pattern={{major}}
+ type=sha
+
+ - uses: docker/setup-buildx-action@v3
+
+ - name: Build and push
+ uses: docker/build-push-action@v6
+ with:
+ context: .
+ file: build/Dockerfile
+ push: true
+ tags: ${{ steps.meta.outputs.tags }}
+ labels: ${{ steps.meta.outputs.labels }}
+ platforms: linux/amd64,linux/arm64
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
+ build-args: |
+ VERSION=${{ github.ref_name }}
+ COMMIT=${{ github.sha }}
+
+ - name: Generate install manifest
+ run: |
+ make build-installer IMG=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}
+
+ - name: Create Release
+ uses: softprops/action-gh-release@v2
+ with:
+ generate_release_notes: true
+ files: |
+ dist/install.yaml
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..bb71bf7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,50 @@
+# Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+/galactic
+bin/
+dist/
+
+# Test binary, built with `go test -c`
+*.test
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+cover.out
+
+# Dependency directories (remove the comment below to include it)
+# vendor/
+
+# Go workspace file
+go.work
+
+# IDEs
+.idea/
+.vscode/
+*.swp
+*.swo
+*~
+
+# Claude Code
+.claude/settings.local.json
+
+# OS
+.DS_Store
+
+# Python
+__pycache__/
+*.py[cod]
+*$py.class
+.Python
+*.egg-info/
+.eggs/
+
+# kubebuilder
+testbin/
+
+# Temporary kustomize files
+config/manager/kustomization.yaml.tmp
+build/Dockerfile.cross
diff --git a/galactic-operator/.golangci.yml b/.golangci.yml
similarity index 98%
rename from galactic-operator/.golangci.yml
rename to .golangci.yml
index e5b21b0..21045c1 100644
--- a/galactic-operator/.golangci.yml
+++ b/.golangci.yml
@@ -40,6 +40,7 @@ linters:
- third_party$
- builtin$
- examples$
+ - ^lab/
formatters:
enable:
- gofmt
diff --git a/galactic-cni/LICENSE b/LICENSE
similarity index 100%
rename from galactic-cni/LICENSE
rename to LICENSE
diff --git a/galactic-operator/Makefile b/Makefile
similarity index 87%
rename from galactic-operator/Makefile
rename to Makefile
index 3e69fc8..8bcbcdb 100644
--- a/galactic-operator/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
# Image URL to use all building/pushing image targets
-IMG ?= ghcr.io/datum-cloud/galactic-operator:latest
+IMG ?= ghcr.io/datum-cloud/galactic:latest
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN))
@@ -55,17 +55,17 @@ fmt: ## Run go fmt against code.
.PHONY: vet
vet: ## Run go vet against code.
- go vet ./...
+ GOOS=linux go vet ./...
.PHONY: test
test: manifests generate fmt vet setup-envtest ## Run tests.
- KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $$(go list ./... | grep -v /e2e) -coverprofile cover.out
+ GOOS=linux KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $$(go list ./... | grep -v /e2e) -coverprofile cover.out
# TODO(user): To use a different vendor for e2e tests, modify the setup under 'tests/e2e'.
# The default setup assumes Kind is pre-installed and builds/loads the Manager Docker image locally.
# CertManager is installed by default; skip with:
# - CERT_MANAGER_INSTALL_SKIP=true
-KIND_CLUSTER ?= galactic-operator-test-e2e
+KIND_CLUSTER ?= galactic-test-e2e
.PHONY: setup-test-e2e
setup-test-e2e: ## Set up a Kind cluster for e2e tests if it does not exist
@@ -105,22 +105,26 @@ lint-config: golangci-lint ## Verify golangci-lint linter configuration
##@ Build
.PHONY: build
-build: manifests generate fmt vet ## Build manager binary.
- go build -o bin/manager cmd/main.go
+build: manifests generate fmt vet ## Build galactic binary.
+ go build -o bin/galactic cmd/galactic/main.go
-.PHONY: run
-run: manifests generate fmt vet ## Run a controller from your host.
- go run ./cmd/main.go
+.PHONY: run-operator
+run-operator: manifests generate fmt vet ## Run operator from your host.
+ go run ./cmd/galactic/main.go operator
+
+.PHONY: run-agent
+run-agent: fmt vet ## Run agent from your host.
+ go run ./cmd/galactic/main.go agent
# If you wish to build the manager image targeting other platforms you can use the --platform flag.
# (i.e. docker build --platform linux/arm64). However, you must enable docker buildKit for it.
# More info: https://docs.docker.com/develop/develop-images/build_enhancements/
.PHONY: docker-build
-docker-build: ## Build docker image with the manager.
- $(CONTAINER_TOOL) build -t ${IMG} .
+docker-build: ## Build docker image with the unified binary.
+ $(CONTAINER_TOOL) build -t ${IMG} -f build/Dockerfile .
.PHONY: docker-push
-docker-push: ## Push docker image with the manager.
+docker-push: ## Push docker image with the unified binary.
$(CONTAINER_TOOL) push ${IMG}
# PLATFORMS defines the target platforms for the manager image be built to provide support to multiple
@@ -131,14 +135,14 @@ docker-push: ## Push docker image with the manager.
# To adequately provide solutions that are compatible with multiple platforms, you should consider using this option.
PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
.PHONY: docker-buildx
-docker-buildx: ## Build and push docker image for the manager for cross-platform support
+docker-buildx: ## Build and push docker image for the unified binary for cross-platform support
# copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile
- sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross
- - $(CONTAINER_TOOL) buildx create --name galactic-operator-builder
- $(CONTAINER_TOOL) buildx use galactic-operator-builder
- - $(CONTAINER_TOOL) buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f Dockerfile.cross .
- - $(CONTAINER_TOOL) buildx rm galactic-operator-builder
- rm Dockerfile.cross
+ sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' build/Dockerfile > build/Dockerfile.cross
+ - $(CONTAINER_TOOL) buildx create --name galactic-builder
+ $(CONTAINER_TOOL) buildx use galactic-builder
+ - $(CONTAINER_TOOL) buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f build/Dockerfile.cross .
+ - $(CONTAINER_TOOL) buildx rm galactic-builder
+ rm build/Dockerfile.cross
.PHONY: build-installer
build-installer: manifests generate kustomize ## Generate a consolidated YAML with CRDs and deployment.
@@ -169,6 +173,14 @@ deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in
undeploy: kustomize ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
$(KUSTOMIZE) build config/default | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f -
+##@ Cleanup
+
+.PHONY: clean
+clean: ## Remove build artifacts and temporary files
+ rm -rf bin/
+ rm -rf dist/
+ rm -f cover.out
+
##@ Dependencies
## Location to install dependencies to
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..4ebbe7d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,55 @@
+# Galactic
+
+**Multi-cloud networking for Kubernetes, simplified.**
+
+Galactic connects Kubernetes workloads across multiple clouds and regions as if they were on a single, unified network. It provides secure, isolated Virtual Private Clouds (VPCs) that span cloud boundaries—without vendor lock-in or complex configuration.
+
+## The Problem
+
+Modern organizations run workloads everywhere: AWS, Azure, GCP, on-premises, and edge locations. Each environment brings its own networking model, APIs, and constraints. The result is fragmented networks, operational complexity, and cloud provider lock-in.
+
+## Our Approach
+
+Galactic extends Kubernetes with two simple resources—VPCs and VPCAttachments—that let you define multi-cloud network topology declaratively:
+
+```yaml
+apiVersion: networking.datum.net/v1alpha1
+kind: VPC
+metadata:
+ name: production
+spec:
+ ipv4CIDRBlocks:
+ - 10.100.0.0/16
+```
+
+Any pod can join the VPC with a single annotation:
+
+```yaml
+metadata:
+ annotations:
+ networking.datum.net/vpc-attachment: us-west
+```
+
+That's it. Your pod now has an interface connected to the VPC, able to communicate with any other attached workload—regardless of which cloud or region it's running in.
+
+Under the hood, Galactic uses Segment Routing over IPv6 (SRv6) for efficient, deterministic routing and Virtual Routing and Forwarding (VRF) for true network isolation at the kernel level.
+
+## Why Galactic
+
+**For Developers** — Attach to a VPC with a single annotation. No networking code, no cloud-specific APIs.
+
+**For Platform Teams** — Manage multi-cloud networking from Kubernetes using GitOps workflows and standard tooling.
+
+**For Organizations** — Move workloads between providers without network redesign. One networking model instead of N cloud-specific implementations.
+
+## Getting Started
+
+See the [`lab/`](./lab/) directory for example topologies and the [DevContainer](./.devcontainer/) for development environment setup.
+
+## License
+
+See [LICENSE](./LICENSE) for details.
+
+---
+
+*Galactic is developed by [Datum](https://datum.net).*
diff --git a/galactic-operator/Dockerfile b/build/Dockerfile
similarity index 80%
rename from galactic-operator/Dockerfile
rename to build/Dockerfile
index cb1b130..97ca004 100644
--- a/galactic-operator/Dockerfile
+++ b/build/Dockerfile
@@ -1,4 +1,4 @@
-# Build the manager binary
+# Build the unified galactic binary
FROM golang:1.24 AS builder
ARG TARGETOS
ARG TARGETARCH
@@ -12,8 +12,8 @@ COPY go.sum go.sum
RUN go mod download
# Copy the go source
-COPY cmd/main.go cmd/main.go
-COPY api/ api/
+COPY cmd/ cmd/
+COPY pkg/ pkg/
COPY internal/ internal/
# Build
@@ -21,13 +21,13 @@ COPY internal/ internal/
# was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO
# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore,
# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform.
-RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/main.go
+RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o galactic cmd/galactic/main.go
-# Use distroless as minimal base image to package the manager binary
+# Use distroless as minimal base image to package the binary
# Refer to https://github.com/GoogleContainerTools/distroless for more details
FROM gcr.io/distroless/static:nonroot
WORKDIR /
-COPY --from=builder /workspace/manager .
+COPY --from=builder /workspace/galactic .
USER 65532:65532
-ENTRYPOINT ["/manager"]
+ENTRYPOINT ["/galactic"]
diff --git a/cmd/galactic/main.go b/cmd/galactic/main.go
new file mode 100644
index 0000000..44ba776
--- /dev/null
+++ b/cmd/galactic/main.go
@@ -0,0 +1,65 @@
+/*
+Copyright 2025.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package main
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/spf13/cobra"
+
+ "go.datum.net/galactic/internal/cmd/agent"
+ "go.datum.net/galactic/internal/cmd/cni"
+ "go.datum.net/galactic/internal/cmd/operator"
+ "go.datum.net/galactic/internal/cmd/version"
+)
+
+func main() {
+ // Auto-detect CNI mode via CNI_COMMAND environment variable
+ // When run as a CNI plugin, the CNI runtime sets this variable
+ if os.Getenv("CNI_COMMAND") != "" {
+ if err := cni.NewCommand().Execute(); err != nil {
+ fmt.Fprintf(os.Stderr, "Error: %v\n", err)
+ os.Exit(1)
+ }
+ return
+ }
+
+ // Normal CLI mode with subcommands
+ rootCmd := &cobra.Command{
+ Use: "galactic",
+ Short: "Galactic multi-cloud networking solution",
+ Long: `Galactic provides VPC connectivity across multiple clouds using SRv6 packet routing.
+
+This unified binary supports multiple modes of operation:
+- operator: Kubernetes operator for VPC/VPCAttachment CRDs
+- agent: Local network agent for SRv6 route management
+- cni: CNI plugin for container network attachment
+`,
+ }
+
+ // Add subcommands
+ rootCmd.AddCommand(operator.NewCommand())
+ rootCmd.AddCommand(agent.NewCommand())
+ rootCmd.AddCommand(cni.NewCommand())
+ rootCmd.AddCommand(version.NewCommand())
+
+ if err := rootCmd.Execute(); err != nil {
+ fmt.Fprintf(os.Stderr, "Error: %v\n", err)
+ os.Exit(1)
+ }
+}
diff --git a/galactic-agent/config/base/daemonset.yaml b/config/agent/daemonset.yaml
similarity index 92%
rename from galactic-agent/config/base/daemonset.yaml
rename to config/agent/daemonset.yaml
index ca8b0a0..8b3ba3a 100644
--- a/galactic-agent/config/base/daemonset.yaml
+++ b/config/agent/daemonset.yaml
@@ -25,7 +25,8 @@ spec:
operator: DoesNotExist
containers:
- name: galactic-agent
- image: ghcr.io/datum-cloud/galactic-agent:latest
+ image: ghcr.io/datum-cloud/galactic:latest
+ command: ["/galactic", "agent"]
imagePullPolicy: Always
resources:
limits:
diff --git a/galactic-agent/config/base/kustomization.yaml b/config/agent/kustomization.yaml
similarity index 100%
rename from galactic-agent/config/base/kustomization.yaml
rename to config/agent/kustomization.yaml
diff --git a/galactic-operator/config/certmanager/certificate-metrics.yaml b/config/certmanager/certificate-metrics.yaml
similarity index 100%
rename from galactic-operator/config/certmanager/certificate-metrics.yaml
rename to config/certmanager/certificate-metrics.yaml
diff --git a/galactic-operator/config/certmanager/certificate-webhook.yaml b/config/certmanager/certificate-webhook.yaml
similarity index 100%
rename from galactic-operator/config/certmanager/certificate-webhook.yaml
rename to config/certmanager/certificate-webhook.yaml
diff --git a/galactic-operator/config/certmanager/issuer.yaml b/config/certmanager/issuer.yaml
similarity index 100%
rename from galactic-operator/config/certmanager/issuer.yaml
rename to config/certmanager/issuer.yaml
diff --git a/galactic-operator/config/certmanager/kustomization.yaml b/config/certmanager/kustomization.yaml
similarity index 100%
rename from galactic-operator/config/certmanager/kustomization.yaml
rename to config/certmanager/kustomization.yaml
diff --git a/galactic-operator/config/certmanager/kustomizeconfig.yaml b/config/certmanager/kustomizeconfig.yaml
similarity index 100%
rename from galactic-operator/config/certmanager/kustomizeconfig.yaml
rename to config/certmanager/kustomizeconfig.yaml
diff --git a/galactic-operator/config/crd/bases/galactic.datumapis.com_vpcattachments.yaml b/config/crd/bases/galactic.datumapis.com_vpcattachments.yaml
similarity index 100%
rename from galactic-operator/config/crd/bases/galactic.datumapis.com_vpcattachments.yaml
rename to config/crd/bases/galactic.datumapis.com_vpcattachments.yaml
diff --git a/galactic-operator/config/crd/bases/galactic.datumapis.com_vpcs.yaml b/config/crd/bases/galactic.datumapis.com_vpcs.yaml
similarity index 100%
rename from galactic-operator/config/crd/bases/galactic.datumapis.com_vpcs.yaml
rename to config/crd/bases/galactic.datumapis.com_vpcs.yaml
diff --git a/galactic-operator/config/crd/bases/k8s.cni.cncf.io_network-attachment-definitions.yaml b/config/crd/bases/k8s.cni.cncf.io_network-attachment-definitions.yaml
similarity index 100%
rename from galactic-operator/config/crd/bases/k8s.cni.cncf.io_network-attachment-definitions.yaml
rename to config/crd/bases/k8s.cni.cncf.io_network-attachment-definitions.yaml
diff --git a/galactic-operator/config/crd/kustomization.yaml b/config/crd/kustomization.yaml
similarity index 100%
rename from galactic-operator/config/crd/kustomization.yaml
rename to config/crd/kustomization.yaml
diff --git a/galactic-operator/config/crd/kustomizeconfig.yaml b/config/crd/kustomizeconfig.yaml
similarity index 100%
rename from galactic-operator/config/crd/kustomizeconfig.yaml
rename to config/crd/kustomizeconfig.yaml
diff --git a/galactic-operator/config/default/cert_metrics_manager_patch.yaml b/config/default/cert_metrics_manager_patch.yaml
similarity index 100%
rename from galactic-operator/config/default/cert_metrics_manager_patch.yaml
rename to config/default/cert_metrics_manager_patch.yaml
diff --git a/galactic-operator/config/default/kustomization.yaml b/config/default/kustomization.yaml
similarity index 100%
rename from galactic-operator/config/default/kustomization.yaml
rename to config/default/kustomization.yaml
diff --git a/galactic-operator/config/default/manager_metrics_patch.yaml b/config/default/manager_metrics_patch.yaml
similarity index 100%
rename from galactic-operator/config/default/manager_metrics_patch.yaml
rename to config/default/manager_metrics_patch.yaml
diff --git a/galactic-operator/config/default/manager_webhook_patch.yaml b/config/default/manager_webhook_patch.yaml
similarity index 100%
rename from galactic-operator/config/default/manager_webhook_patch.yaml
rename to config/default/manager_webhook_patch.yaml
diff --git a/galactic-operator/config/default/metrics_service.yaml b/config/default/metrics_service.yaml
similarity index 100%
rename from galactic-operator/config/default/metrics_service.yaml
rename to config/default/metrics_service.yaml
diff --git a/galactic-operator/config/manager/kustomization.yaml b/config/manager/kustomization.yaml
similarity index 100%
rename from galactic-operator/config/manager/kustomization.yaml
rename to config/manager/kustomization.yaml
diff --git a/galactic-operator/config/manager/manager.yaml b/config/manager/manager.yaml
similarity index 97%
rename from galactic-operator/config/manager/manager.yaml
rename to config/manager/manager.yaml
index 3d3a7bb..5792355 100644
--- a/galactic-operator/config/manager/manager.yaml
+++ b/config/manager/manager.yaml
@@ -59,11 +59,12 @@ spec:
type: RuntimeDefault
containers:
- command:
- - /manager
+ - /galactic
+ - operator
args:
- --leader-elect
- --health-probe-bind-address=:8081
- image: controller:latest
+ image: ghcr.io/datum-cloud/galactic:latest
name: manager
ports: []
securityContext:
diff --git a/galactic-operator/config/network-policy/allow-metrics-traffic.yaml b/config/network-policy/allow-metrics-traffic.yaml
similarity index 100%
rename from galactic-operator/config/network-policy/allow-metrics-traffic.yaml
rename to config/network-policy/allow-metrics-traffic.yaml
diff --git a/galactic-operator/config/network-policy/allow-webhook-traffic.yaml b/config/network-policy/allow-webhook-traffic.yaml
similarity index 100%
rename from galactic-operator/config/network-policy/allow-webhook-traffic.yaml
rename to config/network-policy/allow-webhook-traffic.yaml
diff --git a/galactic-operator/config/network-policy/kustomization.yaml b/config/network-policy/kustomization.yaml
similarity index 100%
rename from galactic-operator/config/network-policy/kustomization.yaml
rename to config/network-policy/kustomization.yaml
diff --git a/galactic-operator/config/prometheus/kustomization.yaml b/config/prometheus/kustomization.yaml
similarity index 100%
rename from galactic-operator/config/prometheus/kustomization.yaml
rename to config/prometheus/kustomization.yaml
diff --git a/galactic-operator/config/prometheus/monitor.yaml b/config/prometheus/monitor.yaml
similarity index 100%
rename from galactic-operator/config/prometheus/monitor.yaml
rename to config/prometheus/monitor.yaml
diff --git a/galactic-operator/config/prometheus/monitor_tls_patch.yaml b/config/prometheus/monitor_tls_patch.yaml
similarity index 100%
rename from galactic-operator/config/prometheus/monitor_tls_patch.yaml
rename to config/prometheus/monitor_tls_patch.yaml
diff --git a/galactic-operator/config/rbac/kustomization.yaml b/config/rbac/kustomization.yaml
similarity index 100%
rename from galactic-operator/config/rbac/kustomization.yaml
rename to config/rbac/kustomization.yaml
diff --git a/galactic-operator/config/rbac/leader_election_role.yaml b/config/rbac/leader_election_role.yaml
similarity index 100%
rename from galactic-operator/config/rbac/leader_election_role.yaml
rename to config/rbac/leader_election_role.yaml
diff --git a/galactic-operator/config/rbac/leader_election_role_binding.yaml b/config/rbac/leader_election_role_binding.yaml
similarity index 100%
rename from galactic-operator/config/rbac/leader_election_role_binding.yaml
rename to config/rbac/leader_election_role_binding.yaml
diff --git a/galactic-operator/config/rbac/metrics_auth_role.yaml b/config/rbac/metrics_auth_role.yaml
similarity index 100%
rename from galactic-operator/config/rbac/metrics_auth_role.yaml
rename to config/rbac/metrics_auth_role.yaml
diff --git a/galactic-operator/config/rbac/metrics_auth_role_binding.yaml b/config/rbac/metrics_auth_role_binding.yaml
similarity index 100%
rename from galactic-operator/config/rbac/metrics_auth_role_binding.yaml
rename to config/rbac/metrics_auth_role_binding.yaml
diff --git a/galactic-operator/config/rbac/metrics_reader_role.yaml b/config/rbac/metrics_reader_role.yaml
similarity index 100%
rename from galactic-operator/config/rbac/metrics_reader_role.yaml
rename to config/rbac/metrics_reader_role.yaml
diff --git a/galactic-operator/config/rbac/role.yaml b/config/rbac/role.yaml
similarity index 100%
rename from galactic-operator/config/rbac/role.yaml
rename to config/rbac/role.yaml
diff --git a/galactic-operator/config/rbac/role_binding.yaml b/config/rbac/role_binding.yaml
similarity index 100%
rename from galactic-operator/config/rbac/role_binding.yaml
rename to config/rbac/role_binding.yaml
diff --git a/galactic-operator/config/rbac/service_account.yaml b/config/rbac/service_account.yaml
similarity index 100%
rename from galactic-operator/config/rbac/service_account.yaml
rename to config/rbac/service_account.yaml
diff --git a/galactic-operator/config/rbac/vpc_admin_role.yaml b/config/rbac/vpc_admin_role.yaml
similarity index 100%
rename from galactic-operator/config/rbac/vpc_admin_role.yaml
rename to config/rbac/vpc_admin_role.yaml
diff --git a/galactic-operator/config/rbac/vpc_editor_role.yaml b/config/rbac/vpc_editor_role.yaml
similarity index 100%
rename from galactic-operator/config/rbac/vpc_editor_role.yaml
rename to config/rbac/vpc_editor_role.yaml
diff --git a/galactic-operator/config/rbac/vpc_viewer_role.yaml b/config/rbac/vpc_viewer_role.yaml
similarity index 100%
rename from galactic-operator/config/rbac/vpc_viewer_role.yaml
rename to config/rbac/vpc_viewer_role.yaml
diff --git a/galactic-operator/config/rbac/vpcattachment_admin_role.yaml b/config/rbac/vpcattachment_admin_role.yaml
similarity index 100%
rename from galactic-operator/config/rbac/vpcattachment_admin_role.yaml
rename to config/rbac/vpcattachment_admin_role.yaml
diff --git a/galactic-operator/config/rbac/vpcattachment_editor_role.yaml b/config/rbac/vpcattachment_editor_role.yaml
similarity index 100%
rename from galactic-operator/config/rbac/vpcattachment_editor_role.yaml
rename to config/rbac/vpcattachment_editor_role.yaml
diff --git a/galactic-operator/config/rbac/vpcattachment_viewer_role.yaml b/config/rbac/vpcattachment_viewer_role.yaml
similarity index 100%
rename from galactic-operator/config/rbac/vpcattachment_viewer_role.yaml
rename to config/rbac/vpcattachment_viewer_role.yaml
diff --git a/galactic-operator/config/samples/galactic_v1alpha_vpc.yaml b/config/samples/galactic_v1alpha_vpc.yaml
similarity index 100%
rename from galactic-operator/config/samples/galactic_v1alpha_vpc.yaml
rename to config/samples/galactic_v1alpha_vpc.yaml
diff --git a/galactic-operator/config/samples/galactic_v1alpha_vpcattachment.yaml b/config/samples/galactic_v1alpha_vpcattachment.yaml
similarity index 100%
rename from galactic-operator/config/samples/galactic_v1alpha_vpcattachment.yaml
rename to config/samples/galactic_v1alpha_vpcattachment.yaml
diff --git a/galactic-operator/config/samples/kustomization.yaml b/config/samples/kustomization.yaml
similarity index 100%
rename from galactic-operator/config/samples/kustomization.yaml
rename to config/samples/kustomization.yaml
diff --git a/galactic-operator/config/samples/pod.yaml b/config/samples/pod.yaml
similarity index 100%
rename from galactic-operator/config/samples/pod.yaml
rename to config/samples/pod.yaml
diff --git a/galactic-operator/config/webhook/kustomization.yaml b/config/webhook/kustomization.yaml
similarity index 100%
rename from galactic-operator/config/webhook/kustomization.yaml
rename to config/webhook/kustomization.yaml
diff --git a/galactic-operator/config/webhook/kustomizeconfig.yaml b/config/webhook/kustomizeconfig.yaml
similarity index 100%
rename from galactic-operator/config/webhook/kustomizeconfig.yaml
rename to config/webhook/kustomizeconfig.yaml
diff --git a/galactic-operator/config/webhook/manifests.yaml b/config/webhook/manifests.yaml
similarity index 100%
rename from galactic-operator/config/webhook/manifests.yaml
rename to config/webhook/manifests.yaml
diff --git a/galactic-operator/config/webhook/service.yaml b/config/webhook/service.yaml
similarity index 100%
rename from galactic-operator/config/webhook/service.yaml
rename to config/webhook/service.yaml
diff --git a/galactic-agent/.github/workflows/lint.yml b/galactic-agent/.github/workflows/lint.yml
deleted file mode 100644
index 7f54b02..0000000
--- a/galactic-agent/.github/workflows/lint.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-name: Lint
-
-on:
- push:
- pull_request:
-
-jobs:
- lint:
- name: lint
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-go@v5
- with:
- go-version: stable
- - uses: golangci/golangci-lint-action@v8
diff --git a/galactic-agent/.github/workflows/publish.yml b/galactic-agent/.github/workflows/publish.yml
deleted file mode 100644
index d3a8553..0000000
--- a/galactic-agent/.github/workflows/publish.yml
+++ /dev/null
@@ -1,34 +0,0 @@
-name: Publish Docker Image
-
-on:
- # Trigger on push
- push:
- # Trigger on all pull requests
- pull_request:
- # Trigger when a release is published
- release:
- types: ['published']
-
-jobs:
- publish-container-image:
- permissions:
- id-token: write
- contents: read
- packages: write
- attestations: write
- uses: datum-cloud/actions/.github/workflows/publish-docker.yaml@v1.8.1
- with:
- image-name: galactic-agent
- platforms: "linux/amd64,linux/arm64"
- secrets: inherit
-
- publish-kustomize-bundles:
- permissions:
- id-token: write
- contents: read
- packages: write
- uses: datum-cloud/actions/.github/workflows/publish-kustomize-bundle.yaml@v1.6.5
- with:
- bundle-name: ghcr.io/datum-cloud/galactic-agent-kustomize
- bundle-path: config
- secrets: inherit
diff --git a/galactic-agent/.github/workflows/test.yml b/galactic-agent/.github/workflows/test.yml
deleted file mode 100644
index e606f10..0000000
--- a/galactic-agent/.github/workflows/test.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-name: Tests
-
-on:
- push:
- pull_request:
-
-jobs:
- test:
- name: test
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-go@v5
- with:
- go-version: stable
- - name: test
- run: |
- go test -v ./...
diff --git a/galactic-agent/.golangci.yml b/galactic-agent/.golangci.yml
deleted file mode 100644
index 366252d..0000000
--- a/galactic-agent/.golangci.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-version: "2"
-
-formatters:
- enable:
- - gofmt
diff --git a/galactic-agent/Dockerfile b/galactic-agent/Dockerfile
deleted file mode 100644
index 96460f2..0000000
--- a/galactic-agent/Dockerfile
+++ /dev/null
@@ -1,14 +0,0 @@
-FROM golang:1.24 AS builder
-WORKDIR /workspace
-COPY go.mod go.mod
-COPY go.sum go.sum
-RUN go mod download
-COPY api api
-COPY srv6 srv6
-COPY main.go main.go
-RUN CGO_ENABLED=0 go build -a -o galactic-agent main.go
-
-FROM gcr.io/distroless/static
-WORKDIR /
-COPY --from=builder /workspace/galactic-agent .
-ENTRYPOINT ["/galactic-agent"]
diff --git a/galactic-agent/LICENSE b/galactic-agent/LICENSE
deleted file mode 100644
index 0ad25db..0000000
--- a/galactic-agent/LICENSE
+++ /dev/null
@@ -1,661 +0,0 @@
- GNU AFFERO GENERAL PUBLIC LICENSE
- Version 3, 19 November 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU Affero General Public License is a free, copyleft license for
-software and other kinds of works, specifically designed to ensure
-cooperation with the community in the case of network server software.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-our General Public Licenses are intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- Developers that use our General Public Licenses protect your rights
-with two steps: (1) assert copyright on the software, and (2) offer
-you this License which gives you legal permission to copy, distribute
-and/or modify the software.
-
- A secondary benefit of defending all users' freedom is that
-improvements made in alternate versions of the program, if they
-receive widespread use, become available for other developers to
-incorporate. Many developers of free software are heartened and
-encouraged by the resulting cooperation. However, in the case of
-software used on network servers, this result may fail to come about.
-The GNU General Public License permits making a modified version and
-letting the public access it on a server without ever releasing its
-source code to the public.
-
- The GNU Affero General Public License is designed specifically to
-ensure that, in such cases, the modified source code becomes available
-to the community. It requires the operator of a network server to
-provide the source code of the modified version running there to the
-users of that server. Therefore, public use of a modified version, on
-a publicly accessible server, gives the public access to the source
-code of the modified version.
-
- An older license, called the Affero General Public License and
-published by Affero, was designed to accomplish similar goals. This is
-a different license, not a version of the Affero GPL, but Affero has
-released a new version of the Affero GPL which permits relicensing under
-this license.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU Affero General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Remote Network Interaction; Use with the GNU General Public License.
-
- Notwithstanding any other provision of this License, if you modify the
-Program, your modified version must prominently offer all users
-interacting with it remotely through a computer network (if your version
-supports such interaction) an opportunity to receive the Corresponding
-Source of your version by providing access to the Corresponding Source
-from a network server at no charge, through some standard or customary
-means of facilitating copying of software. This Corresponding Source
-shall include the Corresponding Source for any work covered by version 3
-of the GNU General Public License that is incorporated pursuant to the
-following paragraph.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the work with which it is combined will remain governed by version
-3 of the GNU General Public License.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU Affero General Public License from time to time. Such new versions
-will be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU Affero General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU Affero General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU Affero General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-
- Copyright (C)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
-
-Also add information on how to contact you by electronic and paper mail.
-
- If your software can interact with users remotely through a computer
-network, you should also make sure that it provides a way for users to
-get its source. For example, if your program is a web application, its
-interface could display a "Source" link that leads users to an archive
-of the code. There are many ways you could offer source, and different
-solutions will be better for different programs; see section 13 for the
-specific requirements.
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU AGPL, see
-.
diff --git a/galactic-agent/README.md b/galactic-agent/README.md
deleted file mode 100644
index ffbb99d..0000000
--- a/galactic-agent/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# galactic-agent
-
-Documentation lives here: http://datum.net/docs/galactic-vpc/#galactic-agent
diff --git a/galactic-agent/api/local/local.proto b/galactic-agent/api/local/local.proto
deleted file mode 100644
index b45fb42..0000000
--- a/galactic-agent/api/local/local.proto
+++ /dev/null
@@ -1,29 +0,0 @@
-syntax = "proto3";
-
-package local.v1;
-option go_package = "github.com/datum-cloud/galactic-agent/api/local;local";
-
-service Local {
- rpc Register(RegisterRequest) returns (RegisterReply);
- rpc Deregister(DeregisterRequest) returns (DeregisterReply);
-}
-
-message RegisterRequest {
- string vpc = 1;
- string vpcattachment = 2;
- repeated string networks = 3;
-}
-
-message RegisterReply {
- bool confirmed = 1;
-}
-
-message DeregisterRequest {
- string vpc = 1;
- string vpcattachment = 2;
- repeated string networks = 3;
-}
-
-message DeregisterReply {
- bool confirmed = 1;
-}
diff --git a/galactic-agent/api/local/local_grpc.pb.go b/galactic-agent/api/local/local_grpc.pb.go
deleted file mode 100644
index ec0612d..0000000
--- a/galactic-agent/api/local/local_grpc.pb.go
+++ /dev/null
@@ -1,159 +0,0 @@
-// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
-// versions:
-// - protoc-gen-go-grpc v1.5.1
-// - protoc v3.21.12
-// source: local.proto
-
-package local
-
-import (
- context "context"
- grpc "google.golang.org/grpc"
- codes "google.golang.org/grpc/codes"
- status "google.golang.org/grpc/status"
-)
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the grpc package it is being compiled against.
-// Requires gRPC-Go v1.64.0 or later.
-const _ = grpc.SupportPackageIsVersion9
-
-const (
- Local_Register_FullMethodName = "/local.v1.Local/Register"
- Local_Deregister_FullMethodName = "/local.v1.Local/Deregister"
-)
-
-// LocalClient is the client API for Local service.
-//
-// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
-type LocalClient interface {
- Register(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (*RegisterReply, error)
- Deregister(ctx context.Context, in *DeregisterRequest, opts ...grpc.CallOption) (*DeregisterReply, error)
-}
-
-type localClient struct {
- cc grpc.ClientConnInterface
-}
-
-func NewLocalClient(cc grpc.ClientConnInterface) LocalClient {
- return &localClient{cc}
-}
-
-func (c *localClient) Register(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (*RegisterReply, error) {
- cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
- out := new(RegisterReply)
- err := c.cc.Invoke(ctx, Local_Register_FullMethodName, in, out, cOpts...)
- if err != nil {
- return nil, err
- }
- return out, nil
-}
-
-func (c *localClient) Deregister(ctx context.Context, in *DeregisterRequest, opts ...grpc.CallOption) (*DeregisterReply, error) {
- cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
- out := new(DeregisterReply)
- err := c.cc.Invoke(ctx, Local_Deregister_FullMethodName, in, out, cOpts...)
- if err != nil {
- return nil, err
- }
- return out, nil
-}
-
-// LocalServer is the server API for Local service.
-// All implementations must embed UnimplementedLocalServer
-// for forward compatibility.
-type LocalServer interface {
- Register(context.Context, *RegisterRequest) (*RegisterReply, error)
- Deregister(context.Context, *DeregisterRequest) (*DeregisterReply, error)
- mustEmbedUnimplementedLocalServer()
-}
-
-// UnimplementedLocalServer must be embedded to have
-// forward compatible implementations.
-//
-// NOTE: this should be embedded by value instead of pointer to avoid a nil
-// pointer dereference when methods are called.
-type UnimplementedLocalServer struct{}
-
-func (UnimplementedLocalServer) Register(context.Context, *RegisterRequest) (*RegisterReply, error) {
- return nil, status.Errorf(codes.Unimplemented, "method Register not implemented")
-}
-func (UnimplementedLocalServer) Deregister(context.Context, *DeregisterRequest) (*DeregisterReply, error) {
- return nil, status.Errorf(codes.Unimplemented, "method Deregister not implemented")
-}
-func (UnimplementedLocalServer) mustEmbedUnimplementedLocalServer() {}
-func (UnimplementedLocalServer) testEmbeddedByValue() {}
-
-// UnsafeLocalServer may be embedded to opt out of forward compatibility for this service.
-// Use of this interface is not recommended, as added methods to LocalServer will
-// result in compilation errors.
-type UnsafeLocalServer interface {
- mustEmbedUnimplementedLocalServer()
-}
-
-func RegisterLocalServer(s grpc.ServiceRegistrar, srv LocalServer) {
- // If the following call pancis, it indicates UnimplementedLocalServer was
- // embedded by pointer and is nil. This will cause panics if an
- // unimplemented method is ever invoked, so we test this at initialization
- // time to prevent it from happening at runtime later due to I/O.
- if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
- t.testEmbeddedByValue()
- }
- s.RegisterService(&Local_ServiceDesc, srv)
-}
-
-func _Local_Register_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
- in := new(RegisterRequest)
- if err := dec(in); err != nil {
- return nil, err
- }
- if interceptor == nil {
- return srv.(LocalServer).Register(ctx, in)
- }
- info := &grpc.UnaryServerInfo{
- Server: srv,
- FullMethod: Local_Register_FullMethodName,
- }
- handler := func(ctx context.Context, req interface{}) (interface{}, error) {
- return srv.(LocalServer).Register(ctx, req.(*RegisterRequest))
- }
- return interceptor(ctx, in, info, handler)
-}
-
-func _Local_Deregister_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
- in := new(DeregisterRequest)
- if err := dec(in); err != nil {
- return nil, err
- }
- if interceptor == nil {
- return srv.(LocalServer).Deregister(ctx, in)
- }
- info := &grpc.UnaryServerInfo{
- Server: srv,
- FullMethod: Local_Deregister_FullMethodName,
- }
- handler := func(ctx context.Context, req interface{}) (interface{}, error) {
- return srv.(LocalServer).Deregister(ctx, req.(*DeregisterRequest))
- }
- return interceptor(ctx, in, info, handler)
-}
-
-// Local_ServiceDesc is the grpc.ServiceDesc for Local service.
-// It's only intended for direct use with grpc.RegisterService,
-// and not to be introspected or modified (even as a copy)
-var Local_ServiceDesc = grpc.ServiceDesc{
- ServiceName: "local.v1.Local",
- HandlerType: (*LocalServer)(nil),
- Methods: []grpc.MethodDesc{
- {
- MethodName: "Register",
- Handler: _Local_Register_Handler,
- },
- {
- MethodName: "Deregister",
- Handler: _Local_Deregister_Handler,
- },
- },
- Streams: []grpc.StreamDesc{},
- Metadata: "local.proto",
-}
diff --git a/galactic-agent/api/remote/remote.proto b/galactic-agent/api/remote/remote.proto
deleted file mode 100644
index 87ad223..0000000
--- a/galactic-agent/api/remote/remote.proto
+++ /dev/null
@@ -1,34 +0,0 @@
-syntax = "proto3";
-
-package remote.v1;
-option go_package = "github.com/datum-cloud/galactic-agent/api/remote;remote";
-
-message Envelope {
- oneof kind {
- Register register = 1;
- Deregister deregister = 2;
- Route route = 3;
- }
-}
-
-message Register {
- string network = 1;
- string srv6_endpoint = 2;
-}
-
-message Deregister {
- string network = 1;
- string srv6_endpoint = 2;
-}
-
-message Route {
- enum Status {
- ADD = 0;
- DELETE = 1;
- }
-
- string network = 1;
- string srv6_endpoint = 2;
- repeated string srv6_segments = 3;
- Status status = 4;
-}
diff --git a/galactic-agent/generate.sh b/galactic-agent/generate.sh
deleted file mode 100644
index 98b4df0..0000000
--- a/galactic-agent/generate.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/bash
-# Requirements:
-# - apt install protobuf-compiler
-# - go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
-# - go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
-find api -type f -name '*.proto' |while read file; do
- dir=$(dirname ${file})
- grep -q rpc ${file}
- if [ $? -eq 0 ]; then
- echo "Generate gRPC ${file}"
- protoc -I ${dir} \
- --go_out=${dir} \
- --go_opt=paths=source_relative \
- --go-grpc_out=${dir} \
- --go-grpc_opt=paths=source_relative \
- ${file}
- else
- echo "Generate protobuf ${file}"
- protoc -I ${dir} \
- --go_out=${dir} \
- --go_opt=paths=source_relative \
- ${file}
- fi
-done
diff --git a/galactic-agent/go.mod b/galactic-agent/go.mod
deleted file mode 100644
index cf3ae3c..0000000
--- a/galactic-agent/go.mod
+++ /dev/null
@@ -1,44 +0,0 @@
-module github.com/datum-cloud/galactic-agent
-
-go 1.24.9
-
-require (
- github.com/datum-cloud/galactic-common v0.0.0-20251029014339-7062fa2334ff
- github.com/eclipse/paho.mqtt.golang v1.5.0
- github.com/spf13/cobra v1.9.1
- github.com/spf13/viper v1.20.1
- github.com/vishvananda/netlink v1.3.2-0.20250622222046-78aca1ace529
- golang.org/x/sync v0.14.0
- google.golang.org/grpc v1.74.2
- google.golang.org/protobuf v1.36.6
-)
-
-require (
- github.com/BurntSushi/toml v1.1.0 // indirect
- github.com/fsnotify/fsnotify v1.8.0 // indirect
- github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
- github.com/gorilla/websocket v1.5.3 // indirect
- github.com/inconshreveable/mousetrap v1.1.0 // indirect
- github.com/kenshaw/baseconv v0.1.1 // indirect
- github.com/lorenzosaino/go-sysctl v0.3.1 // indirect
- github.com/pelletier/go-toml/v2 v2.2.3 // indirect
- github.com/sagikazarmark/locafero v0.7.0 // indirect
- github.com/sourcegraph/conc v0.3.0 // indirect
- github.com/spf13/afero v1.12.0 // indirect
- github.com/spf13/cast v1.7.1 // indirect
- github.com/spf13/pflag v1.0.6 // indirect
- github.com/subosito/gotenv v1.6.0 // indirect
- github.com/vishvananda/netns v0.0.5 // indirect
- go.uber.org/atomic v1.9.0 // indirect
- go.uber.org/multierr v1.9.0 // indirect
- golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d // indirect
- golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
- golang.org/x/mod v0.24.0 // indirect
- golang.org/x/net v0.40.0 // indirect
- golang.org/x/sys v0.33.0 // indirect
- golang.org/x/text v0.25.0 // indirect
- golang.org/x/tools v0.31.0 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect
- gopkg.in/yaml.v3 v3.0.1 // indirect
- honnef.co/go/tools v0.3.2 // indirect
-)
diff --git a/galactic-agent/go.sum b/galactic-agent/go.sum
deleted file mode 100644
index e5b60d8..0000000
--- a/galactic-agent/go.sum
+++ /dev/null
@@ -1,127 +0,0 @@
-github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
-github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
-github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
-github.com/datum-cloud/galactic-common v0.0.0-20251029014339-7062fa2334ff h1:u7c253QSnmIFwhaEZsqqNi5HQ61XKTf91bQ+9WhF4dM=
-github.com/datum-cloud/galactic-common v0.0.0-20251029014339-7062fa2334ff/go.mod h1:gXCoJaHM1Yy8au9VdKNbKJBGIKbqcPdfKvd9lQ9UNyM=
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
-github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/eclipse/paho.mqtt.golang v1.5.0 h1:EH+bUVJNgttidWFkLLVKaQPGmkTUfQQqjOsyvMGvD6o=
-github.com/eclipse/paho.mqtt.golang v1.5.0/go.mod h1:du/2qNQVqJf/Sqs4MEL77kR8QTqANF7XU7Fk0aOTAgk=
-github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
-github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
-github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
-github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
-github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
-github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
-github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
-github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
-github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
-github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
-github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
-github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
-github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
-github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
-github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
-github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
-github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
-github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
-github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
-github.com/kenshaw/baseconv v0.1.1 h1:oAu/C7ipUT2PqT9DT0mZDGDg4URIglizZMjPv9oCu0E=
-github.com/kenshaw/baseconv v0.1.1/go.mod h1:yy9zGmnnR6vgOxOQb702nVdAG30JhyYZpj/5/m0siRI=
-github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
-github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
-github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
-github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
-github.com/lorenzosaino/go-sysctl v0.3.1 h1:3phX80tdITw2fJjZlwbXQnDWs4S30beNcMbw0cn0HtY=
-github.com/lorenzosaino/go-sysctl v0.3.1/go.mod h1:5grcsBRpspKknNS1qzt1eIeRDLrhpKZAtz8Fcuvs1Rc=
-github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
-github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
-github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
-github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo=
-github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k=
-github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
-github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
-github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs=
-github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=
-github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
-github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
-github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
-github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
-github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
-github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4=
-github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4=
-github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
-github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
-github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
-github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
-github.com/vishvananda/netlink v1.3.2-0.20250622222046-78aca1ace529 h1:uMzwac/F73FD0zIGmLA1nqLkVFmbN1s34FFAqX5+jVU=
-github.com/vishvananda/netlink v1.3.2-0.20250622222046-78aca1ace529/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5JS/XMVl45+b4=
-github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY=
-github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
-go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
-go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
-go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
-go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
-go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
-go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
-go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=
-go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=
-go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis=
-go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=
-go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
-go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
-go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
-go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
-go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
-go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d h1:+W8Qf4iJtMGKkyAygcKohjxTk4JPsL9DpzApJ22m5Ic=
-golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
-golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
-golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
-golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
-golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
-golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
-golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
-golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
-golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
-golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
-golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
-google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4=
-google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM=
-google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
-google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
-gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
-gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-honnef.co/go/tools v0.3.2 h1:ytYb4rOqyp1TSa2EPvNVwtPQJctSELKaMyLfqNP4+34=
-honnef.co/go/tools v0.3.2/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw=
diff --git a/galactic-agent/main.go b/galactic-agent/main.go
deleted file mode 100644
index 9726b12..0000000
--- a/galactic-agent/main.go
+++ /dev/null
@@ -1,167 +0,0 @@
-package main
-
-import (
- "context"
- "log"
- "os"
- "os/signal"
- "syscall"
-
- "golang.org/x/sync/errgroup"
-
- "github.com/spf13/cobra"
- "github.com/spf13/viper"
-
- "google.golang.org/protobuf/proto"
-
- "github.com/datum-cloud/galactic-agent/api/local"
- "github.com/datum-cloud/galactic-agent/api/remote"
- "github.com/datum-cloud/galactic-agent/srv6"
- "github.com/datum-cloud/galactic-common/util"
-)
-
-var configFile string
-
-func initConfig() {
- viper.SetDefault("srv6_net", "fc00::/56")
- viper.SetDefault("socket_path", "/var/run/galactic/agent.sock")
- viper.SetDefault("mqtt_url", "tcp://mqtt:1883")
- viper.SetDefault("mqtt_qos", 1)
- viper.SetDefault("mqtt_topic_receive", "galactic/default/receive")
- viper.SetDefault("mqtt_topic_send", "galactic/default/send")
- if configFile != "" {
- viper.SetConfigFile(configFile)
- }
- viper.AutomaticEnv()
- if err := viper.ReadInConfig(); err == nil {
- log.Printf("Using config file: %s\n", viper.ConfigFileUsed())
- } else {
- log.Printf("No config file found - using defaults.")
- }
-}
-
-var (
- l local.Local
- r remote.Remote
-)
-
-func main() {
- cmd := &cobra.Command{
- Use: "galactic-agent",
- Short: "Galactic Agent",
- PersistentPreRun: func(cmd *cobra.Command, args []string) {
- initConfig()
- },
- Run: func(cmd *cobra.Command, args []string) {
- ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
- defer stop() //nolint:errcheck
-
- _, err := util.EncodeSRv6Endpoint(viper.GetString("srv6_net"), "ffffffffffff", "ffff")
- if err != nil {
- log.Fatalf("srv6_endpoint invalid: %v", err)
- }
-
- l = local.Local{
- SocketPath: viper.GetString("socket_path"),
- RegisterHandler: func(vpc, vpcAttachment string, networks []string) error {
- srv6_endpoint, err := util.EncodeSRv6Endpoint(viper.GetString("srv6_net"), vpc, vpcAttachment)
- if err != nil {
- return err
- }
- if err := srv6.RouteIngressAdd(srv6_endpoint); err != nil {
- return err
- }
- for _, n := range networks {
- log.Printf("REGISTER: network='%s', srv6_endpoint='%s'", n, srv6_endpoint)
- payload, err := proto.Marshal(&remote.Envelope{
- Kind: &remote.Envelope_Register{
- Register: &remote.Register{
- Network: n,
- Srv6Endpoint: srv6_endpoint,
- },
- },
- })
- if err != nil {
- return err
- }
- r.Send(payload)
- }
- return nil
- },
- DeregisterHandler: func(vpc, vpcAttachment string, networks []string) error {
- srv6_endpoint, err := util.EncodeSRv6Endpoint(viper.GetString("srv6_net"), vpc, vpcAttachment)
- if err != nil {
- return err
- }
- if err := srv6.RouteIngressDel(srv6_endpoint); err != nil {
- return err
- }
- for _, n := range networks {
- log.Printf("DEREGISTER: network='%s', srv6_endpoint='%s'", n, srv6_endpoint)
- payload, err := proto.Marshal(&remote.Envelope{
- Kind: &remote.Envelope_Deregister{
- Deregister: &remote.Deregister{
- Network: n,
- Srv6Endpoint: srv6_endpoint,
- },
- },
- })
- if err != nil {
- return err
- }
- r.Send(payload)
- }
- return nil
- },
- }
-
- r = remote.Remote{
- URL: viper.GetString("mqtt_url"),
- ClientID: viper.GetString("mqtt_clientid"),
- Username: viper.GetString("mqtt_username"),
- Password: viper.GetString("mqtt_password"),
- QoS: byte(viper.GetInt("mqtt_qos")),
- TopicRX: viper.GetString("mqtt_topic_receive"),
- TopicTX: viper.GetString("mqtt_topic_send"),
- ReceiveHandler: func(payload []byte) error {
- envelope := &remote.Envelope{}
- if err := proto.Unmarshal(payload, envelope); err != nil {
- return err
- }
- switch kind := envelope.Kind.(type) {
- case *remote.Envelope_Route:
- log.Printf("ROUTE: status='%s', network='%s', srv6_endpoint='%s', srv6_segments='%s'", kind.Route.Status, kind.Route.Network, kind.Route.Srv6Endpoint, kind.Route.Srv6Segments)
- switch kind.Route.Status {
- case remote.Route_ADD:
- if err := srv6.RouteEgressAdd(kind.Route.Network, kind.Route.Srv6Endpoint, kind.Route.Srv6Segments); err != nil {
- return err
- }
- case remote.Route_DELETE:
- if err := srv6.RouteEgressDel(kind.Route.Network, kind.Route.Srv6Endpoint, kind.Route.Srv6Segments); err != nil {
- return err
- }
- }
- }
- return nil
- },
- }
-
- g, ctx := errgroup.WithContext(ctx)
- g.Go(func() error {
- return l.Serve(ctx)
- })
- g.Go(func() error {
- return r.Run(ctx)
- })
- if err := g.Wait(); err != nil {
- log.Printf("Error: %v", err)
- }
- log.Printf("Shutdown")
- },
- }
- cmd.PersistentFlags().StringVar(&configFile, "config", "", "config file")
- cmd.SetArgs(os.Args[1:])
- if err := cmd.Execute(); err != nil {
- log.Fatalf("Execution failed: %v", err)
- }
-}
diff --git a/galactic-agent/srv6/neighborproxy/neighborproxy.go b/galactic-agent/srv6/neighborproxy/neighborproxy.go
deleted file mode 100644
index 6c35ad5..0000000
--- a/galactic-agent/srv6/neighborproxy/neighborproxy.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package neighborproxy
-
-import (
- "net"
-
- "github.com/vishvananda/netlink"
-
- "github.com/datum-cloud/galactic-common/util"
-)
-
-func Add(ipnet *net.IPNet, vpc, vpcAttachment string) error {
- dev := util.GenerateInterfaceNameHost(vpc, vpcAttachment)
- link, err := netlink.LinkByName(dev)
- if err != nil {
- return err
- }
-
- neigh := &netlink.Neigh{
- LinkIndex: link.Attrs().Index,
- IP: ipnet.IP,
- State: netlink.NUD_PERMANENT,
- Flags: netlink.NTF_PROXY,
- }
-
- return netlink.NeighAdd(neigh)
-}
-
-func Delete(ipnet *net.IPNet, vpc, vpcAttachment string) error {
- dev := util.GenerateInterfaceNameHost(vpc, vpcAttachment)
- link, err := netlink.LinkByName(dev)
- if err != nil {
- return err
- }
-
- neigh := &netlink.Neigh{
- LinkIndex: link.Attrs().Index,
- IP: ipnet.IP,
- State: netlink.NUD_PERMANENT,
- Flags: netlink.NTF_PROXY,
- }
-
- return netlink.NeighDel(neigh)
-}
diff --git a/galactic-agent/srv6/routeegress/routeegress.go b/galactic-agent/srv6/routeegress/routeegress.go
deleted file mode 100644
index 80ec67a..0000000
--- a/galactic-agent/srv6/routeegress/routeegress.go
+++ /dev/null
@@ -1,55 +0,0 @@
-package routeegress
-
-import (
- "net"
-
- "github.com/vishvananda/netlink"
- "github.com/vishvananda/netlink/nl"
-
- "github.com/datum-cloud/galactic-common/vrf"
-)
-
-const LoopbackDevice = "lo-galactic"
-
-func Add(vpc, vpcAttachment string, prefix *net.IPNet, segments []net.IP) error {
- link, err := netlink.LinkByName(LoopbackDevice)
- if err != nil {
- return err
- }
-
- vrfId, err := vrf.GetVRFIdForVPC(vpc, vpcAttachment)
- if err != nil {
- return err
- }
-
- encap := &netlink.SEG6Encap{
- Mode: nl.SEG6_IPTUN_MODE_ENCAP,
- Segments: segments,
- }
- route := &netlink.Route{
- Dst: prefix,
- Table: int(vrfId),
- LinkIndex: link.Attrs().Index,
- Encap: encap,
- }
- return netlink.RouteReplace(route)
-}
-
-func Delete(vpc, vpcAttachment string, prefix *net.IPNet, segments []net.IP) error {
- link, err := netlink.LinkByName(LoopbackDevice)
- if err != nil {
- return err
- }
-
- vrfId, err := vrf.GetVRFIdForVPC(vpc, vpcAttachment)
- if err != nil {
- return err
- }
-
- route := &netlink.Route{
- Dst: prefix,
- Table: int(vrfId),
- LinkIndex: link.Attrs().Index,
- }
- return netlink.RouteDel(route)
-}
diff --git a/galactic-agent/srv6/srv6.go b/galactic-agent/srv6/srv6.go
deleted file mode 100644
index 6b6cecf..0000000
--- a/galactic-agent/srv6/srv6.go
+++ /dev/null
@@ -1,145 +0,0 @@
-package srv6
-
-import (
- "errors"
- "fmt"
-
- "github.com/vishvananda/netlink"
-
- "github.com/datum-cloud/galactic-agent/srv6/neighborproxy"
- "github.com/datum-cloud/galactic-agent/srv6/routeegress"
- "github.com/datum-cloud/galactic-agent/srv6/routeingress"
- "github.com/datum-cloud/galactic-common/util"
-)
-
-func RouteIngressAdd(ipStr string) error {
- ip, err := util.ParseIP(ipStr)
- if err != nil {
- return fmt.Errorf("invalid ip: %w", err)
- }
- vpc, vpcAttachment, err := util.DecodeSRv6Endpoint(ip)
- if err != nil {
- return fmt.Errorf("could not extract SRv6 endpoint: %w", err)
- }
- vpc, err = util.HexToBase62(vpc)
- if err != nil {
- return fmt.Errorf("invalid vpc: %w", err)
- }
- vpcAttachment, err = util.HexToBase62(vpcAttachment)
- if err != nil {
- return fmt.Errorf("invalid vpcattachment: %w", err)
- }
-
- if err := routeingress.Add(netlink.NewIPNet(ip), vpc, vpcAttachment); err != nil {
- return fmt.Errorf("routeingress add failed: %w", err)
- }
- return nil
-}
-
-func RouteIngressDel(ipStr string) error {
- ip, err := util.ParseIP(ipStr)
- if err != nil {
- return fmt.Errorf("invalid ip: %w", err)
- }
- vpc, vpcAttachment, err := util.DecodeSRv6Endpoint(ip)
- if err != nil {
- return fmt.Errorf("could not extract SRv6 endpoint: %w", err)
- }
- vpc, err = util.HexToBase62(vpc)
- if err != nil {
- return fmt.Errorf("invalid vpc: %w", err)
- }
- vpcAttachment, err = util.HexToBase62(vpcAttachment)
- if err != nil {
- return fmt.Errorf("invalid vpcattachment: %w", err)
- }
-
- if err := routeingress.Delete(netlink.NewIPNet(ip), vpc, vpcAttachment); err != nil {
- return fmt.Errorf("routeingress delete failed: %w", err)
- }
- return nil
-}
-
-func RouteEgressAdd(prefixStr, srcStr string, segmentsStr []string) error {
- prefix, err := netlink.ParseIPNet(prefixStr)
- if err != nil {
- return fmt.Errorf("invalid prefix: %w", err)
- }
- src, err := util.ParseIP(srcStr)
- if err != nil {
- return fmt.Errorf("invalid src: %w", err)
- }
- segments, err := util.ParseSegments(segmentsStr)
- if err != nil {
- return fmt.Errorf("invalid segments: %w", err)
- }
-
- vpc, vpcAttachment, err := util.DecodeSRv6Endpoint(src)
- if err != nil {
- return fmt.Errorf("could not extract SRv6 endpoint: %w", err)
- }
- vpc, err = util.HexToBase62(vpc)
- if err != nil {
- return fmt.Errorf("invalid vpc: %w", err)
- }
- vpcAttachment, err = util.HexToBase62(vpcAttachment)
- if err != nil {
- return fmt.Errorf("invalid vpcattachment: %w", err)
- }
-
- var errs []error
- if util.IsHost(prefix) {
- if err := neighborproxy.Add(prefix, vpc, vpcAttachment); err != nil {
- errs = append(errs, fmt.Errorf("neighborproxy add failed: %w", err))
- }
- }
- if err := routeegress.Add(vpc, vpcAttachment, prefix, segments); err != nil {
- errs = append(errs, fmt.Errorf("routeegress add failed: %w", err))
- }
- if len(errs) > 0 {
- return errors.Join(errs...)
- }
- return nil
-}
-
-func RouteEgressDel(prefixStr, srcStr string, segmentsStr []string) error {
- prefix, err := netlink.ParseIPNet(prefixStr)
- if err != nil {
- return fmt.Errorf("invalid prefix: %w", err)
- }
- src, err := util.ParseIP(srcStr)
- if err != nil {
- return fmt.Errorf("invalid src: %w", err)
- }
- segments, err := util.ParseSegments(segmentsStr)
- if err != nil {
- return fmt.Errorf("invalid segments: %w", err)
- }
-
- vpc, vpcAttachment, err := util.DecodeSRv6Endpoint(src)
- if err != nil {
- return fmt.Errorf("could not extract SRv6 endpoint: %w", err)
- }
- vpc, err = util.HexToBase62(vpc)
- if err != nil {
- return fmt.Errorf("invalid vpc: %w", err)
- }
- vpcAttachment, err = util.HexToBase62(vpcAttachment)
- if err != nil {
- return fmt.Errorf("invalid vpcattachment: %w", err)
- }
-
- var errs []error
- if util.IsHost(prefix) {
- if err := neighborproxy.Delete(prefix, vpc, vpcAttachment); err != nil {
- errs = append(errs, fmt.Errorf("neighborproxy delete failed: %w", err))
- }
- }
- if err := routeegress.Delete(vpc, vpcAttachment, prefix, segments); err != nil {
- errs = append(errs, fmt.Errorf("routeegress delete failed: %w", err))
- }
- if len(errs) > 0 {
- return errors.Join(errs...)
- }
- return nil
-}
diff --git a/galactic-cni/.github/workflows/build.yml b/galactic-cni/.github/workflows/build.yml
deleted file mode 100644
index 71bfb4a..0000000
--- a/galactic-cni/.github/workflows/build.yml
+++ /dev/null
@@ -1,59 +0,0 @@
-name: build
-on:
- pull_request:
- push:
- branches:
- - main
- workflow_call:
-
-permissions:
- contents: read
- pull-requests: read
-
-jobs:
- lint:
- name: lint
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-go@v5
- with:
- go-version: stable
- - uses: golangci/golangci-lint-action@v8
-
- build:
- name: build
- needs: lint
- runs-on: ubuntu-latest
- strategy:
- matrix:
- arch:
- - amd64
- - arm64
- env:
- DEBUG_VERSION: ${{ github.ref_name }}
- DEBUG_REF: ${{ github.sha }}
- steps:
- - uses: actions/checkout@v4
- - uses: docker/setup-qemu-action@v3
- - uses: docker/setup-buildx-action@v3
- - name: test
- run: |
- docker run -v ${{ github.workspace }}:/src -w /src \
- --platform linux/${{ matrix.arch }} \
- golang \
- go test -v ./...
- - name: build
- run: |
- docker run -v ${{ github.workspace }}:/src -w /src \
- --platform linux/${{ matrix.arch }} \
- -e CGO_ENABLED=0 \
- golang \
- go build \
- -ldflags "-X 'github.com/datum-cloud/galactic-cni/debug.DebugVersion=${DEBUG_VERSION}' -X 'github.com/datum-cloud/galactic-cni/debug.DebugRef=${DEBUG_REF}'" \
- -o galactic-${{ matrix.arch }} ./main.go
- - name: upload
- uses: actions/upload-artifact@v4
- with:
- name: galactic-${{ matrix.arch }}
- path: galactic-${{ matrix.arch }}
diff --git a/galactic-cni/.github/workflows/release.yml b/galactic-cni/.github/workflows/release.yml
deleted file mode 100644
index d4737ca..0000000
--- a/galactic-cni/.github/workflows/release.yml
+++ /dev/null
@@ -1,41 +0,0 @@
-name: release
-
-on:
- push:
- tags:
- - "v*"
-
-permissions:
- contents: write
- id-token: write
- pull-requests: read
-
-jobs:
- build:
- uses: ./.github/workflows/build.yml
-
- release:
- needs: build
- runs-on: ubuntu-latest
- steps:
- - name: "download galactic-amd64"
- uses: actions/download-artifact@v4
- with:
- name: galactic-amd64
- - name: "download galactic-arm64"
- uses: actions/download-artifact@v4
- with:
- name: galactic-arm64
- - name: package
- run: |
- mkdir package
- for arch in amd64 arm64; do
- cp galactic-${arch} package/galactic_${arch}
- done
- - name: release
- uses: softprops/action-gh-release@v2
- with:
- draft: true
- generate_release_notes: true
- files: |
- package/*
diff --git a/galactic-cni/.golangci.yml b/galactic-cni/.golangci.yml
deleted file mode 100644
index 366252d..0000000
--- a/galactic-cni/.golangci.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-version: "2"
-
-formatters:
- enable:
- - gofmt
diff --git a/galactic-cni/README.md b/galactic-cni/README.md
deleted file mode 100644
index 1516b05..0000000
--- a/galactic-cni/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# galactic-cni
-
-Documentation lives here: http://datum.net/docs/galactic-vpc/#galactic-cni
diff --git a/galactic-cni/go.mod b/galactic-cni/go.mod
deleted file mode 100644
index 05a82f6..0000000
--- a/galactic-cni/go.mod
+++ /dev/null
@@ -1,35 +0,0 @@
-module github.com/datum-cloud/galactic-cni
-
-go 1.24.9
-
-require (
- github.com/containernetworking/cni v1.3.0
- github.com/coreos/go-iptables v0.8.0
- github.com/datum-cloud/galactic-agent v0.0.4-0.20251029015057-6e532d8afdf9
- github.com/datum-cloud/galactic-common v0.0.0-20251029014339-7062fa2334ff
- github.com/spf13/cobra v1.9.1
- github.com/vishvananda/netlink v1.3.2-0.20250622222046-78aca1ace529
- golang.org/x/sys v0.33.0
- google.golang.org/grpc v1.74.2
-)
-
-require (
- github.com/BurntSushi/toml v1.1.0 // indirect
- github.com/inconshreveable/mousetrap v1.1.0 // indirect
- github.com/kenshaw/baseconv v0.1.1 // indirect
- github.com/lorenzosaino/go-sysctl v0.3.1 // indirect
- github.com/onsi/ginkgo/v2 v2.23.4 // indirect
- github.com/onsi/gomega v1.37.0 // indirect
- github.com/spf13/pflag v1.0.6 // indirect
- github.com/vishvananda/netns v0.0.5 // indirect
- golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d // indirect
- golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
- golang.org/x/mod v0.24.0 // indirect
- golang.org/x/net v0.40.0 // indirect
- golang.org/x/sync v0.14.0 // indirect
- golang.org/x/text v0.25.0 // indirect
- golang.org/x/tools v0.31.0 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect
- google.golang.org/protobuf v1.36.6 // indirect
- honnef.co/go/tools v0.3.2 // indirect
-)
diff --git a/galactic-cni/go.sum b/galactic-cni/go.sum
deleted file mode 100644
index 4384f81..0000000
--- a/galactic-cni/go.sum
+++ /dev/null
@@ -1,98 +0,0 @@
-github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
-github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
-github.com/containernetworking/cni v1.3.0 h1:v6EpN8RznAZj9765HhXQrtXgX+ECGebEYEmnuFjskwo=
-github.com/containernetworking/cni v1.3.0/go.mod h1:Bs8glZjjFfGPHMw6hQu82RUgEPNGEaBb9KS5KtNMnJ4=
-github.com/coreos/go-iptables v0.8.0 h1:MPc2P89IhuVpLI7ETL/2tx3XZ61VeICZjYqDEgNsPRc=
-github.com/coreos/go-iptables v0.8.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
-github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
-github.com/datum-cloud/galactic-agent v0.0.4-0.20251029015057-6e532d8afdf9 h1:SxaD3my4wW16UEVJE7QTWsW3uaENt/4Snll6Kbpa/UA=
-github.com/datum-cloud/galactic-agent v0.0.4-0.20251029015057-6e532d8afdf9/go.mod h1:SUYiFowJqZm5g1OrdOjDYkPK7iB1OaUN9sQV94VyAVk=
-github.com/datum-cloud/galactic-common v0.0.0-20251029014339-7062fa2334ff h1:u7c253QSnmIFwhaEZsqqNi5HQ61XKTf91bQ+9WhF4dM=
-github.com/datum-cloud/galactic-common v0.0.0-20251029014339-7062fa2334ff/go.mod h1:gXCoJaHM1Yy8au9VdKNbKJBGIKbqcPdfKvd9lQ9UNyM=
-github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
-github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
-github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
-github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
-github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
-github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
-github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
-github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
-github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
-github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
-github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=
-github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
-github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
-github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
-github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
-github.com/kenshaw/baseconv v0.1.1 h1:oAu/C7ipUT2PqT9DT0mZDGDg4URIglizZMjPv9oCu0E=
-github.com/kenshaw/baseconv v0.1.1/go.mod h1:yy9zGmnnR6vgOxOQb702nVdAG30JhyYZpj/5/m0siRI=
-github.com/lorenzosaino/go-sysctl v0.3.1 h1:3phX80tdITw2fJjZlwbXQnDWs4S30beNcMbw0cn0HtY=
-github.com/lorenzosaino/go-sysctl v0.3.1/go.mod h1:5grcsBRpspKknNS1qzt1eIeRDLrhpKZAtz8Fcuvs1Rc=
-github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
-github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
-github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y=
-github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
-github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
-github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
-github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
-github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-github.com/vishvananda/netlink v1.3.2-0.20250622222046-78aca1ace529 h1:uMzwac/F73FD0zIGmLA1nqLkVFmbN1s34FFAqX5+jVU=
-github.com/vishvananda/netlink v1.3.2-0.20250622222046-78aca1ace529/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5JS/XMVl45+b4=
-github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY=
-github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
-go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
-go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
-go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
-go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
-go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
-go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
-go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=
-go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=
-go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis=
-go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=
-go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
-go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
-go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
-go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d h1:+W8Qf4iJtMGKkyAygcKohjxTk4JPsL9DpzApJ22m5Ic=
-golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
-golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
-golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
-golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
-golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
-golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
-golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
-golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
-golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
-golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
-golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
-google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4=
-google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM=
-google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
-google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
-gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-honnef.co/go/tools v0.3.2 h1:ytYb4rOqyp1TSa2EPvNVwtPQJctSELKaMyLfqNP4+34=
-honnef.co/go/tools v0.3.2/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw=
diff --git a/galactic-cni/main.go b/galactic-cni/main.go
deleted file mode 100644
index 87f86bc..0000000
--- a/galactic-cni/main.go
+++ /dev/null
@@ -1,32 +0,0 @@
-package main
-
-import (
- "fmt"
- "log"
- "os"
-
- "github.com/spf13/cobra"
-
- "github.com/datum-cloud/galactic-cni/cni"
- "github.com/datum-cloud/galactic-cni/debug"
-)
-
-func main() {
- args := os.Args[1:]
-
- cmd := cni.NewCommand()
-
- versionCmd := &cobra.Command{
- Use: "version",
- Short: "Print version details",
- Run: func(cmd *cobra.Command, args []string) {
- fmt.Println(debug.Version())
- },
- }
- cmd.AddCommand(versionCmd)
-
- cmd.SetArgs(args)
- if err := cmd.Execute(); err != nil {
- log.Fatalf("Execution failed: %v", err)
- }
-}
diff --git a/galactic-common/.github/workflows/build.yml b/galactic-common/.github/workflows/build.yml
deleted file mode 100644
index 2ffea78..0000000
--- a/galactic-common/.github/workflows/build.yml
+++ /dev/null
@@ -1,42 +0,0 @@
-name: build
-on:
- pull_request:
- push:
- branches:
- - main
- workflow_call:
-
-permissions:
- contents: read
- pull-requests: read
-
-jobs:
- lint:
- name: lint
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-go@v5
- with:
- go-version: stable
- - uses: golangci/golangci-lint-action@v8
-
- build:
- name: build
- needs: lint
- runs-on: ubuntu-latest
- strategy:
- matrix:
- arch:
- - amd64
- - arm64
- steps:
- - uses: actions/checkout@v4
- - uses: docker/setup-qemu-action@v3
- - uses: docker/setup-buildx-action@v3
- - name: test
- run: |
- docker run -v ${{ github.workspace }}:/src -w /src \
- --platform linux/${{ matrix.arch }} \
- golang \
- go test -v ./...
diff --git a/galactic-common/LICENSE b/galactic-common/LICENSE
deleted file mode 100644
index 0ad25db..0000000
--- a/galactic-common/LICENSE
+++ /dev/null
@@ -1,661 +0,0 @@
- GNU AFFERO GENERAL PUBLIC LICENSE
- Version 3, 19 November 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU Affero General Public License is a free, copyleft license for
-software and other kinds of works, specifically designed to ensure
-cooperation with the community in the case of network server software.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-our General Public Licenses are intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- Developers that use our General Public Licenses protect your rights
-with two steps: (1) assert copyright on the software, and (2) offer
-you this License which gives you legal permission to copy, distribute
-and/or modify the software.
-
- A secondary benefit of defending all users' freedom is that
-improvements made in alternate versions of the program, if they
-receive widespread use, become available for other developers to
-incorporate. Many developers of free software are heartened and
-encouraged by the resulting cooperation. However, in the case of
-software used on network servers, this result may fail to come about.
-The GNU General Public License permits making a modified version and
-letting the public access it on a server without ever releasing its
-source code to the public.
-
- The GNU Affero General Public License is designed specifically to
-ensure that, in such cases, the modified source code becomes available
-to the community. It requires the operator of a network server to
-provide the source code of the modified version running there to the
-users of that server. Therefore, public use of a modified version, on
-a publicly accessible server, gives the public access to the source
-code of the modified version.
-
- An older license, called the Affero General Public License and
-published by Affero, was designed to accomplish similar goals. This is
-a different license, not a version of the Affero GPL, but Affero has
-released a new version of the Affero GPL which permits relicensing under
-this license.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU Affero General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Remote Network Interaction; Use with the GNU General Public License.
-
- Notwithstanding any other provision of this License, if you modify the
-Program, your modified version must prominently offer all users
-interacting with it remotely through a computer network (if your version
-supports such interaction) an opportunity to receive the Corresponding
-Source of your version by providing access to the Corresponding Source
-from a network server at no charge, through some standard or customary
-means of facilitating copying of software. This Corresponding Source
-shall include the Corresponding Source for any work covered by version 3
-of the GNU General Public License that is incorporated pursuant to the
-following paragraph.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the work with which it is combined will remain governed by version
-3 of the GNU General Public License.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU Affero General Public License from time to time. Such new versions
-will be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU Affero General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU Affero General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU Affero General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-
- Copyright (C)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
-
-Also add information on how to contact you by electronic and paper mail.
-
- If your software can interact with users remotely through a computer
-network, you should also make sure that it provides a way for users to
-get its source. For example, if your program is a web application, its
-interface could display a "Source" link that leads users to an archive
-of the code. There are many ways you could offer source, and different
-solutions will be better for different programs; see section 13 for the
-specific requirements.
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU AGPL, see
-.
diff --git a/galactic-common/go.mod b/galactic-common/go.mod
deleted file mode 100644
index ee9d6dc..0000000
--- a/galactic-common/go.mod
+++ /dev/null
@@ -1,20 +0,0 @@
-module github.com/datum-cloud/galactic-common
-
-go 1.24.9
-
-require (
- github.com/kenshaw/baseconv v0.1.1
- github.com/lorenzosaino/go-sysctl v0.3.1
- github.com/vishvananda/netlink v1.3.1
-)
-
-require (
- github.com/BurntSushi/toml v1.1.0 // indirect
- github.com/vishvananda/netns v0.0.5 // indirect
- golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d // indirect
- golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
- golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
- golang.org/x/sys v0.10.0 // indirect
- golang.org/x/tools v0.1.11 // indirect
- honnef.co/go/tools v0.3.2 // indirect
-)
diff --git a/galactic-common/go.sum b/galactic-common/go.sum
deleted file mode 100644
index 89f86ec..0000000
--- a/galactic-common/go.sum
+++ /dev/null
@@ -1,36 +0,0 @@
-github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
-github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
-github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
-github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/kenshaw/baseconv v0.1.1 h1:oAu/C7ipUT2PqT9DT0mZDGDg4URIglizZMjPv9oCu0E=
-github.com/kenshaw/baseconv v0.1.1/go.mod h1:yy9zGmnnR6vgOxOQb702nVdAG30JhyYZpj/5/m0siRI=
-github.com/lorenzosaino/go-sysctl v0.3.1 h1:3phX80tdITw2fJjZlwbXQnDWs4S30beNcMbw0cn0HtY=
-github.com/lorenzosaino/go-sysctl v0.3.1/go.mod h1:5grcsBRpspKknNS1qzt1eIeRDLrhpKZAtz8Fcuvs1Rc=
-github.com/vishvananda/netlink v1.3.1 h1:3AEMt62VKqz90r0tmNhog0r/PpWKmrEShJU0wJW6bV0=
-github.com/vishvananda/netlink v1.3.1/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5JS/XMVl45+b4=
-github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY=
-github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d h1:+W8Qf4iJtMGKkyAygcKohjxTk4JPsL9DpzApJ22m5Ic=
-golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
-golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
-golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
-golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.1.11 h1:loJ25fNOEhSXfHrpoGj91eCUThwdNX6u24rO1xnNteY=
-golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
-golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-honnef.co/go/tools v0.3.2 h1:ytYb4rOqyp1TSa2EPvNVwtPQJctSELKaMyLfqNP4+34=
-honnef.co/go/tools v0.3.2/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw=
diff --git a/galactic-lab/.devcontainer/devcontainer.json b/galactic-lab/.devcontainer/devcontainer.json
deleted file mode 100644
index eaa59d4..0000000
--- a/galactic-lab/.devcontainer/devcontainer.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "name": "galactic-lab",
- "build": {
- "dockerfile": "../Dockerfile"
- },
- "remoteUser": "vscode",
- "features": {
- "ghcr.io/devcontainers/features/docker-in-docker:2": {
- "version": "latest",
- "enableNonRootDocker": "true"
- }
- }
-}
diff --git a/galactic-lab/LICENSE b/galactic-lab/LICENSE
deleted file mode 100644
index bae94e1..0000000
--- a/galactic-lab/LICENSE
+++ /dev/null
@@ -1,661 +0,0 @@
- GNU AFFERO GENERAL PUBLIC LICENSE
- Version 3, 19 November 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU Affero General Public License is a free, copyleft license for
-software and other kinds of works, specifically designed to ensure
-cooperation with the community in the case of network server software.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-our General Public Licenses are intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- Developers that use our General Public Licenses protect your rights
-with two steps: (1) assert copyright on the software, and (2) offer
-you this License which gives you legal permission to copy, distribute
-and/or modify the software.
-
- A secondary benefit of defending all users' freedom is that
-improvements made in alternate versions of the program, if they
-receive widespread use, become available for other developers to
-incorporate. Many developers of free software are heartened and
-encouraged by the resulting cooperation. However, in the case of
-software used on network servers, this result may fail to come about.
-The GNU General Public License permits making a modified version and
-letting the public access it on a server without ever releasing its
-source code to the public.
-
- The GNU Affero General Public License is designed specifically to
-ensure that, in such cases, the modified source code becomes available
-to the community. It requires the operator of a network server to
-provide the source code of the modified version running there to the
-users of that server. Therefore, public use of a modified version, on
-a publicly accessible server, gives the public access to the source
-code of the modified version.
-
- An older license, called the Affero General Public License and
-published by Affero, was designed to accomplish similar goals. This is
-a different license, not a version of the Affero GPL, but Affero has
-released a new version of the Affero GPL which permits relicensing under
-this license.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU Affero General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Remote Network Interaction; Use with the GNU General Public License.
-
- Notwithstanding any other provision of this License, if you modify the
-Program, your modified version must prominently offer all users
-interacting with it remotely through a computer network (if your version
-supports such interaction) an opportunity to receive the Corresponding
-Source of your version by providing access to the Corresponding Source
-from a network server at no charge, through some standard or customary
-means of facilitating copying of software. This Corresponding Source
-shall include the Corresponding Source for any work covered by version 3
-of the GNU General Public License that is incorporated pursuant to the
-following paragraph.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the work with which it is combined will remain governed by version
-3 of the GNU General Public License.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU Affero General Public License from time to time. Such new versions
-will be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU Affero General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU Affero General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU Affero General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-
- Copyright (C)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
-
-Also add information on how to contact you by electronic and paper mail.
-
- If your software can interact with users remotely through a computer
-network, you should also make sure that it provides a way for users to
-get its source. For example, if your program is a web application, its
-interface could display a "Source" link that leads users to an archive
-of the code. There are many ways you could offer source, and different
-solutions will be better for different programs; see section 13 for the
-specific requirements.
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU AGPL, see
-.
\ No newline at end of file
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/lint.yml b/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/lint.yml
deleted file mode 100644
index 7f54b02..0000000
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/lint.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-name: Lint
-
-on:
- push:
- pull_request:
-
-jobs:
- lint:
- name: lint
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-go@v5
- with:
- go-version: stable
- - uses: golangci/golangci-lint-action@v8
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/publish.yml b/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/publish.yml
deleted file mode 100644
index d3a8553..0000000
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/publish.yml
+++ /dev/null
@@ -1,34 +0,0 @@
-name: Publish Docker Image
-
-on:
- # Trigger on push
- push:
- # Trigger on all pull requests
- pull_request:
- # Trigger when a release is published
- release:
- types: ['published']
-
-jobs:
- publish-container-image:
- permissions:
- id-token: write
- contents: read
- packages: write
- attestations: write
- uses: datum-cloud/actions/.github/workflows/publish-docker.yaml@v1.8.1
- with:
- image-name: galactic-agent
- platforms: "linux/amd64,linux/arm64"
- secrets: inherit
-
- publish-kustomize-bundles:
- permissions:
- id-token: write
- contents: read
- packages: write
- uses: datum-cloud/actions/.github/workflows/publish-kustomize-bundle.yaml@v1.6.5
- with:
- bundle-name: ghcr.io/datum-cloud/galactic-agent-kustomize
- bundle-path: config
- secrets: inherit
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/test.yml b/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/test.yml
deleted file mode 100644
index e606f10..0000000
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/test.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-name: Tests
-
-on:
- push:
- pull_request:
-
-jobs:
- test:
- name: test
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-go@v5
- with:
- go-version: stable
- - name: test
- run: |
- go test -v ./...
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.golangci.yml b/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.golangci.yml
deleted file mode 100644
index 366252d..0000000
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.golangci.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-version: "2"
-
-formatters:
- enable:
- - gofmt
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/Dockerfile b/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/Dockerfile
deleted file mode 100644
index 96460f2..0000000
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/Dockerfile
+++ /dev/null
@@ -1,14 +0,0 @@
-FROM golang:1.24 AS builder
-WORKDIR /workspace
-COPY go.mod go.mod
-COPY go.sum go.sum
-RUN go mod download
-COPY api api
-COPY srv6 srv6
-COPY main.go main.go
-RUN CGO_ENABLED=0 go build -a -o galactic-agent main.go
-
-FROM gcr.io/distroless/static
-WORKDIR /
-COPY --from=builder /workspace/galactic-agent .
-ENTRYPOINT ["/galactic-agent"]
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/LICENSE b/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/LICENSE
deleted file mode 100644
index 0ad25db..0000000
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/LICENSE
+++ /dev/null
@@ -1,661 +0,0 @@
- GNU AFFERO GENERAL PUBLIC LICENSE
- Version 3, 19 November 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU Affero General Public License is a free, copyleft license for
-software and other kinds of works, specifically designed to ensure
-cooperation with the community in the case of network server software.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-our General Public Licenses are intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- Developers that use our General Public Licenses protect your rights
-with two steps: (1) assert copyright on the software, and (2) offer
-you this License which gives you legal permission to copy, distribute
-and/or modify the software.
-
- A secondary benefit of defending all users' freedom is that
-improvements made in alternate versions of the program, if they
-receive widespread use, become available for other developers to
-incorporate. Many developers of free software are heartened and
-encouraged by the resulting cooperation. However, in the case of
-software used on network servers, this result may fail to come about.
-The GNU General Public License permits making a modified version and
-letting the public access it on a server without ever releasing its
-source code to the public.
-
- The GNU Affero General Public License is designed specifically to
-ensure that, in such cases, the modified source code becomes available
-to the community. It requires the operator of a network server to
-provide the source code of the modified version running there to the
-users of that server. Therefore, public use of a modified version, on
-a publicly accessible server, gives the public access to the source
-code of the modified version.
-
- An older license, called the Affero General Public License and
-published by Affero, was designed to accomplish similar goals. This is
-a different license, not a version of the Affero GPL, but Affero has
-released a new version of the Affero GPL which permits relicensing under
-this license.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU Affero General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Remote Network Interaction; Use with the GNU General Public License.
-
- Notwithstanding any other provision of this License, if you modify the
-Program, your modified version must prominently offer all users
-interacting with it remotely through a computer network (if your version
-supports such interaction) an opportunity to receive the Corresponding
-Source of your version by providing access to the Corresponding Source
-from a network server at no charge, through some standard or customary
-means of facilitating copying of software. This Corresponding Source
-shall include the Corresponding Source for any work covered by version 3
-of the GNU General Public License that is incorporated pursuant to the
-following paragraph.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the work with which it is combined will remain governed by version
-3 of the GNU General Public License.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU Affero General Public License from time to time. Such new versions
-will be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU Affero General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU Affero General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU Affero General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-
- Copyright (C)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
-
-Also add information on how to contact you by electronic and paper mail.
-
- If your software can interact with users remotely through a computer
-network, you should also make sure that it provides a way for users to
-get its source. For example, if your program is a web application, its
-interface could display a "Source" link that leads users to an archive
-of the code. There are many ways you could offer source, and different
-solutions will be better for different programs; see section 13 for the
-specific requirements.
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU AGPL, see
-.
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/README.md b/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/README.md
deleted file mode 100644
index ffbb99d..0000000
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# galactic-agent
-
-Documentation lives here: http://datum.net/docs/galactic-vpc/#galactic-agent
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.go b/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.go
deleted file mode 100644
index b718373..0000000
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.go
+++ /dev/null
@@ -1,66 +0,0 @@
-package local
-
-import (
- "context"
- "log"
- "net"
- "os"
-
- "google.golang.org/grpc"
- "google.golang.org/grpc/reflection"
-)
-
-type Local struct {
- UnimplementedLocalServer
- SocketPath string
- RegisterHandler func(string, string, []string) error
- DeregisterHandler func(string, string, []string) error
-}
-
-func (l *Local) Register(ctx context.Context, req *RegisterRequest) (*RegisterReply, error) {
- if err := l.RegisterHandler(req.GetVpc(), req.GetVpcattachment(), req.GetNetworks()); err != nil {
- return nil, err
- }
- return &RegisterReply{Confirmed: true}, nil
-}
-
-func (l *Local) Deregister(ctx context.Context, req *DeregisterRequest) (*DeregisterReply, error) {
- if err := l.DeregisterHandler(req.GetVpc(), req.GetVpcattachment(), req.GetNetworks()); err != nil {
- return nil, err
- }
- return &DeregisterReply{Confirmed: true}, nil
-}
-
-func (l *Local) Serve(ctx context.Context) error {
- // unix socket should be unlinked if it exists first
- // see: https://github.com/golang/go/issues/70985
- err := os.Remove(l.SocketPath)
- if err != nil && !os.IsNotExist(err) {
- return err
- }
- listener, err := net.Listen("unix", l.SocketPath)
- if err != nil {
- return err
- }
- defer listener.Close() //nolint:errcheck
-
- s := grpc.NewServer()
- RegisterLocalServer(s, l)
-
- reflection.Register(s)
-
- routineErr := make(chan error, 1)
- go func() {
- log.Printf("gRPC listening: unix://%s", l.SocketPath)
- if err := s.Serve(listener); err != nil {
- routineErr <- err
- return
- }
- routineErr <- nil
- }()
-
- <-ctx.Done()
- s.Stop()
- log.Println("gRPC stopped")
- return <-routineErr
-}
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.pb.go b/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.pb.go
deleted file mode 100644
index a6fc035..0000000
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.pb.go
+++ /dev/null
@@ -1,307 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// versions:
-// protoc-gen-go v1.36.7
-// protoc v3.21.12
-// source: local.proto
-
-package local
-
-import (
- protoreflect "google.golang.org/protobuf/reflect/protoreflect"
- protoimpl "google.golang.org/protobuf/runtime/protoimpl"
- reflect "reflect"
- sync "sync"
- unsafe "unsafe"
-)
-
-const (
- // Verify that this generated code is sufficiently up-to-date.
- _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
- // Verify that runtime/protoimpl is sufficiently up-to-date.
- _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
-)
-
-type RegisterRequest struct {
- state protoimpl.MessageState `protogen:"open.v1"`
- Vpc string `protobuf:"bytes,1,opt,name=vpc,proto3" json:"vpc,omitempty"`
- Vpcattachment string `protobuf:"bytes,2,opt,name=vpcattachment,proto3" json:"vpcattachment,omitempty"`
- Networks []string `protobuf:"bytes,3,rep,name=networks,proto3" json:"networks,omitempty"`
- unknownFields protoimpl.UnknownFields
- sizeCache protoimpl.SizeCache
-}
-
-func (x *RegisterRequest) Reset() {
- *x = RegisterRequest{}
- mi := &file_local_proto_msgTypes[0]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
-}
-
-func (x *RegisterRequest) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*RegisterRequest) ProtoMessage() {}
-
-func (x *RegisterRequest) ProtoReflect() protoreflect.Message {
- mi := &file_local_proto_msgTypes[0]
- if x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use RegisterRequest.ProtoReflect.Descriptor instead.
-func (*RegisterRequest) Descriptor() ([]byte, []int) {
- return file_local_proto_rawDescGZIP(), []int{0}
-}
-
-func (x *RegisterRequest) GetVpc() string {
- if x != nil {
- return x.Vpc
- }
- return ""
-}
-
-func (x *RegisterRequest) GetVpcattachment() string {
- if x != nil {
- return x.Vpcattachment
- }
- return ""
-}
-
-func (x *RegisterRequest) GetNetworks() []string {
- if x != nil {
- return x.Networks
- }
- return nil
-}
-
-type RegisterReply struct {
- state protoimpl.MessageState `protogen:"open.v1"`
- Confirmed bool `protobuf:"varint,1,opt,name=confirmed,proto3" json:"confirmed,omitempty"`
- unknownFields protoimpl.UnknownFields
- sizeCache protoimpl.SizeCache
-}
-
-func (x *RegisterReply) Reset() {
- *x = RegisterReply{}
- mi := &file_local_proto_msgTypes[1]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
-}
-
-func (x *RegisterReply) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*RegisterReply) ProtoMessage() {}
-
-func (x *RegisterReply) ProtoReflect() protoreflect.Message {
- mi := &file_local_proto_msgTypes[1]
- if x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use RegisterReply.ProtoReflect.Descriptor instead.
-func (*RegisterReply) Descriptor() ([]byte, []int) {
- return file_local_proto_rawDescGZIP(), []int{1}
-}
-
-func (x *RegisterReply) GetConfirmed() bool {
- if x != nil {
- return x.Confirmed
- }
- return false
-}
-
-type DeregisterRequest struct {
- state protoimpl.MessageState `protogen:"open.v1"`
- Vpc string `protobuf:"bytes,1,opt,name=vpc,proto3" json:"vpc,omitempty"`
- Vpcattachment string `protobuf:"bytes,2,opt,name=vpcattachment,proto3" json:"vpcattachment,omitempty"`
- Networks []string `protobuf:"bytes,3,rep,name=networks,proto3" json:"networks,omitempty"`
- unknownFields protoimpl.UnknownFields
- sizeCache protoimpl.SizeCache
-}
-
-func (x *DeregisterRequest) Reset() {
- *x = DeregisterRequest{}
- mi := &file_local_proto_msgTypes[2]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
-}
-
-func (x *DeregisterRequest) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*DeregisterRequest) ProtoMessage() {}
-
-func (x *DeregisterRequest) ProtoReflect() protoreflect.Message {
- mi := &file_local_proto_msgTypes[2]
- if x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use DeregisterRequest.ProtoReflect.Descriptor instead.
-func (*DeregisterRequest) Descriptor() ([]byte, []int) {
- return file_local_proto_rawDescGZIP(), []int{2}
-}
-
-func (x *DeregisterRequest) GetVpc() string {
- if x != nil {
- return x.Vpc
- }
- return ""
-}
-
-func (x *DeregisterRequest) GetVpcattachment() string {
- if x != nil {
- return x.Vpcattachment
- }
- return ""
-}
-
-func (x *DeregisterRequest) GetNetworks() []string {
- if x != nil {
- return x.Networks
- }
- return nil
-}
-
-type DeregisterReply struct {
- state protoimpl.MessageState `protogen:"open.v1"`
- Confirmed bool `protobuf:"varint,1,opt,name=confirmed,proto3" json:"confirmed,omitempty"`
- unknownFields protoimpl.UnknownFields
- sizeCache protoimpl.SizeCache
-}
-
-func (x *DeregisterReply) Reset() {
- *x = DeregisterReply{}
- mi := &file_local_proto_msgTypes[3]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
-}
-
-func (x *DeregisterReply) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*DeregisterReply) ProtoMessage() {}
-
-func (x *DeregisterReply) ProtoReflect() protoreflect.Message {
- mi := &file_local_proto_msgTypes[3]
- if x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use DeregisterReply.ProtoReflect.Descriptor instead.
-func (*DeregisterReply) Descriptor() ([]byte, []int) {
- return file_local_proto_rawDescGZIP(), []int{3}
-}
-
-func (x *DeregisterReply) GetConfirmed() bool {
- if x != nil {
- return x.Confirmed
- }
- return false
-}
-
-var File_local_proto protoreflect.FileDescriptor
-
-const file_local_proto_rawDesc = "" +
- "\n" +
- "\vlocal.proto\x12\blocal.v1\"e\n" +
- "\x0fRegisterRequest\x12\x10\n" +
- "\x03vpc\x18\x01 \x01(\tR\x03vpc\x12$\n" +
- "\rvpcattachment\x18\x02 \x01(\tR\rvpcattachment\x12\x1a\n" +
- "\bnetworks\x18\x03 \x03(\tR\bnetworks\"-\n" +
- "\rRegisterReply\x12\x1c\n" +
- "\tconfirmed\x18\x01 \x01(\bR\tconfirmed\"g\n" +
- "\x11DeregisterRequest\x12\x10\n" +
- "\x03vpc\x18\x01 \x01(\tR\x03vpc\x12$\n" +
- "\rvpcattachment\x18\x02 \x01(\tR\rvpcattachment\x12\x1a\n" +
- "\bnetworks\x18\x03 \x03(\tR\bnetworks\"/\n" +
- "\x0fDeregisterReply\x12\x1c\n" +
- "\tconfirmed\x18\x01 \x01(\bR\tconfirmed2\x8d\x01\n" +
- "\x05Local\x12>\n" +
- "\bRegister\x12\x19.local.v1.RegisterRequest\x1a\x17.local.v1.RegisterReply\x12D\n" +
- "\n" +
- "Deregister\x12\x1b.local.v1.DeregisterRequest\x1a\x19.local.v1.DeregisterReplyB7Z5github.com/datum-cloud/galactic-agent/api/local;localb\x06proto3"
-
-var (
- file_local_proto_rawDescOnce sync.Once
- file_local_proto_rawDescData []byte
-)
-
-func file_local_proto_rawDescGZIP() []byte {
- file_local_proto_rawDescOnce.Do(func() {
- file_local_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_local_proto_rawDesc), len(file_local_proto_rawDesc)))
- })
- return file_local_proto_rawDescData
-}
-
-var file_local_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
-var file_local_proto_goTypes = []any{
- (*RegisterRequest)(nil), // 0: local.v1.RegisterRequest
- (*RegisterReply)(nil), // 1: local.v1.RegisterReply
- (*DeregisterRequest)(nil), // 2: local.v1.DeregisterRequest
- (*DeregisterReply)(nil), // 3: local.v1.DeregisterReply
-}
-var file_local_proto_depIdxs = []int32{
- 0, // 0: local.v1.Local.Register:input_type -> local.v1.RegisterRequest
- 2, // 1: local.v1.Local.Deregister:input_type -> local.v1.DeregisterRequest
- 1, // 2: local.v1.Local.Register:output_type -> local.v1.RegisterReply
- 3, // 3: local.v1.Local.Deregister:output_type -> local.v1.DeregisterReply
- 2, // [2:4] is the sub-list for method output_type
- 0, // [0:2] is the sub-list for method input_type
- 0, // [0:0] is the sub-list for extension type_name
- 0, // [0:0] is the sub-list for extension extendee
- 0, // [0:0] is the sub-list for field type_name
-}
-
-func init() { file_local_proto_init() }
-func file_local_proto_init() {
- if File_local_proto != nil {
- return
- }
- type x struct{}
- out := protoimpl.TypeBuilder{
- File: protoimpl.DescBuilder{
- GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
- RawDescriptor: unsafe.Slice(unsafe.StringData(file_local_proto_rawDesc), len(file_local_proto_rawDesc)),
- NumEnums: 0,
- NumMessages: 4,
- NumExtensions: 0,
- NumServices: 1,
- },
- GoTypes: file_local_proto_goTypes,
- DependencyIndexes: file_local_proto_depIdxs,
- MessageInfos: file_local_proto_msgTypes,
- }.Build()
- File_local_proto = out.File
- file_local_proto_goTypes = nil
- file_local_proto_depIdxs = nil
-}
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.go b/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.go
deleted file mode 100644
index 775c55f..0000000
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.go
+++ /dev/null
@@ -1,76 +0,0 @@
-package remote
-
-import (
- "context"
- "log"
- "time"
-
- mqtt "github.com/eclipse/paho.mqtt.golang"
-)
-
-type Remote struct {
- URL string
- ClientID string
- Username string
- Password string
- QoS byte
- TopicRX string
- TopicTX string
- ReceiveHandler func([]byte) error
-
- client mqtt.Client
-}
-
-func (r *Remote) Run(ctx context.Context) error {
- log.Printf("MQTT connecting")
-
- opts := mqtt.NewClientOptions().
- AddBroker(r.URL)
- if r.ClientID != "" {
- opts.SetClientID(r.ClientID)
- }
- if r.Username != "" {
- opts.SetUsername(r.Username)
- }
- if r.Password != "" {
- opts.SetPassword(r.Password)
- }
- opts.SetCleanSession(r.ClientID == "" || r.QoS == 0)
-
- opts.OnConnect = func(c mqtt.Client) {
- log.Println("MQTT connected")
- token := c.Subscribe(
- r.TopicRX,
- r.QoS,
- func(_ mqtt.Client, msg mqtt.Message) {
- payload := msg.Payload()
- if err := r.ReceiveHandler(payload); err != nil {
- log.Printf("MQTT ReceiveHandler failed: %v", err)
- }
- },
- )
- if !token.WaitTimeout(5*time.Second) || token.Error() != nil {
- log.Printf("MQTT subscribe error: %v", token.Error())
- return
- }
- log.Printf("MQTT subscribed: %s", r.TopicRX)
- }
-
- r.client = mqtt.NewClient(opts)
- if tok := r.client.Connect(); tok.Wait() && tok.Error() != nil {
- return tok.Error()
- }
-
- <-ctx.Done()
- if r.client.IsConnected() {
- r.client.Disconnect(250)
- }
- log.Println("MQTT disconnected")
-
- return nil
-}
-
-func (r *Remote) Send(payload interface{}) {
- token := r.client.Publish(r.TopicTX, r.QoS, false, payload)
- token.Wait()
-}
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.pb.go b/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.pb.go
deleted file mode 100644
index edcce0d..0000000
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.pb.go
+++ /dev/null
@@ -1,430 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// versions:
-// protoc-gen-go v1.36.7
-// protoc v3.21.12
-// source: remote.proto
-
-package remote
-
-import (
- protoreflect "google.golang.org/protobuf/reflect/protoreflect"
- protoimpl "google.golang.org/protobuf/runtime/protoimpl"
- reflect "reflect"
- sync "sync"
- unsafe "unsafe"
-)
-
-const (
- // Verify that this generated code is sufficiently up-to-date.
- _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
- // Verify that runtime/protoimpl is sufficiently up-to-date.
- _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
-)
-
-type Route_Status int32
-
-const (
- Route_ADD Route_Status = 0
- Route_DELETE Route_Status = 1
-)
-
-// Enum value maps for Route_Status.
-var (
- Route_Status_name = map[int32]string{
- 0: "ADD",
- 1: "DELETE",
- }
- Route_Status_value = map[string]int32{
- "ADD": 0,
- "DELETE": 1,
- }
-)
-
-func (x Route_Status) Enum() *Route_Status {
- p := new(Route_Status)
- *p = x
- return p
-}
-
-func (x Route_Status) String() string {
- return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
-}
-
-func (Route_Status) Descriptor() protoreflect.EnumDescriptor {
- return file_remote_proto_enumTypes[0].Descriptor()
-}
-
-func (Route_Status) Type() protoreflect.EnumType {
- return &file_remote_proto_enumTypes[0]
-}
-
-func (x Route_Status) Number() protoreflect.EnumNumber {
- return protoreflect.EnumNumber(x)
-}
-
-// Deprecated: Use Route_Status.Descriptor instead.
-func (Route_Status) EnumDescriptor() ([]byte, []int) {
- return file_remote_proto_rawDescGZIP(), []int{3, 0}
-}
-
-type Envelope struct {
- state protoimpl.MessageState `protogen:"open.v1"`
- // Types that are valid to be assigned to Kind:
- //
- // *Envelope_Register
- // *Envelope_Deregister
- // *Envelope_Route
- Kind isEnvelope_Kind `protobuf_oneof:"kind"`
- unknownFields protoimpl.UnknownFields
- sizeCache protoimpl.SizeCache
-}
-
-func (x *Envelope) Reset() {
- *x = Envelope{}
- mi := &file_remote_proto_msgTypes[0]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
-}
-
-func (x *Envelope) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*Envelope) ProtoMessage() {}
-
-func (x *Envelope) ProtoReflect() protoreflect.Message {
- mi := &file_remote_proto_msgTypes[0]
- if x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use Envelope.ProtoReflect.Descriptor instead.
-func (*Envelope) Descriptor() ([]byte, []int) {
- return file_remote_proto_rawDescGZIP(), []int{0}
-}
-
-func (x *Envelope) GetKind() isEnvelope_Kind {
- if x != nil {
- return x.Kind
- }
- return nil
-}
-
-func (x *Envelope) GetRegister() *Register {
- if x != nil {
- if x, ok := x.Kind.(*Envelope_Register); ok {
- return x.Register
- }
- }
- return nil
-}
-
-func (x *Envelope) GetDeregister() *Deregister {
- if x != nil {
- if x, ok := x.Kind.(*Envelope_Deregister); ok {
- return x.Deregister
- }
- }
- return nil
-}
-
-func (x *Envelope) GetRoute() *Route {
- if x != nil {
- if x, ok := x.Kind.(*Envelope_Route); ok {
- return x.Route
- }
- }
- return nil
-}
-
-type isEnvelope_Kind interface {
- isEnvelope_Kind()
-}
-
-type Envelope_Register struct {
- Register *Register `protobuf:"bytes,1,opt,name=register,proto3,oneof"`
-}
-
-type Envelope_Deregister struct {
- Deregister *Deregister `protobuf:"bytes,2,opt,name=deregister,proto3,oneof"`
-}
-
-type Envelope_Route struct {
- Route *Route `protobuf:"bytes,3,opt,name=route,proto3,oneof"`
-}
-
-func (*Envelope_Register) isEnvelope_Kind() {}
-
-func (*Envelope_Deregister) isEnvelope_Kind() {}
-
-func (*Envelope_Route) isEnvelope_Kind() {}
-
-type Register struct {
- state protoimpl.MessageState `protogen:"open.v1"`
- Network string `protobuf:"bytes,1,opt,name=network,proto3" json:"network,omitempty"`
- Srv6Endpoint string `protobuf:"bytes,2,opt,name=srv6_endpoint,json=srv6Endpoint,proto3" json:"srv6_endpoint,omitempty"`
- unknownFields protoimpl.UnknownFields
- sizeCache protoimpl.SizeCache
-}
-
-func (x *Register) Reset() {
- *x = Register{}
- mi := &file_remote_proto_msgTypes[1]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
-}
-
-func (x *Register) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*Register) ProtoMessage() {}
-
-func (x *Register) ProtoReflect() protoreflect.Message {
- mi := &file_remote_proto_msgTypes[1]
- if x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use Register.ProtoReflect.Descriptor instead.
-func (*Register) Descriptor() ([]byte, []int) {
- return file_remote_proto_rawDescGZIP(), []int{1}
-}
-
-func (x *Register) GetNetwork() string {
- if x != nil {
- return x.Network
- }
- return ""
-}
-
-func (x *Register) GetSrv6Endpoint() string {
- if x != nil {
- return x.Srv6Endpoint
- }
- return ""
-}
-
-type Deregister struct {
- state protoimpl.MessageState `protogen:"open.v1"`
- Network string `protobuf:"bytes,1,opt,name=network,proto3" json:"network,omitempty"`
- Srv6Endpoint string `protobuf:"bytes,2,opt,name=srv6_endpoint,json=srv6Endpoint,proto3" json:"srv6_endpoint,omitempty"`
- unknownFields protoimpl.UnknownFields
- sizeCache protoimpl.SizeCache
-}
-
-func (x *Deregister) Reset() {
- *x = Deregister{}
- mi := &file_remote_proto_msgTypes[2]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
-}
-
-func (x *Deregister) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*Deregister) ProtoMessage() {}
-
-func (x *Deregister) ProtoReflect() protoreflect.Message {
- mi := &file_remote_proto_msgTypes[2]
- if x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use Deregister.ProtoReflect.Descriptor instead.
-func (*Deregister) Descriptor() ([]byte, []int) {
- return file_remote_proto_rawDescGZIP(), []int{2}
-}
-
-func (x *Deregister) GetNetwork() string {
- if x != nil {
- return x.Network
- }
- return ""
-}
-
-func (x *Deregister) GetSrv6Endpoint() string {
- if x != nil {
- return x.Srv6Endpoint
- }
- return ""
-}
-
-type Route struct {
- state protoimpl.MessageState `protogen:"open.v1"`
- Network string `protobuf:"bytes,1,opt,name=network,proto3" json:"network,omitempty"`
- Srv6Endpoint string `protobuf:"bytes,2,opt,name=srv6_endpoint,json=srv6Endpoint,proto3" json:"srv6_endpoint,omitempty"`
- Srv6Segments []string `protobuf:"bytes,3,rep,name=srv6_segments,json=srv6Segments,proto3" json:"srv6_segments,omitempty"`
- Status Route_Status `protobuf:"varint,4,opt,name=status,proto3,enum=remote.v1.Route_Status" json:"status,omitempty"`
- unknownFields protoimpl.UnknownFields
- sizeCache protoimpl.SizeCache
-}
-
-func (x *Route) Reset() {
- *x = Route{}
- mi := &file_remote_proto_msgTypes[3]
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- ms.StoreMessageInfo(mi)
-}
-
-func (x *Route) String() string {
- return protoimpl.X.MessageStringOf(x)
-}
-
-func (*Route) ProtoMessage() {}
-
-func (x *Route) ProtoReflect() protoreflect.Message {
- mi := &file_remote_proto_msgTypes[3]
- if x != nil {
- ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
- if ms.LoadMessageInfo() == nil {
- ms.StoreMessageInfo(mi)
- }
- return ms
- }
- return mi.MessageOf(x)
-}
-
-// Deprecated: Use Route.ProtoReflect.Descriptor instead.
-func (*Route) Descriptor() ([]byte, []int) {
- return file_remote_proto_rawDescGZIP(), []int{3}
-}
-
-func (x *Route) GetNetwork() string {
- if x != nil {
- return x.Network
- }
- return ""
-}
-
-func (x *Route) GetSrv6Endpoint() string {
- if x != nil {
- return x.Srv6Endpoint
- }
- return ""
-}
-
-func (x *Route) GetSrv6Segments() []string {
- if x != nil {
- return x.Srv6Segments
- }
- return nil
-}
-
-func (x *Route) GetStatus() Route_Status {
- if x != nil {
- return x.Status
- }
- return Route_ADD
-}
-
-var File_remote_proto protoreflect.FileDescriptor
-
-const file_remote_proto_rawDesc = "" +
- "\n" +
- "\fremote.proto\x12\tremote.v1\"\xa8\x01\n" +
- "\bEnvelope\x121\n" +
- "\bregister\x18\x01 \x01(\v2\x13.remote.v1.RegisterH\x00R\bregister\x127\n" +
- "\n" +
- "deregister\x18\x02 \x01(\v2\x15.remote.v1.DeregisterH\x00R\n" +
- "deregister\x12(\n" +
- "\x05route\x18\x03 \x01(\v2\x10.remote.v1.RouteH\x00R\x05routeB\x06\n" +
- "\x04kind\"I\n" +
- "\bRegister\x12\x18\n" +
- "\anetwork\x18\x01 \x01(\tR\anetwork\x12#\n" +
- "\rsrv6_endpoint\x18\x02 \x01(\tR\fsrv6Endpoint\"K\n" +
- "\n" +
- "Deregister\x12\x18\n" +
- "\anetwork\x18\x01 \x01(\tR\anetwork\x12#\n" +
- "\rsrv6_endpoint\x18\x02 \x01(\tR\fsrv6Endpoint\"\xbb\x01\n" +
- "\x05Route\x12\x18\n" +
- "\anetwork\x18\x01 \x01(\tR\anetwork\x12#\n" +
- "\rsrv6_endpoint\x18\x02 \x01(\tR\fsrv6Endpoint\x12#\n" +
- "\rsrv6_segments\x18\x03 \x03(\tR\fsrv6Segments\x12/\n" +
- "\x06status\x18\x04 \x01(\x0e2\x17.remote.v1.Route.StatusR\x06status\"\x1d\n" +
- "\x06Status\x12\a\n" +
- "\x03ADD\x10\x00\x12\n" +
- "\n" +
- "\x06DELETE\x10\x01B9Z7github.com/datum-cloud/galactic-agent/api/remote;remoteb\x06proto3"
-
-var (
- file_remote_proto_rawDescOnce sync.Once
- file_remote_proto_rawDescData []byte
-)
-
-func file_remote_proto_rawDescGZIP() []byte {
- file_remote_proto_rawDescOnce.Do(func() {
- file_remote_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_remote_proto_rawDesc), len(file_remote_proto_rawDesc)))
- })
- return file_remote_proto_rawDescData
-}
-
-var file_remote_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_remote_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
-var file_remote_proto_goTypes = []any{
- (Route_Status)(0), // 0: remote.v1.Route.Status
- (*Envelope)(nil), // 1: remote.v1.Envelope
- (*Register)(nil), // 2: remote.v1.Register
- (*Deregister)(nil), // 3: remote.v1.Deregister
- (*Route)(nil), // 4: remote.v1.Route
-}
-var file_remote_proto_depIdxs = []int32{
- 2, // 0: remote.v1.Envelope.register:type_name -> remote.v1.Register
- 3, // 1: remote.v1.Envelope.deregister:type_name -> remote.v1.Deregister
- 4, // 2: remote.v1.Envelope.route:type_name -> remote.v1.Route
- 0, // 3: remote.v1.Route.status:type_name -> remote.v1.Route.Status
- 4, // [4:4] is the sub-list for method output_type
- 4, // [4:4] is the sub-list for method input_type
- 4, // [4:4] is the sub-list for extension type_name
- 4, // [4:4] is the sub-list for extension extendee
- 0, // [0:4] is the sub-list for field type_name
-}
-
-func init() { file_remote_proto_init() }
-func file_remote_proto_init() {
- if File_remote_proto != nil {
- return
- }
- file_remote_proto_msgTypes[0].OneofWrappers = []any{
- (*Envelope_Register)(nil),
- (*Envelope_Deregister)(nil),
- (*Envelope_Route)(nil),
- }
- type x struct{}
- out := protoimpl.TypeBuilder{
- File: protoimpl.DescBuilder{
- GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
- RawDescriptor: unsafe.Slice(unsafe.StringData(file_remote_proto_rawDesc), len(file_remote_proto_rawDesc)),
- NumEnums: 1,
- NumMessages: 4,
- NumExtensions: 0,
- NumServices: 0,
- },
- GoTypes: file_remote_proto_goTypes,
- DependencyIndexes: file_remote_proto_depIdxs,
- EnumInfos: file_remote_proto_enumTypes,
- MessageInfos: file_remote_proto_msgTypes,
- }.Build()
- File_remote_proto = out.File
- file_remote_proto_goTypes = nil
- file_remote_proto_depIdxs = nil
-}
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config.yaml b/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config.yaml
deleted file mode 100644
index c6f48fe..0000000
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
-# Galactic Agent Configuration for WSL Lab
-# Author: Sajjad Ahmed, Multi Naturals Inc.
-
-# SRv6 network prefix - must match your topology
-srv6_net: "fc00::/48"
-
-# Unix socket for CNI communication
-socket_path: "/var/run/galactic/agent.sock"
-
-# MQTT Configuration
-# For local testing without Datum cloud, use a local MQTT broker
-# For Datum cloud integration, use: tcp://mqtt.datum.net:1883
-mqtt_url: "tcp://localhost:1883"
-mqtt_clientid: "galactic-agent-wsl"
-mqtt_username: ""
-mqtt_password: ""
-mqtt_qos: 1
-mqtt_topic_receive: "galactic/routes/wsl"
-mqtt_topic_send: "galactic/register"
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config/base/daemonset.yaml b/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config/base/daemonset.yaml
deleted file mode 100644
index ca8b0a0..0000000
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config/base/daemonset.yaml
+++ /dev/null
@@ -1,46 +0,0 @@
-apiVersion: apps/v1
-kind: DaemonSet
-metadata:
- name: galactic-agent
- labels:
- app.kubernetes.io/instance: galactic-agent
- app.kubernetes.io/name: galactic-agent
-spec:
- selector:
- matchLabels:
- app.kubernetes.io/instance: galactic-agent
- app.kubernetes.io/name: galactic-agent
- template:
- metadata:
- labels:
- app.kubernetes.io/instance: galactic-agent
- app.kubernetes.io/name: galactic-agent
- spec:
- affinity:
- nodeAffinity:
- requiredDuringSchedulingIgnoredDuringExecution:
- nodeSelectorTerms:
- - matchExpressions:
- - key: node-role.kubernetes.io/control-plane
- operator: DoesNotExist
- containers:
- - name: galactic-agent
- image: ghcr.io/datum-cloud/galactic-agent:latest
- imagePullPolicy: Always
- resources:
- limits:
- cpu: 1
- memory: 1Gi
- volumeMounts:
- - name: galactic-run
- mountPath: /var/run/galactic
- securityContext:
- capabilities:
- add:
- - NET_ADMIN
- hostNetwork: true
- volumes:
- - name: galactic-run
- hostPath:
- path: /var/run/galactic
- type: DirectoryOrCreate
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config/base/kustomization.yaml b/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config/base/kustomization.yaml
deleted file mode 100644
index 0987901..0000000
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config/base/kustomization.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-resources:
- - daemonset.yaml
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/generate.sh b/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/generate.sh
deleted file mode 100644
index 98b4df0..0000000
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/generate.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/bash
-# Requirements:
-# - apt install protobuf-compiler
-# - go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
-# - go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
-find api -type f -name '*.proto' |while read file; do
- dir=$(dirname ${file})
- grep -q rpc ${file}
- if [ $? -eq 0 ]; then
- echo "Generate gRPC ${file}"
- protoc -I ${dir} \
- --go_out=${dir} \
- --go_opt=paths=source_relative \
- --go-grpc_out=${dir} \
- --go-grpc_opt=paths=source_relative \
- ${file}
- else
- echo "Generate protobuf ${file}"
- protoc -I ${dir} \
- --go_out=${dir} \
- --go_opt=paths=source_relative \
- ${file}
- fi
-done
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/go.mod b/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/go.mod
deleted file mode 100644
index cf3ae3c..0000000
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/go.mod
+++ /dev/null
@@ -1,44 +0,0 @@
-module github.com/datum-cloud/galactic-agent
-
-go 1.24.9
-
-require (
- github.com/datum-cloud/galactic-common v0.0.0-20251029014339-7062fa2334ff
- github.com/eclipse/paho.mqtt.golang v1.5.0
- github.com/spf13/cobra v1.9.1
- github.com/spf13/viper v1.20.1
- github.com/vishvananda/netlink v1.3.2-0.20250622222046-78aca1ace529
- golang.org/x/sync v0.14.0
- google.golang.org/grpc v1.74.2
- google.golang.org/protobuf v1.36.6
-)
-
-require (
- github.com/BurntSushi/toml v1.1.0 // indirect
- github.com/fsnotify/fsnotify v1.8.0 // indirect
- github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
- github.com/gorilla/websocket v1.5.3 // indirect
- github.com/inconshreveable/mousetrap v1.1.0 // indirect
- github.com/kenshaw/baseconv v0.1.1 // indirect
- github.com/lorenzosaino/go-sysctl v0.3.1 // indirect
- github.com/pelletier/go-toml/v2 v2.2.3 // indirect
- github.com/sagikazarmark/locafero v0.7.0 // indirect
- github.com/sourcegraph/conc v0.3.0 // indirect
- github.com/spf13/afero v1.12.0 // indirect
- github.com/spf13/cast v1.7.1 // indirect
- github.com/spf13/pflag v1.0.6 // indirect
- github.com/subosito/gotenv v1.6.0 // indirect
- github.com/vishvananda/netns v0.0.5 // indirect
- go.uber.org/atomic v1.9.0 // indirect
- go.uber.org/multierr v1.9.0 // indirect
- golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d // indirect
- golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
- golang.org/x/mod v0.24.0 // indirect
- golang.org/x/net v0.40.0 // indirect
- golang.org/x/sys v0.33.0 // indirect
- golang.org/x/text v0.25.0 // indirect
- golang.org/x/tools v0.31.0 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect
- gopkg.in/yaml.v3 v3.0.1 // indirect
- honnef.co/go/tools v0.3.2 // indirect
-)
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/go.sum b/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/go.sum
deleted file mode 100644
index e5b60d8..0000000
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/go.sum
+++ /dev/null
@@ -1,127 +0,0 @@
-github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
-github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
-github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
-github.com/datum-cloud/galactic-common v0.0.0-20251029014339-7062fa2334ff h1:u7c253QSnmIFwhaEZsqqNi5HQ61XKTf91bQ+9WhF4dM=
-github.com/datum-cloud/galactic-common v0.0.0-20251029014339-7062fa2334ff/go.mod h1:gXCoJaHM1Yy8au9VdKNbKJBGIKbqcPdfKvd9lQ9UNyM=
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
-github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/eclipse/paho.mqtt.golang v1.5.0 h1:EH+bUVJNgttidWFkLLVKaQPGmkTUfQQqjOsyvMGvD6o=
-github.com/eclipse/paho.mqtt.golang v1.5.0/go.mod h1:du/2qNQVqJf/Sqs4MEL77kR8QTqANF7XU7Fk0aOTAgk=
-github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
-github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
-github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
-github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
-github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
-github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
-github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
-github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
-github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
-github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
-github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
-github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
-github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
-github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
-github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
-github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
-github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
-github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
-github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
-github.com/kenshaw/baseconv v0.1.1 h1:oAu/C7ipUT2PqT9DT0mZDGDg4URIglizZMjPv9oCu0E=
-github.com/kenshaw/baseconv v0.1.1/go.mod h1:yy9zGmnnR6vgOxOQb702nVdAG30JhyYZpj/5/m0siRI=
-github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
-github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
-github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
-github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
-github.com/lorenzosaino/go-sysctl v0.3.1 h1:3phX80tdITw2fJjZlwbXQnDWs4S30beNcMbw0cn0HtY=
-github.com/lorenzosaino/go-sysctl v0.3.1/go.mod h1:5grcsBRpspKknNS1qzt1eIeRDLrhpKZAtz8Fcuvs1Rc=
-github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
-github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
-github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
-github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo=
-github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k=
-github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
-github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
-github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs=
-github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=
-github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
-github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
-github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
-github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
-github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
-github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4=
-github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4=
-github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
-github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
-github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
-github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
-github.com/vishvananda/netlink v1.3.2-0.20250622222046-78aca1ace529 h1:uMzwac/F73FD0zIGmLA1nqLkVFmbN1s34FFAqX5+jVU=
-github.com/vishvananda/netlink v1.3.2-0.20250622222046-78aca1ace529/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5JS/XMVl45+b4=
-github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY=
-github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
-go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
-go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
-go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
-go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
-go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
-go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
-go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=
-go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=
-go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis=
-go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=
-go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
-go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
-go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
-go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
-go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
-go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d h1:+W8Qf4iJtMGKkyAygcKohjxTk4JPsL9DpzApJ22m5Ic=
-golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
-golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
-golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
-golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
-golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
-golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
-golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
-golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
-golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
-golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
-golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
-google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4=
-google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM=
-google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
-google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
-gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
-gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-honnef.co/go/tools v0.3.2 h1:ytYb4rOqyp1TSa2EPvNVwtPQJctSELKaMyLfqNP4+34=
-honnef.co/go/tools v0.3.2/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw=
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/main.go b/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/main.go
deleted file mode 100644
index 9726b12..0000000
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/main.go
+++ /dev/null
@@ -1,167 +0,0 @@
-package main
-
-import (
- "context"
- "log"
- "os"
- "os/signal"
- "syscall"
-
- "golang.org/x/sync/errgroup"
-
- "github.com/spf13/cobra"
- "github.com/spf13/viper"
-
- "google.golang.org/protobuf/proto"
-
- "github.com/datum-cloud/galactic-agent/api/local"
- "github.com/datum-cloud/galactic-agent/api/remote"
- "github.com/datum-cloud/galactic-agent/srv6"
- "github.com/datum-cloud/galactic-common/util"
-)
-
-var configFile string
-
-func initConfig() {
- viper.SetDefault("srv6_net", "fc00::/56")
- viper.SetDefault("socket_path", "/var/run/galactic/agent.sock")
- viper.SetDefault("mqtt_url", "tcp://mqtt:1883")
- viper.SetDefault("mqtt_qos", 1)
- viper.SetDefault("mqtt_topic_receive", "galactic/default/receive")
- viper.SetDefault("mqtt_topic_send", "galactic/default/send")
- if configFile != "" {
- viper.SetConfigFile(configFile)
- }
- viper.AutomaticEnv()
- if err := viper.ReadInConfig(); err == nil {
- log.Printf("Using config file: %s\n", viper.ConfigFileUsed())
- } else {
- log.Printf("No config file found - using defaults.")
- }
-}
-
-var (
- l local.Local
- r remote.Remote
-)
-
-func main() {
- cmd := &cobra.Command{
- Use: "galactic-agent",
- Short: "Galactic Agent",
- PersistentPreRun: func(cmd *cobra.Command, args []string) {
- initConfig()
- },
- Run: func(cmd *cobra.Command, args []string) {
- ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
- defer stop() //nolint:errcheck
-
- _, err := util.EncodeSRv6Endpoint(viper.GetString("srv6_net"), "ffffffffffff", "ffff")
- if err != nil {
- log.Fatalf("srv6_endpoint invalid: %v", err)
- }
-
- l = local.Local{
- SocketPath: viper.GetString("socket_path"),
- RegisterHandler: func(vpc, vpcAttachment string, networks []string) error {
- srv6_endpoint, err := util.EncodeSRv6Endpoint(viper.GetString("srv6_net"), vpc, vpcAttachment)
- if err != nil {
- return err
- }
- if err := srv6.RouteIngressAdd(srv6_endpoint); err != nil {
- return err
- }
- for _, n := range networks {
- log.Printf("REGISTER: network='%s', srv6_endpoint='%s'", n, srv6_endpoint)
- payload, err := proto.Marshal(&remote.Envelope{
- Kind: &remote.Envelope_Register{
- Register: &remote.Register{
- Network: n,
- Srv6Endpoint: srv6_endpoint,
- },
- },
- })
- if err != nil {
- return err
- }
- r.Send(payload)
- }
- return nil
- },
- DeregisterHandler: func(vpc, vpcAttachment string, networks []string) error {
- srv6_endpoint, err := util.EncodeSRv6Endpoint(viper.GetString("srv6_net"), vpc, vpcAttachment)
- if err != nil {
- return err
- }
- if err := srv6.RouteIngressDel(srv6_endpoint); err != nil {
- return err
- }
- for _, n := range networks {
- log.Printf("DEREGISTER: network='%s', srv6_endpoint='%s'", n, srv6_endpoint)
- payload, err := proto.Marshal(&remote.Envelope{
- Kind: &remote.Envelope_Deregister{
- Deregister: &remote.Deregister{
- Network: n,
- Srv6Endpoint: srv6_endpoint,
- },
- },
- })
- if err != nil {
- return err
- }
- r.Send(payload)
- }
- return nil
- },
- }
-
- r = remote.Remote{
- URL: viper.GetString("mqtt_url"),
- ClientID: viper.GetString("mqtt_clientid"),
- Username: viper.GetString("mqtt_username"),
- Password: viper.GetString("mqtt_password"),
- QoS: byte(viper.GetInt("mqtt_qos")),
- TopicRX: viper.GetString("mqtt_topic_receive"),
- TopicTX: viper.GetString("mqtt_topic_send"),
- ReceiveHandler: func(payload []byte) error {
- envelope := &remote.Envelope{}
- if err := proto.Unmarshal(payload, envelope); err != nil {
- return err
- }
- switch kind := envelope.Kind.(type) {
- case *remote.Envelope_Route:
- log.Printf("ROUTE: status='%s', network='%s', srv6_endpoint='%s', srv6_segments='%s'", kind.Route.Status, kind.Route.Network, kind.Route.Srv6Endpoint, kind.Route.Srv6Segments)
- switch kind.Route.Status {
- case remote.Route_ADD:
- if err := srv6.RouteEgressAdd(kind.Route.Network, kind.Route.Srv6Endpoint, kind.Route.Srv6Segments); err != nil {
- return err
- }
- case remote.Route_DELETE:
- if err := srv6.RouteEgressDel(kind.Route.Network, kind.Route.Srv6Endpoint, kind.Route.Srv6Segments); err != nil {
- return err
- }
- }
- }
- return nil
- },
- }
-
- g, ctx := errgroup.WithContext(ctx)
- g.Go(func() error {
- return l.Serve(ctx)
- })
- g.Go(func() error {
- return r.Run(ctx)
- })
- if err := g.Wait(); err != nil {
- log.Printf("Error: %v", err)
- }
- log.Printf("Shutdown")
- },
- }
- cmd.PersistentFlags().StringVar(&configFile, "config", "", "config file")
- cmd.SetArgs(os.Args[1:])
- if err := cmd.Execute(); err != nil {
- log.Fatalf("Execution failed: %v", err)
- }
-}
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/routeingress/routeingress.go b/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/routeingress/routeingress.go
deleted file mode 100644
index 00ffbdc..0000000
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/routeingress/routeingress.go
+++ /dev/null
@@ -1,54 +0,0 @@
-package routeingress
-
-import (
- "net"
-
- "github.com/vishvananda/netlink"
- "github.com/vishvananda/netlink/nl"
-
- "github.com/datum-cloud/galactic-common/util"
- "github.com/datum-cloud/galactic-common/vrf"
-)
-
-func Add(ip *net.IPNet, vpc, vpcAttachment string) error {
- dev := util.GenerateInterfaceNameHost(vpc, vpcAttachment)
- link, err := netlink.LinkByName(dev)
- if err != nil {
- return err
- }
-
- vrfId, err := vrf.GetVRFIdForVPC(vpc, vpcAttachment)
- if err != nil {
- return err
- }
-
- var flags [nl.SEG6_LOCAL_MAX]bool
- flags[nl.SEG6_LOCAL_ACTION] = true
- flags[nl.SEG6_LOCAL_VRFTABLE] = true
- encap := &netlink.SEG6LocalEncap{
- Action: nl.SEG6_LOCAL_ACTION_END_DT46,
- Flags: flags,
- VrfTable: int(vrfId),
- }
- route := &netlink.Route{
- Dst: ip,
- LinkIndex: link.Attrs().Index,
- Encap: encap,
- }
- return netlink.RouteReplace(route)
-}
-
-func Delete(ip *net.IPNet, vpc, vpcAttachment string) error {
- dev := util.GenerateInterfaceNameHost(vpc, vpcAttachment)
- link, err := netlink.LinkByName(dev)
- if err != nil {
- return err
- }
-
- route := &netlink.Route{
- Dst: ip,
- LinkIndex: link.Attrs().Index,
- Encap: &netlink.SEG6LocalEncap{},
- }
- return netlink.RouteDel(route)
-}
diff --git a/galactic-operator/.devcontainer/devcontainer.json b/galactic-operator/.devcontainer/devcontainer.json
deleted file mode 100644
index a3ab754..0000000
--- a/galactic-operator/.devcontainer/devcontainer.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "name": "Kubebuilder DevContainer",
- "image": "golang:1.24",
- "features": {
- "ghcr.io/devcontainers/features/docker-in-docker:2": {},
- "ghcr.io/devcontainers/features/git:1": {}
- },
-
- "runArgs": ["--network=host"],
-
- "customizations": {
- "vscode": {
- "settings": {
- "terminal.integrated.shell.linux": "/bin/bash"
- },
- "extensions": [
- "ms-kubernetes-tools.vscode-kubernetes-tools",
- "ms-azuretools.vscode-docker"
- ]
- }
- },
-
- "onCreateCommand": "bash .devcontainer/post-install.sh"
-}
-
diff --git a/galactic-operator/.devcontainer/post-install.sh b/galactic-operator/.devcontainer/post-install.sh
deleted file mode 100644
index 265c43e..0000000
--- a/galactic-operator/.devcontainer/post-install.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash
-set -x
-
-curl -Lo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64
-chmod +x ./kind
-mv ./kind /usr/local/bin/kind
-
-curl -L -o kubebuilder https://go.kubebuilder.io/dl/latest/linux/amd64
-chmod +x kubebuilder
-mv kubebuilder /usr/local/bin/
-
-KUBECTL_VERSION=$(curl -L -s https://dl.k8s.io/release/stable.txt)
-curl -LO "https://dl.k8s.io/release/$KUBECTL_VERSION/bin/linux/amd64/kubectl"
-chmod +x kubectl
-mv kubectl /usr/local/bin/kubectl
-
-docker network create -d=bridge --subnet=172.19.0.0/24 kind
-
-kind version
-kubebuilder version
-docker --version
-go version
-kubectl version --client
diff --git a/galactic-operator/.dockerignore b/galactic-operator/.dockerignore
deleted file mode 100644
index a3aab7a..0000000
--- a/galactic-operator/.dockerignore
+++ /dev/null
@@ -1,3 +0,0 @@
-# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file
-# Ignore build and test binaries.
-bin/
diff --git a/galactic-operator/.github/workflows/lint.yml b/galactic-operator/.github/workflows/lint.yml
deleted file mode 100644
index 67ff2bf..0000000
--- a/galactic-operator/.github/workflows/lint.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-name: Lint
-
-on:
- push:
- pull_request:
-
-jobs:
- lint:
- name: Run on Ubuntu
- runs-on: ubuntu-latest
- steps:
- - name: Clone the code
- uses: actions/checkout@v4
-
- - name: Setup Go
- uses: actions/setup-go@v5
- with:
- go-version-file: go.mod
-
- - name: Run linter
- uses: golangci/golangci-lint-action@v8
- with:
- version: v2.1.6
diff --git a/galactic-operator/.github/workflows/publish.yml b/galactic-operator/.github/workflows/publish.yml
deleted file mode 100644
index b39137e..0000000
--- a/galactic-operator/.github/workflows/publish.yml
+++ /dev/null
@@ -1,34 +0,0 @@
-name: Publish Docker Image
-
-on:
- # Trigger on push
- push:
- # Trigger on all pull requests
- pull_request:
- # Trigger when a release is published
- release:
- types: ['published']
-
-jobs:
- publish-container-image:
- permissions:
- id-token: write
- contents: read
- packages: write
- attestations: write
- uses: datum-cloud/actions/.github/workflows/publish-docker.yaml@v1.8.1
- with:
- image-name: galactic-operator
- platforms: "linux/amd64,linux/arm64"
- secrets: inherit
-
- publish-kustomize-bundles:
- permissions:
- id-token: write
- contents: read
- packages: write
- uses: datum-cloud/actions/.github/workflows/publish-kustomize-bundle.yaml@v1.6.5
- with:
- bundle-name: ghcr.io/datum-cloud/galactic-operator-kustomize
- bundle-path: config
- secrets: inherit
diff --git a/galactic-operator/.github/workflows/test-e2e.yml b/galactic-operator/.github/workflows/test-e2e.yml
deleted file mode 100644
index 68fd1ed..0000000
--- a/galactic-operator/.github/workflows/test-e2e.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-name: E2E Tests
-
-on:
- push:
- pull_request:
-
-jobs:
- test-e2e:
- name: Run on Ubuntu
- runs-on: ubuntu-latest
- steps:
- - name: Clone the code
- uses: actions/checkout@v4
-
- - name: Setup Go
- uses: actions/setup-go@v5
- with:
- go-version-file: go.mod
-
- - name: Install the latest version of kind
- run: |
- curl -Lo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64
- chmod +x ./kind
- sudo mv ./kind /usr/local/bin/kind
-
- - name: Verify kind installation
- run: kind version
-
- - name: Running Test e2e
- run: |
- go mod tidy
- make test-e2e
diff --git a/galactic-operator/.github/workflows/test.yml b/galactic-operator/.github/workflows/test.yml
deleted file mode 100644
index fc2e80d..0000000
--- a/galactic-operator/.github/workflows/test.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-name: Tests
-
-on:
- push:
- pull_request:
-
-jobs:
- test:
- name: Run on Ubuntu
- runs-on: ubuntu-latest
- steps:
- - name: Clone the code
- uses: actions/checkout@v4
-
- - name: Setup Go
- uses: actions/setup-go@v5
- with:
- go-version-file: go.mod
-
- - name: Running Tests
- run: |
- go mod tidy
- make test
diff --git a/galactic-operator/.gitignore b/galactic-operator/.gitignore
deleted file mode 100644
index ada68ff..0000000
--- a/galactic-operator/.gitignore
+++ /dev/null
@@ -1,27 +0,0 @@
-# Binaries for programs and plugins
-*.exe
-*.exe~
-*.dll
-*.so
-*.dylib
-bin/*
-Dockerfile.cross
-
-# Test binary, built with `go test -c`
-*.test
-
-# Output of the go coverage tool, specifically when used with LiteIDE
-*.out
-
-# Go workspace file
-go.work
-
-# Kubernetes Generated files - skip generated files, except for vendored files
-!vendor/**/zz_generated.*
-
-# editor and IDE paraphernalia
-.idea
-.vscode
-*.swp
-*.swo
-*~
diff --git a/galactic-operator/LICENSE b/galactic-operator/LICENSE
deleted file mode 100644
index bae94e1..0000000
--- a/galactic-operator/LICENSE
+++ /dev/null
@@ -1,661 +0,0 @@
- GNU AFFERO GENERAL PUBLIC LICENSE
- Version 3, 19 November 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU Affero General Public License is a free, copyleft license for
-software and other kinds of works, specifically designed to ensure
-cooperation with the community in the case of network server software.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-our General Public Licenses are intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- Developers that use our General Public Licenses protect your rights
-with two steps: (1) assert copyright on the software, and (2) offer
-you this License which gives you legal permission to copy, distribute
-and/or modify the software.
-
- A secondary benefit of defending all users' freedom is that
-improvements made in alternate versions of the program, if they
-receive widespread use, become available for other developers to
-incorporate. Many developers of free software are heartened and
-encouraged by the resulting cooperation. However, in the case of
-software used on network servers, this result may fail to come about.
-The GNU General Public License permits making a modified version and
-letting the public access it on a server without ever releasing its
-source code to the public.
-
- The GNU Affero General Public License is designed specifically to
-ensure that, in such cases, the modified source code becomes available
-to the community. It requires the operator of a network server to
-provide the source code of the modified version running there to the
-users of that server. Therefore, public use of a modified version, on
-a publicly accessible server, gives the public access to the source
-code of the modified version.
-
- An older license, called the Affero General Public License and
-published by Affero, was designed to accomplish similar goals. This is
-a different license, not a version of the Affero GPL, but Affero has
-released a new version of the Affero GPL which permits relicensing under
-this license.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU Affero General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Remote Network Interaction; Use with the GNU General Public License.
-
- Notwithstanding any other provision of this License, if you modify the
-Program, your modified version must prominently offer all users
-interacting with it remotely through a computer network (if your version
-supports such interaction) an opportunity to receive the Corresponding
-Source of your version by providing access to the Corresponding Source
-from a network server at no charge, through some standard or customary
-means of facilitating copying of software. This Corresponding Source
-shall include the Corresponding Source for any work covered by version 3
-of the GNU General Public License that is incorporated pursuant to the
-following paragraph.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the work with which it is combined will remain governed by version
-3 of the GNU General Public License.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU Affero General Public License from time to time. Such new versions
-will be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU Affero General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU Affero General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU Affero General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-
- Copyright (C)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
-
-Also add information on how to contact you by electronic and paper mail.
-
- If your software can interact with users remotely through a computer
-network, you should also make sure that it provides a way for users to
-get its source. For example, if your program is a web application, its
-interface could display a "Source" link that leads users to an archive
-of the code. There are many ways you could offer source, and different
-solutions will be better for different programs; see section 13 for the
-specific requirements.
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU AGPL, see
-.
\ No newline at end of file
diff --git a/galactic-operator/PROJECT b/galactic-operator/PROJECT
deleted file mode 100644
index ba356d2..0000000
--- a/galactic-operator/PROJECT
+++ /dev/null
@@ -1,39 +0,0 @@
-# Code generated by tool. DO NOT EDIT.
-# This file is used to track the info used to scaffold your project
-# and allow the plugins properly work.
-# More info: https://book.kubebuilder.io/reference/project-config.html
-cliVersion: 4.7.1
-domain: datumapis.com
-layout:
-- go.kubebuilder.io/v4
-projectName: galactic-operator
-repo: github.com/datum-cloud/galactic-operator
-resources:
-- api:
- crdVersion: v1
- namespaced: true
- controller: true
- domain: datumapis.com
- group: galactic
- kind: VPC
- path: github.com/datum-cloud/galactic-operator/api/v1alpha
- version: v1alpha
-- api:
- crdVersion: v1
- namespaced: true
- controller: true
- domain: datumapis.com
- group: galactic
- kind: VPCAttachment
- path: github.com/datum-cloud/galactic-operator/api/v1alpha
- version: v1alpha
-- core: true
- group: core
- kind: Pod
- path: k8s.io/api/core/v1
- version: v1
- webhooks:
- defaulting: true
- validation: true
- webhookVersion: v1
-version: "3"
diff --git a/galactic-operator/README.md b/galactic-operator/README.md
deleted file mode 100644
index f479d24..0000000
--- a/galactic-operator/README.md
+++ /dev/null
@@ -1,117 +0,0 @@
-# galactic-operator
-
-Documentation lives here: http://datum.net/docs/galactic-vpc/#galactic-operator
-
----
-
-## Getting Started
-
-### Prerequisites
-- go version v1.24.0+
-- docker version 17.03+.
-- kubectl version v1.11.3+.
-- Access to a Kubernetes v1.11.3+ cluster.
-
-### To Deploy on the cluster
-**Build and push your image to the location specified by `IMG`:**
-
-```sh
-make docker-build docker-push IMG=/galactic-operator:tag
-```
-
-**NOTE:** This image ought to be published in the personal registry you specified.
-And it is required to have access to pull the image from the working environment.
-Make sure you have the proper permission to the registry if the above commands don’t work.
-
-**Install the CRDs into the cluster:**
-
-```sh
-make install
-```
-
-**Deploy the Manager to the cluster with the image specified by `IMG`:**
-
-```sh
-make deploy IMG=/galactic-operator:tag
-```
-
-> **NOTE**: If you encounter RBAC errors, you may need to grant yourself cluster-admin
-privileges or be logged in as admin.
-
-**Create instances of your solution**
-You can apply the samples (examples) from the config/sample:
-
-```sh
-kubectl apply -k config/samples/
-```
-
->**NOTE**: Ensure that the samples has default values to test it out.
-
-### To Uninstall
-**Delete the instances (CRs) from the cluster:**
-
-```sh
-kubectl delete -k config/samples/
-```
-
-**Delete the APIs(CRDs) from the cluster:**
-
-```sh
-make uninstall
-```
-
-**UnDeploy the controller from the cluster:**
-
-```sh
-make undeploy
-```
-
-## Project Distribution
-
-Following the options to release and provide this solution to the users.
-
-### By providing a bundle with all YAML files
-
-1. Build the installer for the image built and published in the registry:
-
-```sh
-make build-installer IMG=/galactic-operator:tag
-```
-
-**NOTE:** The makefile target mentioned above generates an 'install.yaml'
-file in the dist directory. This file contains all the resources built
-with Kustomize, which are necessary to install this project without its
-dependencies.
-
-2. Using the installer
-
-Users can just run 'kubectl apply -f ' to install
-the project, i.e.:
-
-```sh
-kubectl apply -f https://raw.githubusercontent.com//galactic-operator//dist/install.yaml
-```
-
-### By providing a Helm Chart
-
-1. Build the chart using the optional helm plugin
-
-```sh
-kubebuilder edit --plugins=helm/v1-alpha
-```
-
-2. See that a chart was generated under 'dist/chart', and users
-can obtain this solution from there.
-
-**NOTE:** If you change the project, you need to update the Helm Chart
-using the same command above to sync the latest changes. Furthermore,
-if you create webhooks, you need to use the above command with
-the '--force' flag and manually ensure that any custom configuration
-previously added to 'dist/chart/values.yaml' or 'dist/chart/manager/manager.yaml'
-is manually re-applied afterwards.
-
-## Contributing
-
-**NOTE:** Run `make help` for more information on all potential `make` targets
-
-More information can be found via the [Kubebuilder Documentation](https://book.kubebuilder.io/introduction.html)
diff --git a/galactic-operator/cmd/main.go b/galactic-operator/cmd/main.go
deleted file mode 100644
index 76a7210..0000000
--- a/galactic-operator/cmd/main.go
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
-Copyright 2025.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package main
-
-import (
- "crypto/tls"
- "flag"
- "os"
- "path/filepath"
-
- // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
- // to ensure that exec-entrypoint and run can make use of them.
- _ "k8s.io/client-go/plugin/pkg/client/auth"
-
- "k8s.io/apimachinery/pkg/runtime"
- utilruntime "k8s.io/apimachinery/pkg/util/runtime"
- clientgoscheme "k8s.io/client-go/kubernetes/scheme"
- ctrl "sigs.k8s.io/controller-runtime"
- "sigs.k8s.io/controller-runtime/pkg/certwatcher"
- "sigs.k8s.io/controller-runtime/pkg/healthz"
- "sigs.k8s.io/controller-runtime/pkg/log/zap"
- "sigs.k8s.io/controller-runtime/pkg/metrics/filters"
- metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
- "sigs.k8s.io/controller-runtime/pkg/webhook"
-
- galacticv1alpha "github.com/datum-cloud/galactic-operator/api/v1alpha"
- "github.com/datum-cloud/galactic-operator/internal/controller"
- webhookv1 "github.com/datum-cloud/galactic-operator/internal/webhook/v1"
- nadv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1"
-
- "github.com/datum-cloud/galactic-operator/internal/identifier"
- // +kubebuilder:scaffold:imports
-)
-
-var (
- scheme = runtime.NewScheme()
- setupLog = ctrl.Log.WithName("setup")
-)
-
-func init() {
- utilruntime.Must(clientgoscheme.AddToScheme(scheme))
-
- utilruntime.Must(galacticv1alpha.AddToScheme(scheme))
- utilruntime.Must(nadv1.AddToScheme(scheme))
- // +kubebuilder:scaffold:scheme
-}
-
-// nolint:gocyclo
-func main() {
- var metricsAddr string
- var metricsCertPath, metricsCertName, metricsCertKey string
- var webhookCertPath, webhookCertName, webhookCertKey string
- var enableLeaderElection bool
- var probeAddr string
- var secureMetrics bool
- var enableHTTP2 bool
- var tlsOpts []func(*tls.Config)
- flag.StringVar(&metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+
- "Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.")
- flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
- flag.BoolVar(&enableLeaderElection, "leader-elect", false,
- "Enable leader election for controller manager. "+
- "Enabling this will ensure there is only one active controller manager.")
- flag.BoolVar(&secureMetrics, "metrics-secure", true,
- "If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead.")
- flag.StringVar(&webhookCertPath, "webhook-cert-path", "", "The directory that contains the webhook certificate.")
- flag.StringVar(&webhookCertName, "webhook-cert-name", "tls.crt", "The name of the webhook certificate file.")
- flag.StringVar(&webhookCertKey, "webhook-cert-key", "tls.key", "The name of the webhook key file.")
- flag.StringVar(&metricsCertPath, "metrics-cert-path", "",
- "The directory that contains the metrics server certificate.")
- flag.StringVar(&metricsCertName, "metrics-cert-name", "tls.crt", "The name of the metrics server certificate file.")
- flag.StringVar(&metricsCertKey, "metrics-cert-key", "tls.key", "The name of the metrics server key file.")
- flag.BoolVar(&enableHTTP2, "enable-http2", false,
- "If set, HTTP/2 will be enabled for the metrics and webhook servers")
- opts := zap.Options{
- Development: true,
- }
- opts.BindFlags(flag.CommandLine)
- flag.Parse()
-
- ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))
-
- // if the enable-http2 flag is false (the default), http/2 should be disabled
- // due to its vulnerabilities. More specifically, disabling http/2 will
- // prevent from being vulnerable to the HTTP/2 Stream Cancellation and
- // Rapid Reset CVEs. For more information see:
- // - https://github.com/advisories/GHSA-qppj-fm5r-hxr3
- // - https://github.com/advisories/GHSA-4374-p667-p6c8
- disableHTTP2 := func(c *tls.Config) {
- setupLog.Info("disabling http/2")
- c.NextProtos = []string{"http/1.1"}
- }
-
- if !enableHTTP2 {
- tlsOpts = append(tlsOpts, disableHTTP2)
- }
-
- // Create watchers for metrics and webhooks certificates
- var metricsCertWatcher, webhookCertWatcher *certwatcher.CertWatcher
-
- // Initial webhook TLS options
- webhookTLSOpts := tlsOpts
-
- if len(webhookCertPath) > 0 {
- setupLog.Info("Initializing webhook certificate watcher using provided certificates",
- "webhook-cert-path", webhookCertPath, "webhook-cert-name", webhookCertName, "webhook-cert-key", webhookCertKey)
-
- var err error
- webhookCertWatcher, err = certwatcher.New(
- filepath.Join(webhookCertPath, webhookCertName),
- filepath.Join(webhookCertPath, webhookCertKey),
- )
- if err != nil {
- setupLog.Error(err, "Failed to initialize webhook certificate watcher")
- os.Exit(1)
- }
-
- webhookTLSOpts = append(webhookTLSOpts, func(config *tls.Config) {
- config.GetCertificate = webhookCertWatcher.GetCertificate
- })
- }
-
- webhookServer := webhook.NewServer(webhook.Options{
- TLSOpts: webhookTLSOpts,
- })
-
- // Metrics endpoint is enabled in 'config/default/kustomization.yaml'. The Metrics options configure the server.
- // More info:
- // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.21.0/pkg/metrics/server
- // - https://book.kubebuilder.io/reference/metrics.html
- metricsServerOptions := metricsserver.Options{
- BindAddress: metricsAddr,
- SecureServing: secureMetrics,
- TLSOpts: tlsOpts,
- }
-
- if secureMetrics {
- // FilterProvider is used to protect the metrics endpoint with authn/authz.
- // These configurations ensure that only authorized users and service accounts
- // can access the metrics endpoint. The RBAC are configured in 'config/rbac/kustomization.yaml'. More info:
- // https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.21.0/pkg/metrics/filters#WithAuthenticationAndAuthorization
- metricsServerOptions.FilterProvider = filters.WithAuthenticationAndAuthorization
- }
-
- // If the certificate is not specified, controller-runtime will automatically
- // generate self-signed certificates for the metrics server. While convenient for development and testing,
- // this setup is not recommended for production.
- //
- // TODO(user): If you enable certManager, uncomment the following lines:
- // - [METRICS-WITH-CERTS] at config/default/kustomization.yaml to generate and use certificates
- // managed by cert-manager for the metrics server.
- // - [PROMETHEUS-WITH-CERTS] at config/prometheus/kustomization.yaml for TLS certification.
- if len(metricsCertPath) > 0 {
- setupLog.Info("Initializing metrics certificate watcher using provided certificates",
- "metrics-cert-path", metricsCertPath, "metrics-cert-name", metricsCertName, "metrics-cert-key", metricsCertKey)
-
- var err error
- metricsCertWatcher, err = certwatcher.New(
- filepath.Join(metricsCertPath, metricsCertName),
- filepath.Join(metricsCertPath, metricsCertKey),
- )
- if err != nil {
- setupLog.Error(err, "to initialize metrics certificate watcher", "error", err)
- os.Exit(1)
- }
-
- metricsServerOptions.TLSOpts = append(metricsServerOptions.TLSOpts, func(config *tls.Config) {
- config.GetCertificate = metricsCertWatcher.GetCertificate
- })
- }
-
- mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
- Scheme: scheme,
- Metrics: metricsServerOptions,
- WebhookServer: webhookServer,
- HealthProbeBindAddress: probeAddr,
- LeaderElection: enableLeaderElection,
- LeaderElectionID: "03028ec1.datumapis.com",
- // LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily
- // when the Manager ends. This requires the binary to immediately end when the
- // Manager is stopped, otherwise, this setting is unsafe. Setting this significantly
- // speeds up voluntary leader transitions as the new leader don't have to wait
- // LeaseDuration time first.
- //
- // In the default scaffold provided, the program ends immediately after
- // the manager stops, so would be fine to enable this option. However,
- // if you are doing or is intended to do any operation such as perform cleanups
- // after the manager stops then its usage might be unsafe.
- // LeaderElectionReleaseOnCancel: true,
- })
- if err != nil {
- setupLog.Error(err, "unable to start manager")
- os.Exit(1)
- }
-
- if err := (&controller.VPCReconciler{
- Client: mgr.GetClient(),
- Scheme: mgr.GetScheme(),
- Identifier: identifier.New(),
- }).SetupWithManager(mgr); err != nil {
- setupLog.Error(err, "unable to create controller", "controller", "VPC")
- os.Exit(1)
- }
- if err := (&controller.VPCAttachmentReconciler{
- Client: mgr.GetClient(),
- Scheme: mgr.GetScheme(),
- Identifier: identifier.New(),
- }).SetupWithManager(mgr); err != nil {
- setupLog.Error(err, "unable to create controller", "controller", "VPCAttachment")
- os.Exit(1)
- }
- // nolint:goconst
- if os.Getenv("ENABLE_WEBHOOKS") != "false" {
- if err := webhookv1.SetupPodWebhookWithManager(mgr); err != nil {
- setupLog.Error(err, "unable to create webhook", "webhook", "Pod")
- os.Exit(1)
- }
- }
- // +kubebuilder:scaffold:builder
-
- if metricsCertWatcher != nil {
- setupLog.Info("Adding metrics certificate watcher to manager")
- if err := mgr.Add(metricsCertWatcher); err != nil {
- setupLog.Error(err, "unable to add metrics certificate watcher to manager")
- os.Exit(1)
- }
- }
-
- if webhookCertWatcher != nil {
- setupLog.Info("Adding webhook certificate watcher to manager")
- if err := mgr.Add(webhookCertWatcher); err != nil {
- setupLog.Error(err, "unable to add webhook certificate watcher to manager")
- os.Exit(1)
- }
- }
-
- if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
- setupLog.Error(err, "unable to set up health check")
- os.Exit(1)
- }
- if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
- setupLog.Error(err, "unable to set up ready check")
- os.Exit(1)
- }
-
- setupLog.Info("starting manager")
- if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
- setupLog.Error(err, "problem running manager")
- os.Exit(1)
- }
-}
diff --git a/galactic-operator/dist/install.yaml b/galactic-operator/dist/install.yaml
deleted file mode 100644
index cac8283..0000000
--- a/galactic-operator/dist/install.yaml
+++ /dev/null
@@ -1,804 +0,0 @@
-apiVersion: v1
-kind: Namespace
-metadata:
- labels:
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: galactic-operator
- control-plane: controller-manager
- name: galactic-operator-system
----
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
- name: network-attachment-definitions.k8s.cni.cncf.io
-spec:
- group: k8s.cni.cncf.io
- names:
- kind: NetworkAttachmentDefinition
- plural: network-attachment-definitions
- shortNames:
- - net-attach-def
- singular: network-attachment-definition
- scope: Namespaced
- versions:
- - name: v1
- schema:
- openAPIV3Schema:
- description: 'NetworkAttachmentDefinition is a CRD schema specified by the
- Network Plumbing Working Group to express the intent for attaching pods
- to one or more logical or physical networks. More information available
- at: https://github.com/k8snetworkplumbingwg/multi-net-spec'
- properties:
- apiVersion:
- description: 'APIVersion defines the versioned schema of this represen
- tation of an object. Servers should convert recognized schemas to the
- latest internal value, and may reject unrecognized values. More info:
- https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
- type: string
- kind:
- description: 'Kind is a string value representing the REST resource this
- object represents. Servers may infer this from the endpoint the client
- submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
- type: string
- metadata:
- type: object
- spec:
- description: NetworkAttachmentDefinition spec defines the desired state
- of a network attachment
- properties:
- config:
- description: NetworkAttachmentDefinition config is a JSON-formatted
- CNI configuration
- type: string
- type: object
- type: object
- served: true
- storage: true
----
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
- annotations:
- controller-gen.kubebuilder.io/version: v0.18.0
- name: vpcattachments.galactic.datumapis.com
-spec:
- group: galactic.datumapis.com
- names:
- kind: VPCAttachment
- listKind: VPCAttachmentList
- plural: vpcattachments
- singular: vpcattachment
- scope: Namespaced
- versions:
- - name: v1alpha
- schema:
- openAPIV3Schema:
- description: VPCAttachment is the Schema for the vpcattachments API
- properties:
- apiVersion:
- description: |-
- APIVersion defines the versioned schema of this representation of an object.
- Servers should convert recognized schemas to the latest internal value, and
- may reject unrecognized values.
- More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
- type: string
- kind:
- description: |-
- Kind is a string value representing the REST resource this object represents.
- Servers may infer this from the endpoint the client submits requests to.
- Cannot be updated.
- In CamelCase.
- More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
- type: string
- metadata:
- type: object
- spec:
- description: spec defines the desired state of VPCAttachment
- properties:
- interface:
- description: Interface defines the network interface configuration.
- properties:
- addresses:
- description: A list of IPv4 or IPv6 addresses associated with
- the interface.
- items:
- type: string
- minItems: 1
- type: array
- name:
- default: galactic0
- description: Name of the interface (e.g., eth0).
- type: string
- required:
- - addresses
- - name
- type: object
- routes:
- description: Routes defines additional routing entries for the VPCAttachment.
- items:
- description: VPCAttachmentRoute defines a routing entry for the
- VPCAttachment.
- properties:
- destination:
- description: IPv4 or IPv6 destination network in CIDR notation.
- type: string
- via:
- description: Via is the next hop address.
- type: string
- required:
- - destination
- type: object
- type: array
- vpc:
- description: VPC this attachment belongs to.
- properties:
- apiVersion:
- description: API version of the referent.
- type: string
- fieldPath:
- description: |-
- If referring to a piece of an object instead of an entire object, this string
- should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
- For example, if the object reference is to a container within a pod, this would take on a value like:
- "spec.containers{name}" (where "name" refers to the name of the container that triggered
- the event) or if no container name is specified "spec.containers[2]" (container with
- index 2 in this pod). This syntax is chosen only to have some well-defined way of
- referencing a part of an object.
- type: string
- kind:
- description: |-
- Kind of the referent.
- More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
- type: string
- name:
- description: |-
- Name of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
- type: string
- namespace:
- description: |-
- Namespace of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
- type: string
- resourceVersion:
- description: |-
- Specific resourceVersion to which this reference is made, if any.
- More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
- type: string
- uid:
- description: |-
- UID of the referent.
- More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids
- type: string
- type: object
- x-kubernetes-map-type: atomic
- required:
- - interface
- - vpc
- type: object
- status:
- description: status defines the observed state of VPCAttachment
- properties:
- identifier:
- description: A unique identifier assigned to this VPCAttachment
- type: string
- ready:
- default: false
- description: Indicates whether the VPCAttachment is ready for use
- type: boolean
- required:
- - ready
- type: object
- required:
- - spec
- type: object
- served: true
- storage: true
- subresources:
- status: {}
----
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
- annotations:
- controller-gen.kubebuilder.io/version: v0.18.0
- name: vpcs.galactic.datumapis.com
-spec:
- group: galactic.datumapis.com
- names:
- kind: VPC
- listKind: VPCList
- plural: vpcs
- singular: vpc
- scope: Namespaced
- versions:
- - name: v1alpha
- schema:
- openAPIV3Schema:
- description: VPC is the Schema for the vpcs API
- properties:
- apiVersion:
- description: |-
- APIVersion defines the versioned schema of this representation of an object.
- Servers should convert recognized schemas to the latest internal value, and
- may reject unrecognized values.
- More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
- type: string
- kind:
- description: |-
- Kind is a string value representing the REST resource this object represents.
- Servers may infer this from the endpoint the client submits requests to.
- Cannot be updated.
- In CamelCase.
- More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
- type: string
- metadata:
- type: object
- spec:
- description: spec defines the desired state of a VPC
- properties:
- networks:
- description: A list of networks in IPv4 or IPv6 CIDR notation associated
- with the VPC
- items:
- type: string
- minItems: 1
- type: array
- required:
- - networks
- type: object
- status:
- description: status defines the observed state of a VPC
- properties:
- identifier:
- description: A unique identifier assigned to this VPC
- type: string
- ready:
- default: false
- description: Indicates whether the VPC is ready for use
- type: boolean
- required:
- - ready
- type: object
- required:
- - spec
- type: object
- served: true
- storage: true
- subresources:
- status: {}
----
-apiVersion: v1
-kind: ServiceAccount
-metadata:
- labels:
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: galactic-operator
- name: galactic-operator-controller-manager
- namespace: galactic-operator-system
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: Role
-metadata:
- labels:
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: galactic-operator
- name: galactic-operator-leader-election-role
- namespace: galactic-operator-system
-rules:
-- apiGroups:
- - ""
- resources:
- - configmaps
- verbs:
- - get
- - list
- - watch
- - create
- - update
- - patch
- - delete
-- apiGroups:
- - coordination.k8s.io
- resources:
- - leases
- verbs:
- - get
- - list
- - watch
- - create
- - update
- - patch
- - delete
-- apiGroups:
- - ""
- resources:
- - events
- verbs:
- - create
- - patch
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- name: galactic-operator-manager-role
-rules:
-- apiGroups:
- - galactic.datumapis.com
- resources:
- - vpcattachments
- - vpcs
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - galactic.datumapis.com
- resources:
- - vpcattachments/finalizers
- - vpcs/finalizers
- verbs:
- - update
-- apiGroups:
- - galactic.datumapis.com
- resources:
- - vpcattachments/status
- - vpcs/status
- verbs:
- - get
- - patch
- - update
-- apiGroups:
- - k8s.cni.cncf.io
- resources:
- - network-attachment-definitions
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- name: galactic-operator-metrics-auth-role
-rules:
-- apiGroups:
- - authentication.k8s.io
- resources:
- - tokenreviews
- verbs:
- - create
-- apiGroups:
- - authorization.k8s.io
- resources:
- - subjectaccessreviews
- verbs:
- - create
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- name: galactic-operator-metrics-reader
-rules:
-- nonResourceURLs:
- - /metrics
- verbs:
- - get
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- labels:
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: galactic-operator
- name: galactic-operator-vpc-admin-role
-rules:
-- apiGroups:
- - galactic.datumapis.com
- resources:
- - vpcs
- verbs:
- - '*'
-- apiGroups:
- - galactic.datumapis.com
- resources:
- - vpcs/status
- verbs:
- - get
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- labels:
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: galactic-operator
- name: galactic-operator-vpc-editor-role
-rules:
-- apiGroups:
- - galactic.datumapis.com
- resources:
- - vpcs
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - galactic.datumapis.com
- resources:
- - vpcs/status
- verbs:
- - get
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- labels:
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: galactic-operator
- name: galactic-operator-vpc-viewer-role
-rules:
-- apiGroups:
- - galactic.datumapis.com
- resources:
- - vpcs
- verbs:
- - get
- - list
- - watch
-- apiGroups:
- - galactic.datumapis.com
- resources:
- - vpcs/status
- verbs:
- - get
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- labels:
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: galactic-operator
- name: galactic-operator-vpcattachment-admin-role
-rules:
-- apiGroups:
- - galactic.datumapis.com
- resources:
- - vpcattachments
- verbs:
- - '*'
-- apiGroups:
- - galactic.datumapis.com
- resources:
- - vpcattachments/status
- verbs:
- - get
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- labels:
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: galactic-operator
- name: galactic-operator-vpcattachment-editor-role
-rules:
-- apiGroups:
- - galactic.datumapis.com
- resources:
- - vpcattachments
- verbs:
- - create
- - delete
- - get
- - list
- - patch
- - update
- - watch
-- apiGroups:
- - galactic.datumapis.com
- resources:
- - vpcattachments/status
- verbs:
- - get
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRole
-metadata:
- labels:
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: galactic-operator
- name: galactic-operator-vpcattachment-viewer-role
-rules:
-- apiGroups:
- - galactic.datumapis.com
- resources:
- - vpcattachments
- verbs:
- - get
- - list
- - watch
-- apiGroups:
- - galactic.datumapis.com
- resources:
- - vpcattachments/status
- verbs:
- - get
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: RoleBinding
-metadata:
- labels:
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: galactic-operator
- name: galactic-operator-leader-election-rolebinding
- namespace: galactic-operator-system
-roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: Role
- name: galactic-operator-leader-election-role
-subjects:
-- kind: ServiceAccount
- name: galactic-operator-controller-manager
- namespace: galactic-operator-system
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
-metadata:
- labels:
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: galactic-operator
- name: galactic-operator-manager-rolebinding
-roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: ClusterRole
- name: galactic-operator-manager-role
-subjects:
-- kind: ServiceAccount
- name: galactic-operator-controller-manager
- namespace: galactic-operator-system
----
-apiVersion: rbac.authorization.k8s.io/v1
-kind: ClusterRoleBinding
-metadata:
- name: galactic-operator-metrics-auth-rolebinding
-roleRef:
- apiGroup: rbac.authorization.k8s.io
- kind: ClusterRole
- name: galactic-operator-metrics-auth-role
-subjects:
-- kind: ServiceAccount
- name: galactic-operator-controller-manager
- namespace: galactic-operator-system
----
-apiVersion: v1
-kind: Service
-metadata:
- labels:
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: galactic-operator
- control-plane: controller-manager
- name: galactic-operator-controller-manager-metrics-service
- namespace: galactic-operator-system
-spec:
- ports:
- - name: https
- port: 8443
- protocol: TCP
- targetPort: 8443
- selector:
- app.kubernetes.io/name: galactic-operator
- control-plane: controller-manager
----
-apiVersion: v1
-kind: Service
-metadata:
- labels:
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: galactic-operator
- name: galactic-operator-webhook-service
- namespace: galactic-operator-system
-spec:
- ports:
- - port: 443
- protocol: TCP
- targetPort: 9443
- selector:
- app.kubernetes.io/name: galactic-operator
- control-plane: controller-manager
----
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- labels:
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: galactic-operator
- control-plane: controller-manager
- name: galactic-operator-controller-manager
- namespace: galactic-operator-system
-spec:
- replicas: 1
- selector:
- matchLabels:
- app.kubernetes.io/name: galactic-operator
- control-plane: controller-manager
- template:
- metadata:
- annotations:
- kubectl.kubernetes.io/default-container: manager
- labels:
- app.kubernetes.io/name: galactic-operator
- control-plane: controller-manager
- spec:
- containers:
- - args:
- - --metrics-bind-address=:8443
- - --leader-elect
- - --health-probe-bind-address=:8081
- - --webhook-cert-path=/tmp/k8s-webhook-server/serving-certs
- command:
- - /manager
- image: ghcr.io/datum-cloud/galactic-operator:latest
- livenessProbe:
- httpGet:
- path: /healthz
- port: 8081
- initialDelaySeconds: 15
- periodSeconds: 20
- name: manager
- ports:
- - containerPort: 9443
- name: webhook-server
- protocol: TCP
- readinessProbe:
- httpGet:
- path: /readyz
- port: 8081
- initialDelaySeconds: 5
- periodSeconds: 10
- resources:
- limits:
- cpu: 500m
- memory: 128Mi
- requests:
- cpu: 10m
- memory: 64Mi
- securityContext:
- allowPrivilegeEscalation: false
- capabilities:
- drop:
- - ALL
- readOnlyRootFilesystem: true
- volumeMounts:
- - mountPath: /tmp/k8s-webhook-server/serving-certs
- name: webhook-certs
- readOnly: true
- securityContext:
- runAsNonRoot: true
- seccompProfile:
- type: RuntimeDefault
- serviceAccountName: galactic-operator-controller-manager
- terminationGracePeriodSeconds: 10
- volumes:
- - name: webhook-certs
- secret:
- secretName: webhook-server-cert
----
-apiVersion: cert-manager.io/v1
-kind: Certificate
-metadata:
- labels:
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: galactic-operator
- name: galactic-operator-metrics-certs
- namespace: galactic-operator-system
-spec:
- dnsNames:
- - SERVICE_NAME.SERVICE_NAMESPACE.svc
- - SERVICE_NAME.SERVICE_NAMESPACE.svc.cluster.local
- issuerRef:
- kind: Issuer
- name: galactic-operator-selfsigned-issuer
- secretName: metrics-server-cert
----
-apiVersion: cert-manager.io/v1
-kind: Certificate
-metadata:
- labels:
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: galactic-operator
- name: galactic-operator-serving-cert
- namespace: galactic-operator-system
-spec:
- dnsNames:
- - galactic-operator-webhook-service.galactic-operator-system.svc
- - galactic-operator-webhook-service.galactic-operator-system.svc.cluster.local
- issuerRef:
- kind: Issuer
- name: galactic-operator-selfsigned-issuer
- secretName: webhook-server-cert
----
-apiVersion: cert-manager.io/v1
-kind: Issuer
-metadata:
- labels:
- app.kubernetes.io/managed-by: kustomize
- app.kubernetes.io/name: galactic-operator
- name: galactic-operator-selfsigned-issuer
- namespace: galactic-operator-system
-spec:
- selfSigned: {}
----
-apiVersion: admissionregistration.k8s.io/v1
-kind: MutatingWebhookConfiguration
-metadata:
- annotations:
- cert-manager.io/inject-ca-from: galactic-operator-system/galactic-operator-serving-cert
- name: galactic-operator-mutating-webhook-configuration
-webhooks:
-- admissionReviewVersions:
- - v1
- clientConfig:
- service:
- name: galactic-operator-webhook-service
- namespace: galactic-operator-system
- path: /mutate--v1-pod
- failurePolicy: Fail
- matchConditions:
- - expression: object != null && has(object.metadata) && has(object.metadata.annotations)
- && "k8s.v1alpha.galactic.datumapis.com/vpc-attachment" in object.metadata.annotations
- name: vpc-attachment-annotation-exists
- name: mpod-v1.kb.io
- rules:
- - apiGroups:
- - ""
- apiVersions:
- - v1
- operations:
- - CREATE
- - UPDATE
- resources:
- - pods
- sideEffects: None
----
-apiVersion: admissionregistration.k8s.io/v1
-kind: ValidatingWebhookConfiguration
-metadata:
- annotations:
- cert-manager.io/inject-ca-from: galactic-operator-system/galactic-operator-serving-cert
- name: galactic-operator-validating-webhook-configuration
-webhooks:
-- admissionReviewVersions:
- - v1
- clientConfig:
- service:
- name: galactic-operator-webhook-service
- namespace: galactic-operator-system
- path: /validate--v1-pod
- failurePolicy: Fail
- matchConditions:
- - expression: object != null && has(object.metadata) && has(object.metadata.annotations)
- && "k8s.v1alpha.galactic.datumapis.com/vpc-attachment" in object.metadata.annotations
- name: vpc-attachment-annotation-exists
- name: vpod-v1.kb.io
- rules:
- - apiGroups:
- - ""
- apiVersions:
- - v1
- operations:
- - CREATE
- - UPDATE
- resources:
- - pods
- sideEffects: None
diff --git a/galactic-operator/test/e2e/e2e_suite_test.go b/galactic-operator/test/e2e/e2e_suite_test.go
deleted file mode 100644
index 2281e13..0000000
--- a/galactic-operator/test/e2e/e2e_suite_test.go
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
-Copyright 2025.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package e2e
-
-import (
- "fmt"
- "os"
- "os/exec"
- "testing"
-
- . "github.com/onsi/ginkgo/v2"
- . "github.com/onsi/gomega"
-
- "github.com/datum-cloud/galactic-operator/test/utils"
-)
-
-var (
- // Optional Environment Variables:
- // - CERT_MANAGER_INSTALL_SKIP=true: Skips CertManager installation during test setup.
- // These variables are useful if CertManager is already installed, avoiding
- // re-installation and conflicts.
- skipCertManagerInstall = os.Getenv("CERT_MANAGER_INSTALL_SKIP") == "true"
- // isCertManagerAlreadyInstalled will be set true when CertManager CRDs be found on the cluster
- isCertManagerAlreadyInstalled = false
-
- // projectImage is the name of the image which will be build and loaded
- // with the code source changes to be tested.
- projectImage = "example.com/galactic-operator:v0.0.1"
-)
-
-// TestE2E runs the end-to-end (e2e) test suite for the project. These tests execute in an isolated,
-// temporary environment to validate project changes with the purpose of being used in CI jobs.
-// The default setup requires Kind, builds/loads the Manager Docker image locally, and installs
-// CertManager.
-func TestE2E(t *testing.T) {
- RegisterFailHandler(Fail)
- _, _ = fmt.Fprintf(GinkgoWriter, "Starting galactic-operator integration test suite\n")
- RunSpecs(t, "e2e suite")
-}
-
-var _ = BeforeSuite(func() {
- By("building the manager(Operator) image")
- cmd := exec.Command("make", "docker-build", fmt.Sprintf("IMG=%s", projectImage))
- _, err := utils.Run(cmd)
- ExpectWithOffset(1, err).NotTo(HaveOccurred(), "Failed to build the manager(Operator) image")
-
- // TODO(user): If you want to change the e2e test vendor from Kind, ensure the image is
- // built and available before running the tests. Also, remove the following block.
- By("loading the manager(Operator) image on Kind")
- err = utils.LoadImageToKindClusterWithName(projectImage)
- ExpectWithOffset(1, err).NotTo(HaveOccurred(), "Failed to load the manager(Operator) image into Kind")
-
- // The tests-e2e are intended to run on a temporary cluster that is created and destroyed for testing.
- // To prevent errors when tests run in environments with CertManager already installed,
- // we check for its presence before execution.
- // Setup CertManager before the suite if not skipped and if not already installed
- if !skipCertManagerInstall {
- By("checking if cert manager is installed already")
- isCertManagerAlreadyInstalled = utils.IsCertManagerCRDsInstalled()
- if !isCertManagerAlreadyInstalled {
- _, _ = fmt.Fprintf(GinkgoWriter, "Installing CertManager...\n")
- Expect(utils.InstallCertManager()).To(Succeed(), "Failed to install CertManager")
- } else {
- _, _ = fmt.Fprintf(GinkgoWriter, "WARNING: CertManager is already installed. Skipping installation...\n")
- }
- }
-})
-
-var _ = AfterSuite(func() {
- // Teardown CertManager after the suite if not skipped and if it was not already installed
- if !skipCertManagerInstall && !isCertManagerAlreadyInstalled {
- _, _ = fmt.Fprintf(GinkgoWriter, "Uninstalling CertManager...\n")
- utils.UninstallCertManager()
- }
-})
diff --git a/galactic-operator/test/e2e/e2e_test.go b/galactic-operator/test/e2e/e2e_test.go
deleted file mode 100644
index 23e5073..0000000
--- a/galactic-operator/test/e2e/e2e_test.go
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
-Copyright 2025.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package e2e
-
-import (
- "encoding/json"
- "fmt"
- "os"
- "os/exec"
- "path/filepath"
- "time"
-
- . "github.com/onsi/ginkgo/v2"
- . "github.com/onsi/gomega"
-
- "github.com/datum-cloud/galactic-operator/test/utils"
-)
-
-// namespace where the project is deployed in
-const namespace = "galactic-operator-system"
-
-// serviceAccountName created for the project
-const serviceAccountName = "galactic-operator-controller-manager"
-
-// metricsServiceName is the name of the metrics service of the project
-const metricsServiceName = "galactic-operator-controller-manager-metrics-service"
-
-// metricsRoleBindingName is the name of the RBAC that will be created to allow get the metrics data
-const metricsRoleBindingName = "galactic-operator-metrics-binding"
-
-var _ = Describe("Manager", Ordered, func() {
- var controllerPodName string
-
- // Before running the tests, set up the environment by creating the namespace,
- // enforce the restricted security policy to the namespace, installing CRDs,
- // and deploying the controller.
- BeforeAll(func() {
- By("creating manager namespace")
- cmd := exec.Command("kubectl", "create", "ns", namespace)
- _, err := utils.Run(cmd)
- Expect(err).NotTo(HaveOccurred(), "Failed to create namespace")
-
- By("labeling the namespace to enforce the restricted security policy")
- cmd = exec.Command("kubectl", "label", "--overwrite", "ns", namespace,
- "pod-security.kubernetes.io/enforce=restricted")
- _, err = utils.Run(cmd)
- Expect(err).NotTo(HaveOccurred(), "Failed to label namespace with restricted policy")
-
- By("installing CRDs")
- cmd = exec.Command("make", "install")
- _, err = utils.Run(cmd)
- Expect(err).NotTo(HaveOccurred(), "Failed to install CRDs")
-
- By("deploying the controller-manager")
- cmd = exec.Command("make", "deploy", fmt.Sprintf("IMG=%s", projectImage))
- _, err = utils.Run(cmd)
- Expect(err).NotTo(HaveOccurred(), "Failed to deploy the controller-manager")
- })
-
- // After all tests have been executed, clean up by undeploying the controller, uninstalling CRDs,
- // and deleting the namespace.
- AfterAll(func() {
- By("cleaning up the curl pod for metrics")
- cmd := exec.Command("kubectl", "delete", "pod", "curl-metrics", "-n", namespace)
- _, _ = utils.Run(cmd)
-
- By("undeploying the controller-manager")
- cmd = exec.Command("make", "undeploy")
- _, _ = utils.Run(cmd)
-
- By("uninstalling CRDs")
- cmd = exec.Command("make", "uninstall")
- _, _ = utils.Run(cmd)
-
- By("removing manager namespace")
- cmd = exec.Command("kubectl", "delete", "ns", namespace)
- _, _ = utils.Run(cmd)
- })
-
- // After each test, check for failures and collect logs, events,
- // and pod descriptions for debugging.
- AfterEach(func() {
- specReport := CurrentSpecReport()
- if specReport.Failed() {
- By("Fetching controller manager pod logs")
- cmd := exec.Command("kubectl", "logs", controllerPodName, "-n", namespace)
- controllerLogs, err := utils.Run(cmd)
- if err == nil {
- _, _ = fmt.Fprintf(GinkgoWriter, "Controller logs:\n %s", controllerLogs)
- } else {
- _, _ = fmt.Fprintf(GinkgoWriter, "Failed to get Controller logs: %s", err)
- }
-
- By("Fetching Kubernetes events")
- cmd = exec.Command("kubectl", "get", "events", "-n", namespace, "--sort-by=.lastTimestamp")
- eventsOutput, err := utils.Run(cmd)
- if err == nil {
- _, _ = fmt.Fprintf(GinkgoWriter, "Kubernetes events:\n%s", eventsOutput)
- } else {
- _, _ = fmt.Fprintf(GinkgoWriter, "Failed to get Kubernetes events: %s", err)
- }
-
- By("Fetching curl-metrics logs")
- cmd = exec.Command("kubectl", "logs", "curl-metrics", "-n", namespace)
- metricsOutput, err := utils.Run(cmd)
- if err == nil {
- _, _ = fmt.Fprintf(GinkgoWriter, "Metrics logs:\n %s", metricsOutput)
- } else {
- _, _ = fmt.Fprintf(GinkgoWriter, "Failed to get curl-metrics logs: %s", err)
- }
-
- By("Fetching controller manager pod description")
- cmd = exec.Command("kubectl", "describe", "pod", controllerPodName, "-n", namespace)
- podDescription, err := utils.Run(cmd)
- if err == nil {
- fmt.Println("Pod description:\n", podDescription)
- } else {
- fmt.Println("Failed to describe controller pod")
- }
- }
- })
-
- SetDefaultEventuallyTimeout(2 * time.Minute)
- SetDefaultEventuallyPollingInterval(time.Second)
-
- Context("Manager", func() {
- It("should run successfully", func() {
- By("validating that the controller-manager pod is running as expected")
- verifyControllerUp := func(g Gomega) {
- // Get the name of the controller-manager pod
- cmd := exec.Command("kubectl", "get",
- "pods", "-l", "control-plane=controller-manager",
- "-o", "go-template={{ range .items }}"+
- "{{ if not .metadata.deletionTimestamp }}"+
- "{{ .metadata.name }}"+
- "{{ \"\\n\" }}{{ end }}{{ end }}",
- "-n", namespace,
- )
-
- podOutput, err := utils.Run(cmd)
- g.Expect(err).NotTo(HaveOccurred(), "Failed to retrieve controller-manager pod information")
- podNames := utils.GetNonEmptyLines(podOutput)
- g.Expect(podNames).To(HaveLen(1), "expected 1 controller pod running")
- controllerPodName = podNames[0]
- g.Expect(controllerPodName).To(ContainSubstring("controller-manager"))
-
- // Validate the pod's status
- cmd = exec.Command("kubectl", "get",
- "pods", controllerPodName, "-o", "jsonpath={.status.phase}",
- "-n", namespace,
- )
- output, err := utils.Run(cmd)
- g.Expect(err).NotTo(HaveOccurred())
- g.Expect(output).To(Equal("Running"), "Incorrect controller-manager pod status")
- }
- Eventually(verifyControllerUp).Should(Succeed())
- })
-
- It("should ensure the metrics endpoint is serving metrics", func() {
- By("creating a ClusterRoleBinding for the service account to allow access to metrics")
- cmd := exec.Command("kubectl", "create", "clusterrolebinding", metricsRoleBindingName,
- "--clusterrole=galactic-operator-metrics-reader",
- fmt.Sprintf("--serviceaccount=%s:%s", namespace, serviceAccountName),
- )
- _, err := utils.Run(cmd)
- Expect(err).NotTo(HaveOccurred(), "Failed to create ClusterRoleBinding")
-
- By("validating that the metrics service is available")
- cmd = exec.Command("kubectl", "get", "service", metricsServiceName, "-n", namespace)
- _, err = utils.Run(cmd)
- Expect(err).NotTo(HaveOccurred(), "Metrics service should exist")
-
- By("getting the service account token")
- token, err := serviceAccountToken()
- Expect(err).NotTo(HaveOccurred())
- Expect(token).NotTo(BeEmpty())
-
- By("waiting for the metrics endpoint to be ready")
- verifyMetricsEndpointReady := func(g Gomega) {
- cmd := exec.Command("kubectl", "get", "endpoints", metricsServiceName, "-n", namespace)
- output, err := utils.Run(cmd)
- g.Expect(err).NotTo(HaveOccurred())
- g.Expect(output).To(ContainSubstring("8443"), "Metrics endpoint is not ready")
- }
- Eventually(verifyMetricsEndpointReady).Should(Succeed())
-
- By("verifying that the controller manager is serving the metrics server")
- verifyMetricsServerStarted := func(g Gomega) {
- cmd := exec.Command("kubectl", "logs", controllerPodName, "-n", namespace)
- output, err := utils.Run(cmd)
- g.Expect(err).NotTo(HaveOccurred())
- g.Expect(output).To(ContainSubstring("controller-runtime.metrics\tServing metrics server"),
- "Metrics server not yet started")
- }
- Eventually(verifyMetricsServerStarted).Should(Succeed())
-
- By("creating the curl-metrics pod to access the metrics endpoint")
- cmd = exec.Command("kubectl", "run", "curl-metrics", "--restart=Never",
- "--namespace", namespace,
- "--image=curlimages/curl:latest",
- "--overrides",
- fmt.Sprintf(`{
- "spec": {
- "containers": [{
- "name": "curl",
- "image": "curlimages/curl:latest",
- "command": ["/bin/sh", "-c"],
- "args": ["curl -v -k -H 'Authorization: Bearer %s' https://%s.%s.svc.cluster.local:8443/metrics"],
- "securityContext": {
- "readOnlyRootFilesystem": true,
- "allowPrivilegeEscalation": false,
- "capabilities": {
- "drop": ["ALL"]
- },
- "runAsNonRoot": true,
- "runAsUser": 1000,
- "seccompProfile": {
- "type": "RuntimeDefault"
- }
- }
- }],
- "serviceAccountName": "%s"
- }
- }`, token, metricsServiceName, namespace, serviceAccountName))
- _, err = utils.Run(cmd)
- Expect(err).NotTo(HaveOccurred(), "Failed to create curl-metrics pod")
-
- By("waiting for the curl-metrics pod to complete.")
- verifyCurlUp := func(g Gomega) {
- cmd := exec.Command("kubectl", "get", "pods", "curl-metrics",
- "-o", "jsonpath={.status.phase}",
- "-n", namespace)
- output, err := utils.Run(cmd)
- g.Expect(err).NotTo(HaveOccurred())
- g.Expect(output).To(Equal("Succeeded"), "curl pod in wrong status")
- }
- Eventually(verifyCurlUp, 5*time.Minute).Should(Succeed())
-
- By("getting the metrics by checking curl-metrics logs")
- metricsOutput := getMetricsOutput()
- Expect(metricsOutput).To(ContainSubstring(
- "controller_runtime_reconcile_total",
- ))
- })
-
- It("should provisioned cert-manager", func() {
- By("validating that cert-manager has the certificate Secret")
- verifyCertManager := func(g Gomega) {
- cmd := exec.Command("kubectl", "get", "secrets", "webhook-server-cert", "-n", namespace)
- _, err := utils.Run(cmd)
- g.Expect(err).NotTo(HaveOccurred())
- }
- Eventually(verifyCertManager).Should(Succeed())
- })
-
- It("should have CA injection for mutating webhooks", func() {
- By("checking CA injection for mutating webhooks")
- verifyCAInjection := func(g Gomega) {
- cmd := exec.Command("kubectl", "get",
- "mutatingwebhookconfigurations.admissionregistration.k8s.io",
- "galactic-operator-mutating-webhook-configuration",
- "-o", "go-template={{ range .webhooks }}{{ .clientConfig.caBundle }}{{ end }}")
- mwhOutput, err := utils.Run(cmd)
- g.Expect(err).NotTo(HaveOccurred())
- g.Expect(len(mwhOutput)).To(BeNumerically(">", 10))
- }
- Eventually(verifyCAInjection).Should(Succeed())
- })
-
- It("should have CA injection for validating webhooks", func() {
- By("checking CA injection for validating webhooks")
- verifyCAInjection := func(g Gomega) {
- cmd := exec.Command("kubectl", "get",
- "validatingwebhookconfigurations.admissionregistration.k8s.io",
- "galactic-operator-validating-webhook-configuration",
- "-o", "go-template={{ range .webhooks }}{{ .clientConfig.caBundle }}{{ end }}")
- vwhOutput, err := utils.Run(cmd)
- g.Expect(err).NotTo(HaveOccurred())
- g.Expect(len(vwhOutput)).To(BeNumerically(">", 10))
- }
- Eventually(verifyCAInjection).Should(Succeed())
- })
-
- // +kubebuilder:scaffold:e2e-webhooks-checks
-
- // TODO: Customize the e2e test suite with scenarios specific to your project.
- // Consider applying sample/CR(s) and check their status and/or verifying
- // the reconciliation by using the metrics, i.e.:
- // metricsOutput := getMetricsOutput()
- // Expect(metricsOutput).To(ContainSubstring(
- // fmt.Sprintf(`controller_runtime_reconcile_total{controller="%s",result="success"} 1`,
- // strings.ToLower(),
- // ))
- })
-})
-
-// serviceAccountToken returns a token for the specified service account in the given namespace.
-// It uses the Kubernetes TokenRequest API to generate a token by directly sending a request
-// and parsing the resulting token from the API response.
-func serviceAccountToken() (string, error) {
- const tokenRequestRawString = `{
- "apiVersion": "authentication.k8s.io/v1",
- "kind": "TokenRequest"
- }`
-
- // Temporary file to store the token request
- secretName := fmt.Sprintf("%s-token-request", serviceAccountName)
- tokenRequestFile := filepath.Join("/tmp", secretName)
- err := os.WriteFile(tokenRequestFile, []byte(tokenRequestRawString), os.FileMode(0o644))
- if err != nil {
- return "", err
- }
-
- var out string
- verifyTokenCreation := func(g Gomega) {
- // Execute kubectl command to create the token
- cmd := exec.Command("kubectl", "create", "--raw", fmt.Sprintf(
- "/api/v1/namespaces/%s/serviceaccounts/%s/token",
- namespace,
- serviceAccountName,
- ), "-f", tokenRequestFile)
-
- output, err := cmd.CombinedOutput()
- g.Expect(err).NotTo(HaveOccurred())
-
- // Parse the JSON output to extract the token
- var token tokenRequest
- err = json.Unmarshal(output, &token)
- g.Expect(err).NotTo(HaveOccurred())
-
- out = token.Status.Token
- }
- Eventually(verifyTokenCreation).Should(Succeed())
-
- return out, err
-}
-
-// getMetricsOutput retrieves and returns the logs from the curl pod used to access the metrics endpoint.
-func getMetricsOutput() string {
- By("getting the curl-metrics logs")
- cmd := exec.Command("kubectl", "logs", "curl-metrics", "-n", namespace)
- metricsOutput, err := utils.Run(cmd)
- Expect(err).NotTo(HaveOccurred(), "Failed to retrieve logs from curl pod")
- Expect(metricsOutput).To(ContainSubstring("< HTTP/1.1 200 OK"))
- return metricsOutput
-}
-
-// tokenRequest is a simplified representation of the Kubernetes TokenRequest API response,
-// containing only the token field that we need to extract.
-type tokenRequest struct {
- Status struct {
- Token string `json:"token"`
- } `json:"status"`
-}
diff --git a/galactic-operator/test/utils/utils.go b/galactic-operator/test/utils/utils.go
deleted file mode 100644
index 37bba56..0000000
--- a/galactic-operator/test/utils/utils.go
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
-Copyright 2025.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package utils
-
-import (
- "bufio"
- "bytes"
- "fmt"
- "os"
- "os/exec"
- "strings"
-
- . "github.com/onsi/ginkgo/v2" // nolint:revive,staticcheck
-)
-
-const (
- prometheusOperatorVersion = "v0.77.1"
- prometheusOperatorURL = "https://github.com/prometheus-operator/prometheus-operator/" +
- "releases/download/%s/bundle.yaml"
-
- certmanagerVersion = "v1.16.3"
- certmanagerURLTmpl = "https://github.com/cert-manager/cert-manager/releases/download/%s/cert-manager.yaml"
-)
-
-func warnError(err error) {
- _, _ = fmt.Fprintf(GinkgoWriter, "warning: %v\n", err)
-}
-
-// Run executes the provided command within this context
-func Run(cmd *exec.Cmd) (string, error) {
- dir, _ := GetProjectDir()
- cmd.Dir = dir
-
- if err := os.Chdir(cmd.Dir); err != nil {
- _, _ = fmt.Fprintf(GinkgoWriter, "chdir dir: %q\n", err)
- }
-
- cmd.Env = append(os.Environ(), "GO111MODULE=on")
- command := strings.Join(cmd.Args, " ")
- _, _ = fmt.Fprintf(GinkgoWriter, "running: %q\n", command)
- output, err := cmd.CombinedOutput()
- if err != nil {
- return string(output), fmt.Errorf("%q failed with error %q: %w", command, string(output), err)
- }
-
- return string(output), nil
-}
-
-// InstallPrometheusOperator installs the prometheus Operator to be used to export the enabled metrics.
-func InstallPrometheusOperator() error {
- url := fmt.Sprintf(prometheusOperatorURL, prometheusOperatorVersion)
- cmd := exec.Command("kubectl", "create", "-f", url)
- _, err := Run(cmd)
- return err
-}
-
-// UninstallPrometheusOperator uninstalls the prometheus
-func UninstallPrometheusOperator() {
- url := fmt.Sprintf(prometheusOperatorURL, prometheusOperatorVersion)
- cmd := exec.Command("kubectl", "delete", "-f", url)
- if _, err := Run(cmd); err != nil {
- warnError(err)
- }
-}
-
-// IsPrometheusCRDsInstalled checks if any Prometheus CRDs are installed
-// by verifying the existence of key CRDs related to Prometheus.
-func IsPrometheusCRDsInstalled() bool {
- // List of common Prometheus CRDs
- prometheusCRDs := []string{
- "prometheuses.monitoring.coreos.com",
- "prometheusrules.monitoring.coreos.com",
- "prometheusagents.monitoring.coreos.com",
- }
-
- cmd := exec.Command("kubectl", "get", "crds", "-o", "custom-columns=NAME:.metadata.name")
- output, err := Run(cmd)
- if err != nil {
- return false
- }
- crdList := GetNonEmptyLines(output)
- for _, crd := range prometheusCRDs {
- for _, line := range crdList {
- if strings.Contains(line, crd) {
- return true
- }
- }
- }
-
- return false
-}
-
-// UninstallCertManager uninstalls the cert manager
-func UninstallCertManager() {
- url := fmt.Sprintf(certmanagerURLTmpl, certmanagerVersion)
- cmd := exec.Command("kubectl", "delete", "-f", url)
- if _, err := Run(cmd); err != nil {
- warnError(err)
- }
-
- // Delete leftover leases in kube-system (not cleaned by default)
- kubeSystemLeases := []string{
- "cert-manager-cainjector-leader-election",
- "cert-manager-controller",
- }
- for _, lease := range kubeSystemLeases {
- cmd = exec.Command("kubectl", "delete", "lease", lease,
- "-n", "kube-system", "--ignore-not-found", "--force", "--grace-period=0")
- if _, err := Run(cmd); err != nil {
- warnError(err)
- }
- }
-}
-
-// InstallCertManager installs the cert manager bundle.
-func InstallCertManager() error {
- url := fmt.Sprintf(certmanagerURLTmpl, certmanagerVersion)
- cmd := exec.Command("kubectl", "apply", "-f", url)
- if _, err := Run(cmd); err != nil {
- return err
- }
- // Wait for cert-manager-webhook to be ready, which can take time if cert-manager
- // was re-installed after uninstalling on a cluster.
- cmd = exec.Command("kubectl", "wait", "deployment.apps/cert-manager-webhook",
- "--for", "condition=Available",
- "--namespace", "cert-manager",
- "--timeout", "5m",
- )
-
- _, err := Run(cmd)
- return err
-}
-
-// IsCertManagerCRDsInstalled checks if any Cert Manager CRDs are installed
-// by verifying the existence of key CRDs related to Cert Manager.
-func IsCertManagerCRDsInstalled() bool {
- // List of common Cert Manager CRDs
- certManagerCRDs := []string{
- "certificates.cert-manager.io",
- "issuers.cert-manager.io",
- "clusterissuers.cert-manager.io",
- "certificaterequests.cert-manager.io",
- "orders.acme.cert-manager.io",
- "challenges.acme.cert-manager.io",
- }
-
- // Execute the kubectl command to get all CRDs
- cmd := exec.Command("kubectl", "get", "crds")
- output, err := Run(cmd)
- if err != nil {
- return false
- }
-
- // Check if any of the Cert Manager CRDs are present
- crdList := GetNonEmptyLines(output)
- for _, crd := range certManagerCRDs {
- for _, line := range crdList {
- if strings.Contains(line, crd) {
- return true
- }
- }
- }
-
- return false
-}
-
-// LoadImageToKindClusterWithName loads a local docker image to the kind cluster
-func LoadImageToKindClusterWithName(name string) error {
- cluster := "kind"
- if v, ok := os.LookupEnv("KIND_CLUSTER"); ok {
- cluster = v
- }
- kindOptions := []string{"load", "docker-image", name, "--name", cluster}
- cmd := exec.Command("kind", kindOptions...)
- _, err := Run(cmd)
- return err
-}
-
-// GetNonEmptyLines converts given command output string into individual objects
-// according to line breakers, and ignores the empty elements in it.
-func GetNonEmptyLines(output string) []string {
- var res []string
- elements := strings.Split(output, "\n")
- for _, element := range elements {
- if element != "" {
- res = append(res, element)
- }
- }
-
- return res
-}
-
-// GetProjectDir will return the directory where the project is
-func GetProjectDir() (string, error) {
- wd, err := os.Getwd()
- if err != nil {
- return wd, fmt.Errorf("failed to get current working directory: %w", err)
- }
- wd = strings.ReplaceAll(wd, "/test/e2e", "")
- return wd, nil
-}
-
-// UncommentCode searches for target in the file and remove the comment prefix
-// of the target content. The target content may span multiple lines.
-func UncommentCode(filename, target, prefix string) error {
- // false positive
- // nolint:gosec
- content, err := os.ReadFile(filename)
- if err != nil {
- return fmt.Errorf("failed to read file %q: %w", filename, err)
- }
- strContent := string(content)
-
- idx := strings.Index(strContent, target)
- if idx < 0 {
- return fmt.Errorf("unable to find the code %q to be uncomment", target)
- }
-
- out := new(bytes.Buffer)
- _, err = out.Write(content[:idx])
- if err != nil {
- return fmt.Errorf("failed to write to output: %w", err)
- }
-
- scanner := bufio.NewScanner(bytes.NewBufferString(target))
- if !scanner.Scan() {
- return nil
- }
- for {
- if _, err = out.WriteString(strings.TrimPrefix(scanner.Text(), prefix)); err != nil {
- return fmt.Errorf("failed to write to output: %w", err)
- }
- // Avoid writing a newline in case the previous line was the last in target.
- if !scanner.Scan() {
- break
- }
- if _, err = out.WriteString("\n"); err != nil {
- return fmt.Errorf("failed to write to output: %w", err)
- }
- }
-
- if _, err = out.Write(content[idx+len(target):]); err != nil {
- return fmt.Errorf("failed to write to output: %w", err)
- }
-
- // false positive
- // nolint:gosec
- if err = os.WriteFile(filename, out.Bytes(), 0644); err != nil {
- return fmt.Errorf("failed to write file %q: %w", filename, err)
- }
-
- return nil
-}
diff --git a/galactic-router/.github/workflows/publish.yml b/galactic-router/.github/workflows/publish.yml
deleted file mode 100644
index a1c12a7..0000000
--- a/galactic-router/.github/workflows/publish.yml
+++ /dev/null
@@ -1,34 +0,0 @@
-name: Publish Docker Image
-
-on:
- # Trigger on push
- push:
- # Trigger on all pull requests
- pull_request:
- # Trigger when a release is published
- release:
- types: ['published']
-
-jobs:
- publish-container-image:
- permissions:
- id-token: write
- contents: read
- packages: write
- attestations: write
- uses: datum-cloud/actions/.github/workflows/publish-docker.yaml@v1.8.1
- with:
- image-name: galactic-router
- platforms: "linux/amd64,linux/arm64"
- secrets: inherit
-
- publish-kustomize-bundles:
- permissions:
- id-token: write
- contents: read
- packages: write
- uses: datum-cloud/actions/.github/workflows/publish-kustomize-bundle.yaml@v1.6.5
- with:
- bundle-name: ghcr.io/datum-cloud/galactic-router-kustomize
- bundle-path: config
- secrets: inherit
diff --git a/galactic-router/.github/workflows/test.yml b/galactic-router/.github/workflows/test.yml
deleted file mode 100644
index 2dcf069..0000000
--- a/galactic-router/.github/workflows/test.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-name: Tests
-
-on:
- push:
- pull_request:
-
-jobs:
- test:
- name: Run on Ubuntu
- runs-on: ubuntu-latest
- steps:
- - name: Clone the code
- uses: actions/checkout@v4
-
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v3
-
- - name: Running Tests
- run: |
- docker build . -f Dockerfile.test
diff --git a/galactic-router/LICENSE b/galactic-router/LICENSE
deleted file mode 100644
index bae94e1..0000000
--- a/galactic-router/LICENSE
+++ /dev/null
@@ -1,661 +0,0 @@
- GNU AFFERO GENERAL PUBLIC LICENSE
- Version 3, 19 November 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU Affero General Public License is a free, copyleft license for
-software and other kinds of works, specifically designed to ensure
-cooperation with the community in the case of network server software.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-our General Public Licenses are intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- Developers that use our General Public Licenses protect your rights
-with two steps: (1) assert copyright on the software, and (2) offer
-you this License which gives you legal permission to copy, distribute
-and/or modify the software.
-
- A secondary benefit of defending all users' freedom is that
-improvements made in alternate versions of the program, if they
-receive widespread use, become available for other developers to
-incorporate. Many developers of free software are heartened and
-encouraged by the resulting cooperation. However, in the case of
-software used on network servers, this result may fail to come about.
-The GNU General Public License permits making a modified version and
-letting the public access it on a server without ever releasing its
-source code to the public.
-
- The GNU Affero General Public License is designed specifically to
-ensure that, in such cases, the modified source code becomes available
-to the community. It requires the operator of a network server to
-provide the source code of the modified version running there to the
-users of that server. Therefore, public use of a modified version, on
-a publicly accessible server, gives the public access to the source
-code of the modified version.
-
- An older license, called the Affero General Public License and
-published by Affero, was designed to accomplish similar goals. This is
-a different license, not a version of the Affero GPL, but Affero has
-released a new version of the Affero GPL which permits relicensing under
-this license.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU Affero General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Remote Network Interaction; Use with the GNU General Public License.
-
- Notwithstanding any other provision of this License, if you modify the
-Program, your modified version must prominently offer all users
-interacting with it remotely through a computer network (if your version
-supports such interaction) an opportunity to receive the Corresponding
-Source of your version by providing access to the Corresponding Source
-from a network server at no charge, through some standard or customary
-means of facilitating copying of software. This Corresponding Source
-shall include the Corresponding Source for any work covered by version 3
-of the GNU General Public License that is incorporated pursuant to the
-following paragraph.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the work with which it is combined will remain governed by version
-3 of the GNU General Public License.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU Affero General Public License from time to time. Such new versions
-will be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU Affero General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU Affero General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU Affero General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-
- Copyright (C)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
-
-Also add information on how to contact you by electronic and paper mail.
-
- If your software can interact with users remotely through a computer
-network, you should also make sure that it provides a way for users to
-get its source. For example, if your program is a web application, its
-interface could display a "Source" link that leads users to an archive
-of the code. There are many ways you could offer source, and different
-solutions will be better for different programs; see section 13 for the
-specific requirements.
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU AGPL, see
-.
\ No newline at end of file
diff --git a/galactic-operator/go.mod b/go.mod
similarity index 53%
rename from galactic-operator/go.mod
rename to go.mod
index 09aba6d..bca802a 100644
--- a/galactic-operator/go.mod
+++ b/go.mod
@@ -1,12 +1,25 @@
-module github.com/datum-cloud/galactic-operator
+module go.datum.net/galactic
-go 1.24.9
+go 1.24.0
+
+toolchain go1.24.2
require (
- github.com/datum-cloud/galactic-common v0.0.0-20251029014339-7062fa2334ff
+ github.com/containernetworking/cni v1.3.0
+ github.com/coreos/go-iptables v0.8.0
+ github.com/eclipse/paho.mqtt.golang v1.5.0
github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.7
- github.com/onsi/ginkgo/v2 v2.22.0
- github.com/onsi/gomega v1.36.1
+ github.com/kenshaw/baseconv v0.1.1
+ github.com/lorenzosaino/go-sysctl v0.3.1
+ github.com/onsi/ginkgo/v2 v2.23.4
+ github.com/onsi/gomega v1.37.0
+ github.com/spf13/cobra v1.9.1
+ github.com/spf13/viper v1.20.1
+ github.com/vishvananda/netlink v1.3.2-0.20250622222046-78aca1ace529
+ golang.org/x/sync v0.14.0
+ golang.org/x/sys v0.33.0
+ google.golang.org/grpc v1.74.2
+ google.golang.org/protobuf v1.36.6
k8s.io/api v0.33.0
k8s.io/apimachinery v0.33.0
k8s.io/client-go v0.33.0
@@ -14,85 +27,72 @@ require (
)
require (
- cel.dev/expr v0.19.1 // indirect
- github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
+ github.com/BurntSushi/toml v1.1.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
- github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
- github.com/felixge/httpsnoop v1.0.4 // indirect
- github.com/fsnotify/fsnotify v1.7.0 // indirect
+ github.com/fsnotify/fsnotify v1.8.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
- github.com/go-logr/logr v1.4.2 // indirect
- github.com/go-logr/stdr v1.2.2 // indirect
+ github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/zapr v1.3.0 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
+ github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/btree v1.1.3 // indirect
- github.com/google/cel-go v0.23.2 // indirect
github.com/google/gnostic-models v0.6.9 // indirect
github.com/google/go-cmp v0.7.0 // indirect
- github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db // indirect
+ github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect
github.com/google/uuid v1.6.0 // indirect
- github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect
+ github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
- github.com/kenshaw/baseconv v0.1.1 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
+ github.com/pelletier/go-toml/v2 v2.2.3 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/prometheus/client_golang v1.22.0 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.62.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
- github.com/spf13/cobra v1.8.1 // indirect
- github.com/spf13/pflag v1.0.5 // indirect
- github.com/stoewer/go-strcase v1.3.0 // indirect
+ github.com/sagikazarmark/locafero v0.7.0 // indirect
+ github.com/sourcegraph/conc v0.3.0 // indirect
+ github.com/spf13/afero v1.12.0 // indirect
+ github.com/spf13/cast v1.7.1 // indirect
+ github.com/spf13/pflag v1.0.6 // indirect
+ github.com/subosito/gotenv v1.6.0 // indirect
+ github.com/vishvananda/netns v0.0.5 // indirect
github.com/x448/float16 v0.8.4 // indirect
- go.opentelemetry.io/auto/sdk v1.1.0 // indirect
- go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect
- go.opentelemetry.io/otel v1.33.0 // indirect
- go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 // indirect
- go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 // indirect
- go.opentelemetry.io/otel/metric v1.33.0 // indirect
- go.opentelemetry.io/otel/sdk v1.33.0 // indirect
- go.opentelemetry.io/otel/trace v1.33.0 // indirect
- go.opentelemetry.io/proto/otlp v1.4.0 // indirect
+ go.uber.org/automaxprocs v1.6.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
- golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
- golang.org/x/net v0.38.0 // indirect
- golang.org/x/oauth2 v0.27.0 // indirect
- golang.org/x/sync v0.12.0 // indirect
- golang.org/x/sys v0.31.0 // indirect
- golang.org/x/term v0.30.0 // indirect
- golang.org/x/text v0.23.0 // indirect
+ golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d // indirect
+ golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
+ golang.org/x/mod v0.24.0 // indirect
+ golang.org/x/net v0.40.0 // indirect
+ golang.org/x/oauth2 v0.30.0 // indirect
+ golang.org/x/term v0.32.0 // indirect
+ golang.org/x/text v0.25.0 // indirect
golang.org/x/time v0.9.0 // indirect
- golang.org/x/tools v0.26.0 // indirect
+ golang.org/x/tools v0.31.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
- google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect
- google.golang.org/grpc v1.68.1 // indirect
- google.golang.org/protobuf v1.36.5 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
+ honnef.co/go/tools v0.3.2 // indirect
k8s.io/apiextensions-apiserver v0.33.0 // indirect
- k8s.io/apiserver v0.33.0 // indirect
- k8s.io/component-base v0.33.0 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
- sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect
diff --git a/galactic-operator/go.sum b/go.sum
similarity index 66%
rename from galactic-operator/go.sum
rename to go.sum
index dbdcb2d..c334a3a 100644
--- a/galactic-operator/go.sum
+++ b/go.sum
@@ -1,37 +1,36 @@
-cel.dev/expr v0.19.1 h1:NciYrtDRIR0lNCnH1LFJegdjspNx9fI59O7TWcua/W4=
-cel.dev/expr v0.19.1/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw=
-github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
-github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
+github.com/BurntSushi/toml v1.1.0 h1:ksErzDEI1khOiGPgpwuI7x2ebx/uXQNw7xJpn9Eq1+I=
+github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
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/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
-github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
-github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
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/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/containernetworking/cni v1.3.0 h1:v6EpN8RznAZj9765HhXQrtXgX+ECGebEYEmnuFjskwo=
+github.com/containernetworking/cni v1.3.0/go.mod h1:Bs8glZjjFfGPHMw6hQu82RUgEPNGEaBb9KS5KtNMnJ4=
+github.com/coreos/go-iptables v0.8.0 h1:MPc2P89IhuVpLI7ETL/2tx3XZ61VeICZjYqDEgNsPRc=
+github.com/coreos/go-iptables v0.8.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
+github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
-github.com/datum-cloud/galactic-common v0.0.0-20251029014339-7062fa2334ff h1:u7c253QSnmIFwhaEZsqqNi5HQ61XKTf91bQ+9WhF4dM=
-github.com/datum-cloud/galactic-common v0.0.0-20251029014339-7062fa2334ff/go.mod h1:gXCoJaHM1Yy8au9VdKNbKJBGIKbqcPdfKvd9lQ9UNyM=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/eclipse/paho.mqtt.golang v1.5.0 h1:EH+bUVJNgttidWFkLLVKaQPGmkTUfQQqjOsyvMGvD6o=
+github.com/eclipse/paho.mqtt.golang v1.5.0/go.mod h1:du/2qNQVqJf/Sqs4MEL77kR8QTqANF7XU7Fk0aOTAgk=
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU=
github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM=
-github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
-github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
-github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
-github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
+github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
+github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
+github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
+github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
-github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
-github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
+github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
@@ -46,14 +45,14 @@ github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+Gr
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
+github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
+github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
-github.com/google/cel-go v0.23.2 h1:UdEe3CvQh3Nv+E/j9r1Y//WO0K0cSyD7/y0bzyLIMI4=
-github.com/google/cel-go v0.23.2/go.mod h1:52Pb6QsDbC5kvgxvZhiL9QX1oZEkcUF/ZqaPx1J5Wwo=
github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw=
github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
@@ -62,12 +61,12 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo=
-github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
+github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=
+github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI=
+github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
+github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
@@ -91,6 +90,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
+github.com/lorenzosaino/go-sysctl v0.3.1 h1:3phX80tdITw2fJjZlwbXQnDWs4S30beNcMbw0cn0HtY=
+github.com/lorenzosaino/go-sysctl v0.3.1/go.mod h1:5grcsBRpspKknNS1qzt1eIeRDLrhpKZAtz8Fcuvs1Rc=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -100,14 +101,18 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
-github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg=
-github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
-github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw=
-github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
+github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
+github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
+github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y=
+github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
+github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
+github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
+github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
@@ -119,12 +124,20 @@ github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoG
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
-github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
-github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
-github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs=
-github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
+github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo=
+github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k=
+github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
+github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
+github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs=
+github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=
+github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
+github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
+github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
+github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
+github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
+github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/viper v1.20.1 h1:ZMi+z/lvLyPSCoNtFCpqjy0S4kPbirhpTMwl8BkW9X4=
+github.com/spf13/viper v1.20.1/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@@ -136,28 +149,30 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
+github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
+github.com/vishvananda/netlink v1.3.2-0.20250622222046-78aca1ace529 h1:uMzwac/F73FD0zIGmLA1nqLkVFmbN1s34FFAqX5+jVU=
+github.com/vishvananda/netlink v1.3.2-0.20250622222046-78aca1ace529/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5JS/XMVl45+b4=
+github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY=
+github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q=
-go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw=
-go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 h1:Vh5HayB/0HHfOQA7Ctx69E/Y/DcQSMPpKANYVMQ7fBA=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0/go.mod h1:cpgtDBaqD/6ok/UG0jT15/uKjAY8mRA53diogHBg3UI=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 h1:5pojmb1U1AogINhN3SurB+zm/nIcusopeBNp42f45QM=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0/go.mod h1:57gTHJSE5S1tqg+EKsLPlTWhpHMsWlVmer+LA926XiA=
-go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ=
-go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M=
-go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM=
-go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM=
-go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s=
-go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck=
-go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg=
-go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY=
+go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
+go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
+go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
+go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
+go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=
+go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=
+go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis=
+go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=
+go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
+go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
+go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
+go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
@@ -167,56 +182,62 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
-golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
+golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d h1:+W8Qf4iJtMGKkyAygcKohjxTk4JPsL9DpzApJ22m5Ic=
+golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
+golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
+golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
+golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
-golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
-golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M=
-golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
+golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
+golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
+golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
+golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
-golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
+golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
+golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
-golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
-golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
-golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
+golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
+golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
+golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
+golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
-golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
+golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
+golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
-golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
+golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
+golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
-google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q=
-google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 h1:8ZmaLZE4XWrtU3MyClkYqqtl6Oegr3235h7jxsDyqCY=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU=
-google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0=
-google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw=
-google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
-google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
+google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4=
+google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM=
+google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
+google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
@@ -227,26 +248,22 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+honnef.co/go/tools v0.3.2 h1:ytYb4rOqyp1TSa2EPvNVwtPQJctSELKaMyLfqNP4+34=
+honnef.co/go/tools v0.3.2/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw=
k8s.io/api v0.33.0 h1:yTgZVn1XEe6opVpP1FylmNrIFWuDqe2H0V8CT5gxfIU=
k8s.io/api v0.33.0/go.mod h1:CTO61ECK/KU7haa3qq8sarQ0biLq2ju405IZAd9zsiM=
k8s.io/apiextensions-apiserver v0.33.0 h1:d2qpYL7Mngbsc1taA4IjJPRJ9ilnsXIrndH+r9IimOs=
k8s.io/apiextensions-apiserver v0.33.0/go.mod h1:VeJ8u9dEEN+tbETo+lFkwaaZPg6uFKLGj5vyNEwwSzc=
k8s.io/apimachinery v0.33.0 h1:1a6kHrJxb2hs4t8EE5wuR/WxKDwGN1FKH3JvDtA0CIQ=
k8s.io/apimachinery v0.33.0/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
-k8s.io/apiserver v0.33.0 h1:QqcM6c+qEEjkOODHppFXRiw/cE2zP85704YrQ9YaBbc=
-k8s.io/apiserver v0.33.0/go.mod h1:EixYOit0YTxt8zrO2kBU7ixAtxFce9gKGq367nFmqI8=
k8s.io/client-go v0.33.0 h1:UASR0sAYVUzs2kYuKn/ZakZlcs2bEHaizrrHUZg0G98=
k8s.io/client-go v0.33.0/go.mod h1:kGkd+l/gNGg8GYWAPr0xF1rRKvVWvzh9vmZAMXtaKOg=
-k8s.io/component-base v0.33.0 h1:Ot4PyJI+0JAD9covDhwLp9UNkUja209OzsJ4FzScBNk=
-k8s.io/component-base v0.33.0/go.mod h1:aXYZLbw3kihdkOPMDhWbjGCO6sg+luw554KP51t8qCU=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4=
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8=
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro=
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
-sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 h1:jpcvIRr3GLoUoEKRkHKSmGjxb6lWwrBlJsXc+eUYQHM=
-sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8=
sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM=
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8=
diff --git a/galactic-operator/hack/boilerplate.go.txt b/hack/boilerplate.go.txt
similarity index 100%
rename from galactic-operator/hack/boilerplate.go.txt
rename to hack/boilerplate.go.txt
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/neighborproxy/neighborproxy.go b/internal/agent/srv6/neighborproxy/neighborproxy.go
similarity index 94%
rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/neighborproxy/neighborproxy.go
rename to internal/agent/srv6/neighborproxy/neighborproxy.go
index 6c35ad5..23e7059 100644
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/neighborproxy/neighborproxy.go
+++ b/internal/agent/srv6/neighborproxy/neighborproxy.go
@@ -5,7 +5,7 @@ import (
"github.com/vishvananda/netlink"
- "github.com/datum-cloud/galactic-common/util"
+ "go.datum.net/galactic/pkg/common/util"
)
func Add(ipnet *net.IPNet, vpc, vpcAttachment string) error {
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/routeegress/routeegress.go b/internal/agent/srv6/routeegress/routeegress.go
similarity index 95%
rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/routeegress/routeegress.go
rename to internal/agent/srv6/routeegress/routeegress.go
index 80ec67a..479ee1d 100644
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/routeegress/routeegress.go
+++ b/internal/agent/srv6/routeegress/routeegress.go
@@ -6,7 +6,7 @@ import (
"github.com/vishvananda/netlink"
"github.com/vishvananda/netlink/nl"
- "github.com/datum-cloud/galactic-common/vrf"
+ "go.datum.net/galactic/pkg/common/vrf"
)
const LoopbackDevice = "lo-galactic"
diff --git a/galactic-agent/srv6/routeingress/routeingress.go b/internal/agent/srv6/routeingress/routeingress.go
similarity index 92%
rename from galactic-agent/srv6/routeingress/routeingress.go
rename to internal/agent/srv6/routeingress/routeingress.go
index 00ffbdc..b4e4393 100644
--- a/galactic-agent/srv6/routeingress/routeingress.go
+++ b/internal/agent/srv6/routeingress/routeingress.go
@@ -6,8 +6,8 @@ import (
"github.com/vishvananda/netlink"
"github.com/vishvananda/netlink/nl"
- "github.com/datum-cloud/galactic-common/util"
- "github.com/datum-cloud/galactic-common/vrf"
+ "go.datum.net/galactic/pkg/common/util"
+ "go.datum.net/galactic/pkg/common/vrf"
)
func Add(ip *net.IPNet, vpc, vpcAttachment string) error {
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/srv6.go b/internal/agent/srv6/srv6.go
similarity index 94%
rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/srv6.go
rename to internal/agent/srv6/srv6.go
index 6b6cecf..e6fab25 100644
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/srv6.go
+++ b/internal/agent/srv6/srv6.go
@@ -6,10 +6,10 @@ import (
"github.com/vishvananda/netlink"
- "github.com/datum-cloud/galactic-agent/srv6/neighborproxy"
- "github.com/datum-cloud/galactic-agent/srv6/routeegress"
- "github.com/datum-cloud/galactic-agent/srv6/routeingress"
- "github.com/datum-cloud/galactic-common/util"
+ "go.datum.net/galactic/internal/agent/srv6/neighborproxy"
+ "go.datum.net/galactic/internal/agent/srv6/routeegress"
+ "go.datum.net/galactic/internal/agent/srv6/routeingress"
+ "go.datum.net/galactic/pkg/common/util"
)
func RouteIngressAdd(ipStr string) error {
diff --git a/internal/cmd/agent/agent.go b/internal/cmd/agent/agent.go
new file mode 100644
index 0000000..30c1dcb
--- /dev/null
+++ b/internal/cmd/agent/agent.go
@@ -0,0 +1,221 @@
+/*
+Copyright 2025.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package agent
+
+import (
+ "context"
+ "log"
+
+ "os/signal"
+ "syscall"
+
+ "github.com/spf13/cobra"
+ "github.com/spf13/viper"
+ "golang.org/x/sync/errgroup"
+ "google.golang.org/protobuf/proto"
+
+ "go.datum.net/galactic/internal/agent/srv6"
+ "go.datum.net/galactic/pkg/common/util"
+ "go.datum.net/galactic/pkg/proto/local"
+ "go.datum.net/galactic/pkg/proto/remote"
+)
+
+type agentFlags struct {
+ configFile string
+}
+
+func NewCommand() *cobra.Command {
+ flags := &agentFlags{}
+
+ cmd := &cobra.Command{
+ Use: "agent",
+ Short: "Run the Galactic network agent",
+ Long: `The agent runs on each node and manages local SRv6 routes and VRF configurations.
+It communicates with the CNI plugin via a local gRPC socket and with the router via MQTT.`,
+ PreRun: func(cmd *cobra.Command, args []string) {
+ initConfig(flags.configFile)
+ },
+ RunE: func(cmd *cobra.Command, args []string) error {
+ return runAgent()
+ },
+ }
+
+ cmd.Flags().StringVar(&flags.configFile, "config", "", "Config file path")
+ cmd.Flags().String("srv6-net", "fc00::/56", "SRv6 network CIDR")
+ cmd.Flags().String("socket-path", "/var/run/galactic/agent.sock", "Unix socket path for CNI communication")
+ cmd.Flags().String("mqtt-url", "tcp://mqtt:1883", "MQTT broker URL")
+ cmd.Flags().String("mqtt-clientid", "", "MQTT client ID (empty for random)")
+ cmd.Flags().String("mqtt-username", "", "MQTT username")
+ cmd.Flags().String("mqtt-password", "", "MQTT password")
+ cmd.Flags().Int("mqtt-qos", 1, "MQTT QoS level (0, 1, or 2)")
+ cmd.Flags().String("mqtt-topic-receive", "galactic/default/receive", "MQTT topic for receiving messages")
+ cmd.Flags().String("mqtt-topic-send", "galactic/default/send", "MQTT topic for sending messages")
+
+ // Bind flags to viper
+ _ = viper.BindPFlag("srv6_net", cmd.Flags().Lookup("srv6-net"))
+ _ = viper.BindPFlag("socket_path", cmd.Flags().Lookup("socket-path"))
+ _ = viper.BindPFlag("mqtt_url", cmd.Flags().Lookup("mqtt-url"))
+ _ = viper.BindPFlag("mqtt_clientid", cmd.Flags().Lookup("mqtt-clientid"))
+ _ = viper.BindPFlag("mqtt_username", cmd.Flags().Lookup("mqtt-username"))
+ _ = viper.BindPFlag("mqtt_password", cmd.Flags().Lookup("mqtt-password"))
+ _ = viper.BindPFlag("mqtt_qos", cmd.Flags().Lookup("mqtt-qos"))
+ _ = viper.BindPFlag("mqtt_topic_receive", cmd.Flags().Lookup("mqtt-topic-receive"))
+ _ = viper.BindPFlag("mqtt_topic_send", cmd.Flags().Lookup("mqtt-topic-send"))
+
+ return cmd
+}
+
+func initConfig(configFile string) {
+ // Set defaults
+ viper.SetDefault("srv6_net", "fc00::/56")
+ viper.SetDefault("socket_path", "/var/run/galactic/agent.sock")
+ viper.SetDefault("mqtt_url", "tcp://mqtt:1883")
+ viper.SetDefault("mqtt_qos", 1)
+ viper.SetDefault("mqtt_topic_receive", "galactic/default/receive")
+ viper.SetDefault("mqtt_topic_send", "galactic/default/send")
+
+ if configFile != "" {
+ viper.SetConfigFile(configFile)
+ }
+
+ viper.AutomaticEnv()
+
+ if err := viper.ReadInConfig(); err == nil {
+ log.Printf("Using config file: %s\n", viper.ConfigFileUsed())
+ } else {
+ log.Printf("No config file found - using defaults and environment variables")
+ }
+}
+
+func runAgent() error {
+ ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
+ defer stop()
+
+ // Validate SRv6 network configuration
+ _, err := util.EncodeSRv6Endpoint(viper.GetString("srv6_net"), "ffffffffffff", "ffff")
+ if err != nil {
+ log.Fatalf("srv6_net invalid: %v", err)
+ }
+
+ // Setup local gRPC server for CNI communication
+ var l local.Local
+ var r remote.Remote
+
+ l = local.Local{
+ SocketPath: viper.GetString("socket_path"),
+ RegisterHandler: func(vpc, vpcAttachment string, networks []string) error {
+ srv6Endpoint, err := util.EncodeSRv6Endpoint(viper.GetString("srv6_net"), vpc, vpcAttachment)
+ if err != nil {
+ return err
+ }
+ if err := srv6.RouteIngressAdd(srv6Endpoint); err != nil {
+ return err
+ }
+ for _, n := range networks {
+ log.Printf("REGISTER: network='%s', srv6_endpoint='%s'", n, srv6Endpoint)
+ payload, err := proto.Marshal(&remote.Envelope{
+ Kind: &remote.Envelope_Register{
+ Register: &remote.Register{
+ Network: n,
+ Srv6Endpoint: srv6Endpoint,
+ },
+ },
+ })
+ if err != nil {
+ return err
+ }
+ r.Send(payload)
+ }
+ return nil
+ },
+ DeregisterHandler: func(vpc, vpcAttachment string, networks []string) error {
+ srv6Endpoint, err := util.EncodeSRv6Endpoint(viper.GetString("srv6_net"), vpc, vpcAttachment)
+ if err != nil {
+ return err
+ }
+ if err := srv6.RouteIngressDel(srv6Endpoint); err != nil {
+ return err
+ }
+ for _, n := range networks {
+ log.Printf("DEREGISTER: network='%s', srv6_endpoint='%s'", n, srv6Endpoint)
+ payload, err := proto.Marshal(&remote.Envelope{
+ Kind: &remote.Envelope_Deregister{
+ Deregister: &remote.Deregister{
+ Network: n,
+ Srv6Endpoint: srv6Endpoint,
+ },
+ },
+ })
+ if err != nil {
+ return err
+ }
+ r.Send(payload)
+ }
+ return nil
+ },
+ }
+
+ // Setup MQTT client for router communication
+ r = remote.Remote{
+ URL: viper.GetString("mqtt_url"),
+ ClientID: viper.GetString("mqtt_clientid"),
+ Username: viper.GetString("mqtt_username"),
+ Password: viper.GetString("mqtt_password"),
+ QoS: byte(viper.GetInt("mqtt_qos")),
+ TopicRX: viper.GetString("mqtt_topic_receive"),
+ TopicTX: viper.GetString("mqtt_topic_send"),
+ ReceiveHandler: func(payload []byte) error {
+ envelope := &remote.Envelope{}
+ if err := proto.Unmarshal(payload, envelope); err != nil {
+ return err
+ }
+ switch kind := envelope.Kind.(type) {
+ case *remote.Envelope_Route:
+ log.Printf("ROUTE: status='%s', network='%s', srv6_endpoint='%s', srv6_segments='%s'",
+ kind.Route.Status, kind.Route.Network, kind.Route.Srv6Endpoint, kind.Route.Srv6Segments)
+ switch kind.Route.Status {
+ case remote.Route_ADD:
+ if err := srv6.RouteEgressAdd(kind.Route.Network, kind.Route.Srv6Endpoint, kind.Route.Srv6Segments); err != nil {
+ return err
+ }
+ case remote.Route_DELETE:
+ if err := srv6.RouteEgressDel(kind.Route.Network, kind.Route.Srv6Endpoint, kind.Route.Srv6Segments); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+ },
+ }
+
+ // Run local and remote servers concurrently
+ g, ctx := errgroup.WithContext(ctx)
+ g.Go(func() error {
+ return l.Serve(ctx)
+ })
+ g.Go(func() error {
+ return r.Run(ctx)
+ })
+
+ if err := g.Wait(); err != nil {
+ log.Printf("Error: %v", err)
+ return err
+ }
+
+ log.Printf("Shutdown complete")
+ return nil
+}
diff --git a/internal/cmd/cni/cni.go b/internal/cmd/cni/cni.go
new file mode 100644
index 0000000..90e6acc
--- /dev/null
+++ b/internal/cmd/cni/cni.go
@@ -0,0 +1,43 @@
+/*
+Copyright 2025.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package cni
+
+import (
+ "github.com/spf13/cobra"
+
+ cniimpl "go.datum.net/galactic/internal/cni"
+)
+
+func NewCommand() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "cni",
+ Short: "Run as a CNI plugin",
+ Long: `The CNI plugin is invoked by the container runtime to set up network interfaces
+for pods. It configures VRF, veth pairs, routes, and communicates with the agent
+via gRPC to register network attachments.
+
+This command is typically invoked automatically by the container runtime when the
+CNI_COMMAND environment variable is set. The main binary auto-detects CNI mode
+and invokes this subcommand.`,
+ Run: func(cmd *cobra.Command, args []string) {
+ // Delegate to the CNI implementation
+ cniimpl.NewCommand().Run(cmd, args)
+ },
+ }
+
+ return cmd
+}
diff --git a/internal/cmd/operator/operator.go b/internal/cmd/operator/operator.go
new file mode 100644
index 0000000..bb1cf60
--- /dev/null
+++ b/internal/cmd/operator/operator.go
@@ -0,0 +1,181 @@
+/*
+Copyright 2025.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package operator
+
+import (
+ "crypto/tls"
+ "os"
+
+ "github.com/spf13/cobra"
+ "k8s.io/apimachinery/pkg/runtime"
+ utilruntime "k8s.io/apimachinery/pkg/util/runtime"
+ clientgoscheme "k8s.io/client-go/kubernetes/scheme"
+ ctrl "sigs.k8s.io/controller-runtime"
+ "sigs.k8s.io/controller-runtime/pkg/healthz"
+ "sigs.k8s.io/controller-runtime/pkg/log/zap"
+ metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
+ "sigs.k8s.io/controller-runtime/pkg/webhook"
+
+ "go.datum.net/galactic/internal/operator/controller"
+ "go.datum.net/galactic/internal/operator/identifier"
+ webhookv1 "go.datum.net/galactic/internal/operator/webhook/v1"
+ galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha"
+)
+
+var (
+ scheme = runtime.NewScheme()
+ setupLog = ctrl.Log.WithName("setup")
+)
+
+func init() {
+ utilruntime.Must(clientgoscheme.AddToScheme(scheme))
+ utilruntime.Must(galacticv1alpha.AddToScheme(scheme))
+}
+
+type operatorFlags struct {
+ metricsAddr string
+ enableLeaderElection bool
+ probeAddr string
+ secureMetrics bool
+ enableHTTP2 bool
+ tlsOpts []func(*tls.Config)
+}
+
+func NewCommand() *cobra.Command {
+ flags := &operatorFlags{}
+
+ cmd := &cobra.Command{
+ Use: "operator",
+ Short: "Run the Galactic Kubernetes operator",
+ Long: `The operator manages VPC and VPCAttachment custom resources in Kubernetes.
+It reconciles resource state, assigns identifiers, and configures pod network attachments
+via mutation webhooks.`,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ return runOperator(flags)
+ },
+ }
+
+ cmd.Flags().StringVar(&flags.metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+
+ "Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.")
+ cmd.Flags().StringVar(&flags.probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
+ cmd.Flags().BoolVar(&flags.enableLeaderElection, "leader-elect", false,
+ "Enable leader election for controller manager. "+
+ "Enabling this will ensure there is only one active controller manager.")
+ cmd.Flags().BoolVar(&flags.secureMetrics, "metrics-secure", true,
+ "If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead.")
+ cmd.Flags().BoolVar(&flags.enableHTTP2, "enable-http2", false,
+ "If set, HTTP/2 will be enabled for the metrics and webhook servers")
+
+ return cmd
+}
+
+func runOperator(flags *operatorFlags) error {
+ opts := zap.Options{
+ Development: true,
+ }
+ ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))
+
+ // if the enable-http2 flag is false (the default), http/2 should be disabled
+ // due to its vulnerabilities. More specifically, disabling http/2 will
+ // prevent from being vulnerable to the HTTP/2 Stream Cancellation and
+ // Rapid Reset CVEs. For more information see:
+ // - https://github.com/advisories/GHSA-qppj-fm5r-hxr3
+ // - https://github.com/advisories/GHSA-4374-p667-p6c8
+ disableHTTP2 := func(c *tls.Config) {
+ setupLog.Info("disabling http/2")
+ c.NextProtos = []string{"http/1.1"}
+ }
+
+ if !flags.enableHTTP2 {
+ flags.tlsOpts = append(flags.tlsOpts, disableHTTP2)
+ }
+
+ webhookServer := webhook.NewServer(webhook.Options{
+ TLSOpts: flags.tlsOpts,
+ })
+
+ // Metrics endpoint is enabled in 'config/default/kustomization.yaml'. The Metrics options configure the server.
+ // More info:
+ // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.1/pkg/metrics/server
+ // - https://book.kubebuilder.io/reference/metrics.html
+ metricsServerOptions := metricsserver.Options{
+ BindAddress: flags.metricsAddr,
+ SecureServing: flags.secureMetrics,
+ TLSOpts: flags.tlsOpts,
+ }
+
+ mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
+ Scheme: scheme,
+ Metrics: metricsServerOptions,
+ WebhookServer: webhookServer,
+ HealthProbeBindAddress: flags.probeAddr,
+ LeaderElection: flags.enableLeaderElection,
+ LeaderElectionID: "galactic.datumapis.com",
+ })
+ if err != nil {
+ setupLog.Error(err, "unable to start manager")
+ return err
+ }
+
+ // Create identifier generator for VPC and VPCAttachment
+ identifierGen := identifier.New()
+
+ // Register VPC controller
+ if err = (&controller.VPCReconciler{
+ Client: mgr.GetClient(),
+ Scheme: mgr.GetScheme(),
+ Identifier: identifierGen,
+ }).SetupWithManager(mgr); err != nil {
+ setupLog.Error(err, "unable to create controller", "controller", "VPC")
+ return err
+ }
+
+ // Register VPCAttachment controller
+ if err = (&controller.VPCAttachmentReconciler{
+ Client: mgr.GetClient(),
+ Scheme: mgr.GetScheme(),
+ Identifier: identifierGen,
+ }).SetupWithManager(mgr); err != nil {
+ setupLog.Error(err, "unable to create controller", "controller", "VPCAttachment")
+ return err
+ }
+
+ // Register Pod mutation webhook
+ if os.Getenv("ENABLE_WEBHOOKS") != "false" {
+ if err = webhookv1.SetupPodWebhookWithManager(mgr); err != nil {
+ setupLog.Error(err, "unable to create webhook", "webhook", "Pod")
+ return err
+ }
+ }
+
+ if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
+ setupLog.Error(err, "unable to set up health check")
+ return err
+ }
+ if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
+ setupLog.Error(err, "unable to set up ready check")
+ return err
+ }
+
+ setupLog.Info("starting manager")
+ if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
+ setupLog.Error(err, "problem running manager")
+ return err
+ }
+
+ return nil
+}
diff --git a/internal/cmd/version/version.go b/internal/cmd/version/version.go
new file mode 100644
index 0000000..9f13e51
--- /dev/null
+++ b/internal/cmd/version/version.go
@@ -0,0 +1,50 @@
+/*
+Copyright 2025.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package version
+
+import (
+ "fmt"
+ "runtime"
+
+ "github.com/spf13/cobra"
+)
+
+var (
+ // Version information - set via ldflags during build
+ Version = "dev"
+ GitCommit = "unknown"
+ BuildDate = "unknown"
+ GoVersion = runtime.Version()
+ Platform = fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)
+)
+
+func NewCommand() *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "version",
+ Short: "Print version information",
+ Long: `Print the version, git commit, build date, and platform information for this binary.`,
+ Run: func(cmd *cobra.Command, args []string) {
+ fmt.Printf("Galactic Version: %s\n", Version)
+ fmt.Printf("Git Commit: %s\n", GitCommit)
+ fmt.Printf("Build Date: %s\n", BuildDate)
+ fmt.Printf("Go Version: %s\n", GoVersion)
+ fmt.Printf("Platform: %s\n", Platform)
+ },
+ }
+
+ return cmd
+}
diff --git a/galactic-cni/cni/cni.go b/internal/cni/cni.go
similarity index 93%
rename from galactic-cni/cni/cni.go
rename to internal/cni/cni.go
index e1684d6..3ad9e38 100644
--- a/galactic-cni/cni/cni.go
+++ b/internal/cni/cni.go
@@ -16,13 +16,13 @@ import (
type100 "github.com/containernetworking/cni/pkg/types/100"
"github.com/containernetworking/cni/pkg/version"
- "github.com/datum-cloud/galactic-cni/cni/registration"
- "github.com/datum-cloud/galactic-cni/cni/route"
- "github.com/datum-cloud/galactic-cni/cni/veth"
- "github.com/datum-cloud/galactic-cni/debug"
- "github.com/datum-cloud/galactic-common/cni"
- "github.com/datum-cloud/galactic-common/util"
- "github.com/datum-cloud/galactic-common/vrf"
+ "go.datum.net/galactic/internal/cni/debug"
+ "go.datum.net/galactic/internal/cni/registration"
+ "go.datum.net/galactic/internal/cni/route"
+ "go.datum.net/galactic/internal/cni/veth"
+ "go.datum.net/galactic/pkg/common/cni"
+ "go.datum.net/galactic/pkg/common/util"
+ "go.datum.net/galactic/pkg/common/vrf"
)
type PluginConf struct {
diff --git a/galactic-cni/debug/debug.go b/internal/cni/debug/debug.go
similarity index 100%
rename from galactic-cni/debug/debug.go
rename to internal/cni/debug/debug.go
diff --git a/galactic-cni/cni/registration/registration.go b/internal/cni/registration/registration.go
similarity index 96%
rename from galactic-cni/cni/registration/registration.go
rename to internal/cni/registration/registration.go
index c210e3f..621608a 100644
--- a/galactic-cni/cni/registration/registration.go
+++ b/internal/cni/registration/registration.go
@@ -8,7 +8,7 @@ import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
- "github.com/datum-cloud/galactic-agent/api/local"
+ "go.datum.net/galactic/pkg/proto/local"
)
const DEFAULT_SOCKET_PATH = "/var/run/galactic/agent.sock"
diff --git a/galactic-cni/cni/route/route.go b/internal/cni/route/route.go
similarity index 92%
rename from galactic-cni/cni/route/route.go
rename to internal/cni/route/route.go
index 2307f25..32a7822 100644
--- a/galactic-cni/cni/route/route.go
+++ b/internal/cni/route/route.go
@@ -7,8 +7,8 @@ import (
"github.com/vishvananda/netlink"
- gutil "github.com/datum-cloud/galactic-common/util"
- "github.com/datum-cloud/galactic-common/vrf"
+ gutil "go.datum.net/galactic/pkg/common/util"
+ "go.datum.net/galactic/pkg/common/vrf"
)
func assembleRoute(vrfId uint32, prefix, nextHop, dev string) (*netlink.Route, error) {
diff --git a/galactic-cni/cni/veth/veth.go b/internal/cni/veth/veth.go
similarity index 95%
rename from galactic-cni/cni/veth/veth.go
rename to internal/cni/veth/veth.go
index 3d76c70..6753a9b 100644
--- a/galactic-cni/cni/veth/veth.go
+++ b/internal/cni/veth/veth.go
@@ -4,9 +4,9 @@ import (
"fmt"
"github.com/coreos/go-iptables/iptables"
- "github.com/datum-cloud/galactic-common/sysctl"
- "github.com/datum-cloud/galactic-common/util"
"github.com/vishvananda/netlink"
+ "go.datum.net/galactic/pkg/common/sysctl"
+ "go.datum.net/galactic/pkg/common/util"
)
func updateForwardRule(interfaceName string, action string) error {
diff --git a/galactic-operator/internal/cniconfig/cniconfig.go b/internal/operator/cniconfig/cniconfig.go
similarity index 94%
rename from galactic-operator/internal/cniconfig/cniconfig.go
rename to internal/operator/cniconfig/cniconfig.go
index 59a8517..88fa555 100644
--- a/galactic-operator/internal/cniconfig/cniconfig.go
+++ b/internal/operator/cniconfig/cniconfig.go
@@ -4,10 +4,10 @@ import (
"fmt"
"net"
- galacticv1alpha "github.com/datum-cloud/galactic-operator/api/v1alpha"
+ galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha"
- "github.com/datum-cloud/galactic-common/cni"
- "github.com/datum-cloud/galactic-common/util"
+ "go.datum.net/galactic/pkg/common/cni"
+ "go.datum.net/galactic/pkg/common/util"
)
// types inlined from CNI and Galactic CNI packages to simplify cross dependencies
diff --git a/galactic-operator/internal/cniconfig/cniconfig_test.go b/internal/operator/cniconfig/cniconfig_test.go
similarity index 93%
rename from galactic-operator/internal/cniconfig/cniconfig_test.go
rename to internal/operator/cniconfig/cniconfig_test.go
index 3b6bf8e..774a634 100644
--- a/galactic-operator/internal/cniconfig/cniconfig_test.go
+++ b/internal/operator/cniconfig/cniconfig_test.go
@@ -7,10 +7,10 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- galacticv1alpha "github.com/datum-cloud/galactic-operator/api/v1alpha"
+ galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha"
- "github.com/datum-cloud/galactic-common/cni"
- "github.com/datum-cloud/galactic-operator/internal/cniconfig"
+ "go.datum.net/galactic/internal/operator/cniconfig"
+ "go.datum.net/galactic/pkg/common/cni"
)
func TestCNIConfigForVPCAttachment(t *testing.T) {
diff --git a/galactic-operator/internal/controller/suite_test.go b/internal/operator/controller/suite_test.go
similarity index 93%
rename from galactic-operator/internal/controller/suite_test.go
rename to internal/operator/controller/suite_test.go
index 0bd35b1..4a72563 100644
--- a/galactic-operator/internal/controller/suite_test.go
+++ b/internal/operator/controller/suite_test.go
@@ -32,7 +32,7 @@ import (
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
- galacticv1alpha "github.com/datum-cloud/galactic-operator/api/v1alpha"
+ galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha"
// +kubebuilder:scaffold:imports
)
@@ -66,7 +66,7 @@ var _ = BeforeSuite(func() {
By("bootstrapping test environment")
testEnv = &envtest.Environment{
- CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases")},
+ CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")},
ErrorIfCRDPathMissing: true,
}
@@ -101,7 +101,7 @@ var _ = AfterSuite(func() {
// setting the 'KUBEBUILDER_ASSETS' environment variable. To ensure the binaries are
// properly set up, run 'make setup-envtest' beforehand.
func getFirstFoundEnvTestBinaryDir() string {
- basePath := filepath.Join("..", "..", "bin", "k8s")
+ basePath := filepath.Join("..", "..", "..", "bin", "k8s")
entries, err := os.ReadDir(basePath)
if err != nil {
logf.Log.Error(err, "Failed to read directory", "path", basePath)
diff --git a/galactic-operator/internal/controller/vpc_controller.go b/internal/operator/controller/vpc_controller.go
similarity index 94%
rename from galactic-operator/internal/controller/vpc_controller.go
rename to internal/operator/controller/vpc_controller.go
index fdb1b3a..4929427 100644
--- a/galactic-operator/internal/controller/vpc_controller.go
+++ b/internal/operator/controller/vpc_controller.go
@@ -9,8 +9,8 @@ import (
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
- galacticv1alpha "github.com/datum-cloud/galactic-operator/api/v1alpha"
- "github.com/datum-cloud/galactic-operator/internal/identifier"
+ "go.datum.net/galactic/internal/operator/identifier"
+ galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha"
)
const MaxIdentifierAttemptsVPC = 100
diff --git a/galactic-operator/internal/controller/vpc_controller_test.go b/internal/operator/controller/vpc_controller_test.go
similarity index 95%
rename from galactic-operator/internal/controller/vpc_controller_test.go
rename to internal/operator/controller/vpc_controller_test.go
index 77dd0be..95e29c3 100644
--- a/galactic-operator/internal/controller/vpc_controller_test.go
+++ b/internal/operator/controller/vpc_controller_test.go
@@ -12,8 +12,8 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- galacticv1alpha "github.com/datum-cloud/galactic-operator/api/v1alpha"
- "github.com/datum-cloud/galactic-operator/internal/identifier"
+ "go.datum.net/galactic/internal/operator/identifier"
+ galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha"
)
var _ = Describe("VPC Controller", func() {
diff --git a/galactic-operator/internal/controller/vpcattachment_controller.go b/internal/operator/controller/vpcattachment_controller.go
similarity index 95%
rename from galactic-operator/internal/controller/vpcattachment_controller.go
rename to internal/operator/controller/vpcattachment_controller.go
index c0f0390..b336c51 100644
--- a/galactic-operator/internal/controller/vpcattachment_controller.go
+++ b/internal/operator/controller/vpcattachment_controller.go
@@ -15,11 +15,11 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- galacticv1alpha "github.com/datum-cloud/galactic-operator/api/v1alpha"
nadv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1"
+ galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha"
- "github.com/datum-cloud/galactic-operator/internal/cniconfig"
- "github.com/datum-cloud/galactic-operator/internal/identifier"
+ "go.datum.net/galactic/internal/operator/cniconfig"
+ "go.datum.net/galactic/internal/operator/identifier"
)
const MaxIdentifierAttemptsVPCAttachment = 100
diff --git a/galactic-operator/internal/controller/vpcattachment_controller_test.go b/internal/operator/controller/vpcattachment_controller_test.go
similarity index 97%
rename from galactic-operator/internal/controller/vpcattachment_controller_test.go
rename to internal/operator/controller/vpcattachment_controller_test.go
index 3c308c7..83d69d1 100644
--- a/galactic-operator/internal/controller/vpcattachment_controller_test.go
+++ b/internal/operator/controller/vpcattachment_controller_test.go
@@ -13,10 +13,10 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- galacticv1alpha "github.com/datum-cloud/galactic-operator/api/v1alpha"
nadv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1"
+ galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha"
- "github.com/datum-cloud/galactic-operator/internal/identifier"
+ "go.datum.net/galactic/internal/operator/identifier"
)
var _ = Describe("VPCAttachment Controller", func() {
diff --git a/galactic-operator/internal/identifier/identifier.go b/internal/operator/identifier/identifier.go
similarity index 100%
rename from galactic-operator/internal/identifier/identifier.go
rename to internal/operator/identifier/identifier.go
diff --git a/galactic-operator/internal/identifier/identifier_test.go b/internal/operator/identifier/identifier_test.go
similarity index 96%
rename from galactic-operator/internal/identifier/identifier_test.go
rename to internal/operator/identifier/identifier_test.go
index d05186f..2f652b6 100644
--- a/galactic-operator/internal/identifier/identifier_test.go
+++ b/internal/operator/identifier/identifier_test.go
@@ -3,7 +3,7 @@ package identifier_test
import (
"testing"
- "github.com/datum-cloud/galactic-operator/internal/identifier"
+ "go.datum.net/galactic/internal/operator/identifier"
)
func TestForVPC(t *testing.T) {
diff --git a/galactic-operator/internal/webhook/v1/pod_webhook.go b/internal/operator/webhook/v1/pod_webhook.go
similarity index 98%
rename from galactic-operator/internal/webhook/v1/pod_webhook.go
rename to internal/operator/webhook/v1/pod_webhook.go
index ef6d03c..b6c9ea6 100644
--- a/galactic-operator/internal/webhook/v1/pod_webhook.go
+++ b/internal/operator/webhook/v1/pod_webhook.go
@@ -14,7 +14,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/webhook"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
- galacticv1alpha "github.com/datum-cloud/galactic-operator/api/v1alpha"
+ galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha"
)
const PodAnnotationMultusNetworks = "k8s.v1.cni.cncf.io/networks"
diff --git a/galactic-operator/internal/webhook/v1/pod_webhook_test.go b/internal/operator/webhook/v1/pod_webhook_test.go
similarity index 97%
rename from galactic-operator/internal/webhook/v1/pod_webhook_test.go
rename to internal/operator/webhook/v1/pod_webhook_test.go
index 247c461..d124832 100644
--- a/galactic-operator/internal/webhook/v1/pod_webhook_test.go
+++ b/internal/operator/webhook/v1/pod_webhook_test.go
@@ -9,7 +9,7 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
- galacticv1alpha "github.com/datum-cloud/galactic-operator/api/v1alpha"
+ galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha"
)
const VPCAttachmentName = "abcd1234"
diff --git a/galactic-operator/internal/webhook/v1/webhook_suite_test.go b/internal/operator/webhook/v1/webhook_suite_test.go
similarity index 96%
rename from galactic-operator/internal/webhook/v1/webhook_suite_test.go
rename to internal/operator/webhook/v1/webhook_suite_test.go
index c1b2e5c..c853384 100644
--- a/galactic-operator/internal/webhook/v1/webhook_suite_test.go
+++ b/internal/operator/webhook/v1/webhook_suite_test.go
@@ -72,11 +72,11 @@ var _ = BeforeSuite(func() {
By("bootstrapping test environment")
testEnv = &envtest.Environment{
- CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")},
+ CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "..", "config", "crd", "bases")},
ErrorIfCRDPathMissing: false,
WebhookInstallOptions: envtest.WebhookInstallOptions{
- Paths: []string{filepath.Join("..", "..", "..", "config", "webhook")},
+ Paths: []string{filepath.Join("..", "..", "..", "..", "config", "webhook")},
},
}
@@ -148,7 +148,7 @@ var _ = AfterSuite(func() {
// setting the 'KUBEBUILDER_ASSETS' environment variable. To ensure the binaries are
// properly set up, run 'make setup-envtest' beforehand.
func getFirstFoundEnvTestBinaryDir() string {
- basePath := filepath.Join("..", "..", "..", "bin", "k8s")
+ basePath := filepath.Join("..", "..", "..", "..", "bin", "k8s")
entries, err := os.ReadDir(basePath)
if err != nil {
logf.Log.Error(err, "Failed to read directory", "path", basePath)
diff --git a/galactic-lab/Dockerfile b/lab/Dockerfile
similarity index 100%
rename from galactic-lab/Dockerfile
rename to lab/Dockerfile
diff --git a/galactic-lab/README.md b/lab/README.md
similarity index 98%
rename from galactic-lab/README.md
rename to lab/README.md
index fd1eba1..36a852f 100644
--- a/galactic-lab/README.md
+++ b/lab/README.md
@@ -99,8 +99,8 @@ Run the lab inside WSL2 on Windows using Docker Engine installed in WSL.
2. **Clone the repo**
```bash
- git clone https://github.com/datum-cloud/galactic-lab.git
- cd galactic-lab
+ git clone https://github.com/datum-cloud/galactic.git
+ cd galactic/lab
```
3. **Install Netlab and dependencies (inside WSL)**
diff --git a/galactic-lab/basic/.gitignore b/lab/basic/.gitignore
similarity index 100%
rename from galactic-lab/basic/.gitignore
rename to lab/basic/.gitignore
diff --git a/galactic-lab/basic/README.md b/lab/basic/README.md
similarity index 100%
rename from galactic-lab/basic/README.md
rename to lab/basic/README.md
diff --git a/galactic-lab/basic/deployment.k8s.yml b/lab/basic/deployment.k8s.yml
similarity index 100%
rename from galactic-lab/basic/deployment.k8s.yml
rename to lab/basic/deployment.k8s.yml
diff --git a/galactic-lab/basic/k01-config.yml b/lab/basic/k01-config.yml
similarity index 100%
rename from galactic-lab/basic/k01-config.yml
rename to lab/basic/k01-config.yml
diff --git a/galactic-lab/basic/topology.svg b/lab/basic/topology.svg
similarity index 100%
rename from galactic-lab/basic/topology.svg
rename to lab/basic/topology.svg
diff --git a/galactic-lab/basic/topology.yml b/lab/basic/topology.yml
similarity index 100%
rename from galactic-lab/basic/topology.yml
rename to lab/basic/topology.yml
diff --git a/galactic-lab/basic/vpc.k8s.yml b/lab/basic/vpc.k8s.yml
similarity index 100%
rename from galactic-lab/basic/vpc.k8s.yml
rename to lab/basic/vpc.k8s.yml
diff --git a/galactic-lab/galactic-lab.code-workspace b/lab/galactic-lab.code-workspace
similarity index 100%
rename from galactic-lab/galactic-lab.code-workspace
rename to lab/galactic-lab.code-workspace
diff --git a/galactic-lab/geo/.gitignore b/lab/geo/.gitignore
similarity index 100%
rename from galactic-lab/geo/.gitignore
rename to lab/geo/.gitignore
diff --git a/galactic-lab/geo/README.md b/lab/geo/README.md
similarity index 100%
rename from galactic-lab/geo/README.md
rename to lab/geo/README.md
diff --git a/galactic-lab/geo/deployment.k8s.yml b/lab/geo/deployment.k8s.yml
similarity index 100%
rename from galactic-lab/geo/deployment.k8s.yml
rename to lab/geo/deployment.k8s.yml
diff --git a/galactic-lab/geo/k01-config.yml b/lab/geo/k01-config.yml
similarity index 100%
rename from galactic-lab/geo/k01-config.yml
rename to lab/geo/k01-config.yml
diff --git a/galactic-lab/geo/topology.svg b/lab/geo/topology.svg
similarity index 100%
rename from galactic-lab/geo/topology.svg
rename to lab/geo/topology.svg
diff --git a/galactic-lab/geo/topology.yml b/lab/geo/topology.yml
similarity index 100%
rename from galactic-lab/geo/topology.yml
rename to lab/geo/topology.yml
diff --git a/galactic-lab/geo/vpc.k8s.yml b/lab/geo/vpc.k8s.yml
similarity index 100%
rename from galactic-lab/geo/vpc.k8s.yml
rename to lab/geo/vpc.k8s.yml
diff --git a/galactic-lab/kindest-node-galactic/Dockerfile b/lab/kindest-node-galactic/Dockerfile
similarity index 100%
rename from galactic-lab/kindest-node-galactic/Dockerfile
rename to lab/kindest-node-galactic/Dockerfile
diff --git a/galactic-lab/kindest-node-galactic/agent.k8s.yml b/lab/kindest-node-galactic/agent.k8s.yml
similarity index 100%
rename from galactic-lab/kindest-node-galactic/agent.k8s.yml
rename to lab/kindest-node-galactic/agent.k8s.yml
diff --git a/galactic-lab/kindest-node-galactic/install.sh b/lab/kindest-node-galactic/install.sh
similarity index 78%
rename from galactic-lab/kindest-node-galactic/install.sh
rename to lab/kindest-node-galactic/install.sh
index f53bf8c..6c13963 100644
--- a/galactic-lab/kindest-node-galactic/install.sh
+++ b/lab/kindest-node-galactic/install.sh
@@ -7,10 +7,7 @@ CILIUM_VERSION="v0.18.8"
CERTMANAGER_VERSION="v1.19.1"
MULTUS_VERSION="v4.2.3"
CNI_PLUGIN_VERSION="v1.8.0"
-GALACTIC_OPERATOR_VERSION="v0.0.5"
-GALACTIC_ROUTER_VERSION="v0.0.5"
-GALACTIC_AGENT_VERSION="v0.0.5"
-GALACTIC_CNI_VERSION="v0.0.5"
+GALACTIC_VERSION="v0.0.5"
ARCH=amd64
if [ "$(uname -m)" = "aarch64" ]; then ARCH=arm64; fi
@@ -37,15 +34,15 @@ if hostname |grep -q control-plane; then # control-plane
kubectl -n galactic-mqtt rollout status deployment galactic-mqtt
# Galactic Operator
- curl -L "https://raw.githubusercontent.com/datum-cloud/galactic-operator/refs/heads/main/dist/install.yaml" |sed -e "s/galactic-operator:latest/galactic-operator:${GALACTIC_OPERATOR_VERSION}/g" |kubectl apply -f -
- kubectl -n galactic-operator-system rollout status deployment galactic-operator-controller-manager
+ curl -L "https://raw.githubusercontent.com/datum-cloud/galactic/refs/heads/main/dist/install.yaml" |sed -e "s/galactic:latest/galactic:${GALACTIC_VERSION}/g" |kubectl apply -f -
+ kubectl -n galactic-system rollout status deployment galactic-controller-manager
# Galactic Router
- cat /galactic/router.k8s.yml |sed -e "s/galactic-router:latest/galactic-router:${GALACTIC_ROUTER_VERSION}/g" |kubectl apply -f -
+ cat /galactic/router.k8s.yml |sed -e "s/galactic-router:latest/galactic-router:${GALACTIC_VERSION}/g" |kubectl apply -f -
kubectl -n galactic-router rollout status deployment galactic-router
# Galactic Agent
- cat /galactic/agent.k8s.yml |sed -e "s/galactic-agent:latest/galactic-agent:${GALACTIC_AGENT_VERSION}/g" |kubectl apply -f -
+ cat /galactic/agent.k8s.yml |sed -e "s/galactic:latest/galactic:${GALACTIC_VERSION}/g" |kubectl apply -f -
kubectl -n galactic-agent rollout status daemonset galactic-agent
else # worker
until journalctl -q -u kubelet -g "Successfully registered node"; do
@@ -74,6 +71,6 @@ else # worker
# CNI Plugins
curl -L "https://github.com/containernetworking/plugins/releases/download/${CNI_PLUGIN_VERSION}/cni-plugins-linux-${ARCH}-${CNI_PLUGIN_VERSION}.tgz" |tar xvfz - -C /opt/cni/bin
- # Galactic CNI
- curl -Lo /opt/cni/bin/galactic "https://github.com/datum-cloud/galactic-cni/releases/download/${GALACTIC_CNI_VERSION}/galactic_${ARCH}" && chmod +x /opt/cni/bin/galactic
+ # Galactic CNI (now bundled in the unified galactic binary)
+ curl -Lo /opt/cni/bin/galactic "https://github.com/datum-cloud/galactic/releases/download/${GALACTIC_VERSION}/galactic_linux_${ARCH}" && chmod +x /opt/cni/bin/galactic
fi
diff --git a/galactic-lab/kindest-node-galactic/mqtt.k8s.yml b/lab/kindest-node-galactic/mqtt.k8s.yml
similarity index 100%
rename from galactic-lab/kindest-node-galactic/mqtt.k8s.yml
rename to lab/kindest-node-galactic/mqtt.k8s.yml
diff --git a/galactic-lab/kindest-node-galactic/router.k8s.yml b/lab/kindest-node-galactic/router.k8s.yml
similarity index 100%
rename from galactic-lab/kindest-node-galactic/router.k8s.yml
rename to lab/kindest-node-galactic/router.k8s.yml
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/.gitignore b/lab/platform/wsl/srv6-vpc-lab-attachment/.gitignore
similarity index 100%
rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/.gitignore
rename to lab/platform/wsl/srv6-vpc-lab-attachment/.gitignore
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/CHANGELOG.md b/lab/platform/wsl/srv6-vpc-lab-attachment/CHANGELOG.md
similarity index 100%
rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/CHANGELOG.md
rename to lab/platform/wsl/srv6-vpc-lab-attachment/CHANGELOG.md
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/README.md b/lab/platform/wsl/srv6-vpc-lab-attachment/README.md
similarity index 96%
rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/README.md
rename to lab/platform/wsl/srv6-vpc-lab-attachment/README.md
index b22f18d..38fff41 100755
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/README.md
+++ b/lab/platform/wsl/srv6-vpc-lab-attachment/README.md
@@ -173,9 +173,9 @@ your containerlab nodes to Datum's SRv6 underlay.
### Setup Steps
```bash
-# 1. Clone the galactic-lab repository
-git clone https://github.com/datum-cloud/galactic-lab.git
-cd galactic-lab
+# 1. Clone the galactic repository
+git clone https://github.com/datum-cloud/galactic.git
+cd galactic
# 2. Install Galactic CRDs and operator on k3s
kubectl apply -f deploy/crds/
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/TUTORIAL.md b/lab/platform/wsl/srv6-vpc-lab-attachment/TUTORIAL.md
similarity index 97%
rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/TUTORIAL.md
rename to lab/platform/wsl/srv6-vpc-lab-attachment/TUTORIAL.md
index 8656801..124e4b2 100755
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/TUTORIAL.md
+++ b/lab/platform/wsl/srv6-vpc-lab-attachment/TUTORIAL.md
@@ -1274,13 +1274,13 @@ go version
# Expected: go version go1.23.4 linux/amd64
```
-### 10.2 Clone Galactic-Agent Repository
+### 10.2 Clone Galactic Repository
```bash
# Clone into your galantic-vpc directory (keeps everything together for git)
cd ~/datum/galantic-vpc
-git clone https://github.com/datum-cloud/galactic-agent.git
-cd galactic-agent
+git clone https://github.com/datum-cloud/galactic.git
+cd galactic
```
### 10.3 Build the Agent
@@ -1288,11 +1288,11 @@ cd galactic-agent
```bash
# Download dependencies and build
go mod download
-go build -o galactic-agent .
+go build -o galactic ./cmd/galactic
# Verify binary was created
-ls -la galactic-agent
-# Expected: -rwxr-xr-x 1 sonic sonic 20196174 Jan 14 14:05 galactic-agent
+ls -la galactic
+# Expected: -rwxr-xr-x 1 sonic sonic 20196174 Jan 14 14:05 galactic
```
### 10.4 Install MQTT Broker (Mosquitto)
@@ -1357,7 +1357,7 @@ sudo mkdir -p /var/run/galactic
sudo chmod 777 /var/run/galactic
# Run the agent (requires sudo for NET_ADMIN capability)
-sudo ./galactic-agent --config config.yaml
+sudo ./galactic agent --config config.yaml
```
**Expected Output:**
@@ -1638,7 +1638,7 @@ To connect your local WSL lab to Datum's production infrastructure, update the a
### 11.1 Update Agent Configuration for Datum Cloud
```bash
-cd ~/datum/galantic-vpc/galactic-agent
+cd ~/datum/galantic-vpc/galactic
# Create production config
cat > config-datum.yaml << 'EOF'
@@ -1671,7 +1671,7 @@ EOF
```bash
# Stop local agent if running (Ctrl+C)
# Run with Datum config
-sudo ./galactic-agent --config config-datum.yaml
+sudo ./galactic agent --config config-datum.yaml
```
### 11.4 End-to-End Architecture with Datum Cloud
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/agent.yaml b/lab/platform/wsl/srv6-vpc-lab-attachment/agent.yaml
similarity index 100%
rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/agent.yaml
rename to lab/platform/wsl/srv6-vpc-lab-attachment/agent.yaml
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/filter_plugins/netlab_filters.py b/lab/platform/wsl/srv6-vpc-lab-attachment/filter_plugins/netlab_filters.py
similarity index 100%
rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/filter_plugins/netlab_filters.py
rename to lab/platform/wsl/srv6-vpc-lab-attachment/filter_plugins/netlab_filters.py
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent-config.yaml b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent-config.yaml
similarity index 97%
rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent-config.yaml
rename to lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent-config.yaml
index 947a2ae..c2b2ae7 100755
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent-config.yaml
+++ b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent-config.yaml
@@ -169,7 +169,7 @@ mqtt_topic_send: "galactic/register"
# The galactic-agent uses Protocol Buffers for MQTT messages. Here are the
# actual message definitions from the Datum galactic-agent source code:
#
-# Source: https://github.com/datum-cloud/galactic-agent/blob/main/api/remote/remote.proto
+# Source: https://github.com/datum-cloud/galactic/blob/main/internal/api/remote/remote.proto
#
# message Envelope {
# oneof kind {
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-manifest.yaml b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-manifest.yaml
similarity index 100%
rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-manifest.yaml
rename to lab/platform/wsl/srv6-vpc-lab-attachment/galactic-manifest.yaml
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/run_lab_demo.py b/lab/platform/wsl/srv6-vpc-lab-attachment/run_lab_demo.py
similarity index 100%
rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/run_lab_demo.py
rename to lab/platform/wsl/srv6-vpc-lab-attachment/run_lab_demo.py
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/setup_wsl_lab.py b/lab/platform/wsl/srv6-vpc-lab-attachment/setup_wsl_lab.py
similarity index 92%
rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/setup_wsl_lab.py
rename to lab/platform/wsl/srv6-vpc-lab-attachment/setup_wsl_lab.py
index 2160d09..f117de3 100755
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/setup_wsl_lab.py
+++ b/lab/platform/wsl/srv6-vpc-lab-attachment/setup_wsl_lab.py
@@ -34,8 +34,8 @@
# 3. Installs Ubuntu 22.04 in WSL
# 4. Installs Docker Engine inside WSL (NOT Docker Desktop)
# 5. Installs Containerlab and Netlab
-# 6. Installs Go 1.23+ for galactic-agent
-# 7. Clones and builds galactic-agent
+# 6. Installs Go 1.23+ for galactic
+# 7. Clones and builds galactic
# 8. Installs Mosquitto MQTT broker
# 9. Copies topology files to WSL
# 10. Starts the lab topology
@@ -466,25 +466,25 @@ def clone_galactic_agent():
print_header("Setting Up Galactic Agent")
# Check if already cloned
- print_step(1, "Checking existing galactic-agent...")
- result = run_wsl("ls ~/datum/galantic-vpc/galactic-agent/main.go", distro=WSL_DISTRO)
+ print_step(1, "Checking existing galactic...")
+ result = run_wsl("ls ~/datum/galantic-vpc/galactic/cmd/galactic/main.go", distro=WSL_DISTRO)
if result.returncode == 0:
- print_success("galactic-agent already exists")
+ print_success("galactic already exists")
else:
- # Clone galactic-agent
- print_step(2, "Cloning galactic-agent...")
- clone_cmd = "cd ~/datum/galantic-vpc && git clone https://github.com/datum-cloud/galactic-agent.git"
+ # Clone galactic
+ print_step(2, "Cloning galactic...")
+ clone_cmd = "cd ~/datum/galantic-vpc && git clone https://github.com/datum-cloud/galactic.git"
run_wsl(clone_cmd, distro=WSL_DISTRO)
- # Build galactic-agent
- print_step(3, "Building galactic-agent...")
- build_cmd = "cd ~/datum/galantic-vpc/galactic-agent && /usr/local/go/bin/go mod download && /usr/local/go/bin/go build -o galactic-agent ."
+ # Build galactic
+ print_step(3, "Building galactic...")
+ build_cmd = "cd ~/datum/galantic-vpc/galactic && /usr/local/go/bin/go mod download && /usr/local/go/bin/go build -o galactic ./cmd/galactic"
result = run_wsl(build_cmd, distro=WSL_DISTRO)
-
+
if result.returncode == 0:
- print_success("galactic-agent built successfully")
+ print_success("galactic built successfully")
else:
- print_warning("galactic-agent build may have issues, check manually")
+ print_warning("galactic build may have issues, check manually")
return True
@@ -506,9 +506,9 @@ def print_final_instructions():
3. Start the lab topology:
{Colors.CYAN}sudo netlab up{Colors.ENDC}
-4. In another terminal, start the galactic-agent:
- {Colors.CYAN}cd ~/datum/galantic-vpc/galactic-agent
- sudo ./galactic-agent -config ../galactic-agent-config.yaml{Colors.ENDC}
+4. In another terminal, start the galactic agent:
+ {Colors.CYAN}cd ~/datum/galantic-vpc/galactic
+ sudo ./galactic agent --config ../galactic-agent-config.yaml{Colors.ENDC}
5. Test MQTT route injection:
{Colors.CYAN}cd ~/datum/galantic-vpc
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/test-mqtt-route.go b/lab/platform/wsl/srv6-vpc-lab-attachment/test-mqtt-route.go
similarity index 93%
rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/test-mqtt-route.go
rename to lab/platform/wsl/srv6-vpc-lab-attachment/test-mqtt-route.go
index c4072b7..4d97303 100755
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/test-mqtt-route.go
+++ b/lab/platform/wsl/srv6-vpc-lab-attachment/test-mqtt-route.go
@@ -1,317 +1,317 @@
-// =============================================================================
-// Test MQTT Route Injection for Galactic Agent
-// =============================================================================
-// Author: Sajjad Ahmed
-// Company: Multi Naturals Inc.
-// Created: January 2026
-//
-// PURPOSE:
-// This script creates a properly encoded protobuf message and publishes it
-// to the local MQTT broker. The galactic-agent will receive this message
-// and program the route into the WSL2 Linux kernel.
-//
-// USAGE:
-// cd ~/datum/galantic-vpc
-// go run test-mqtt-route.go
-//
-// PREREQUISITES:
-// - Mosquitto MQTT broker running: sudo systemctl start mosquitto
-// - galactic-agent running: sudo ./galactic-agent/galactic-agent --config galactic-agent-config.yaml
-//
-// HOW IT WORKS:
-// The galactic-agent expects protobuf-encoded messages. This script manually
-// encodes the protobuf binary format based on the remote.proto definitions.
-//
-// Protobuf wire format:
-// - Field 1 (network): tag=0x0a, length-delimited string
-// - Field 2 (srv6_endpoint): tag=0x12, length-delimited string
-// - Field 3 (srv6_segments): tag=0x1a, length-delimited string (repeated)
-// - Field 4 (status): tag=0x20, varint (0=ADD, 1=DELETE)
-//
-// Envelope wraps Route in field 3: tag=0x1a
-//
-// =============================================================================
-
-package main
-
-import (
- "encoding/hex"
- "fmt"
- "os"
- "os/exec"
- "strings"
-)
-
-// encodeString creates a protobuf length-delimited string field
-func encodeString(fieldNum int, value string) []byte {
- tag := byte((fieldNum << 3) | 2) // wire type 2 = length-delimited
- length := byte(len(value))
- result := []byte{tag, length}
- result = append(result, []byte(value)...)
- return result
-}
-
-// encodeVarint creates a protobuf varint field
-func encodeVarint(fieldNum int, value int) []byte {
- tag := byte((fieldNum << 3) | 0) // wire type 0 = varint
- return []byte{tag, byte(value)}
-}
-
-// encodeRoute creates a protobuf-encoded Route message
-func encodeRoute(network, srv6Endpoint string, srv6Segments []string, status int) []byte {
- var route []byte
-
- // Field 1: network (string)
- route = append(route, encodeString(1, network)...)
-
- // Field 2: srv6_endpoint (string)
- route = append(route, encodeString(2, srv6Endpoint)...)
-
- // Field 3: srv6_segments (repeated string)
- for _, seg := range srv6Segments {
- route = append(route, encodeString(3, seg)...)
- }
-
- // Field 4: status (enum/varint, 0=ADD, 1=DELETE)
- route = append(route, encodeVarint(4, status)...)
-
- return route
-}
-
-// generateSRv6Endpoint creates a properly formatted SRv6 endpoint
-// The galactic-agent expects VPC ID (48 bits) and VPCAttachment ID (16 bits)
-// encoded in the lower 64 bits of the IPv6 address.
-//
-// Format: fc00:XXXX:XXXX:XXXX:VVVV:VVVV:VVVV:AAAA
-// - fc00::/16 = SRv6 prefix
-// - VVVV:VVVV:VVVV = VPC ID (48 bits, hex)
-// - AAAA = VPCAttachment ID (16 bits, hex)
-//
-// Example: fc00::0001:0000:0000:0001 = VPC=000000000001, VPCAttachment=0001
-func generateSRv6Endpoint(vpcHex string, vpcAttachmentHex string) string {
- // Pad VPC to 12 hex chars (48 bits)
- for len(vpcHex) < 12 {
- vpcHex = "0" + vpcHex
- }
- // Pad VPCAttachment to 4 hex chars (16 bits)
- for len(vpcAttachmentHex) < 4 {
- vpcAttachmentHex = "0" + vpcAttachmentHex
- }
-
- // Build IPv6: fc00:0000:0000:0000:VVVV:VVVV:VVVV:AAAA
- // VPC goes in bytes 8-13, VPCAttachment in bytes 14-15
- return fmt.Sprintf("fc00::%s:%s:%s:%s",
- vpcHex[0:4], vpcHex[4:8], vpcHex[8:12], vpcAttachmentHex)
-}
-
-// encodeEnvelope wraps a Route in an Envelope (field 3)
-func encodeEnvelope(route []byte) []byte {
- // Envelope field 3 = Route
- tag := byte((3 << 3) | 2) // field 3, wire type 2 (length-delimited)
- length := byte(len(route))
- result := []byte{tag, length}
- result = append(result, route...)
- return result
-}
-
-// createVRF creates a VRF interface for the given VPC and attachment
-// VRF = Virtual Routing and Forwarding - provides network isolation (Private Cloud)
-// Each VPC gets its own VRF with isolated routing table
-func createVRF(vpcHex, attachmentHex string, tableID int) (string, error) {
- // The agent expects VRF interface name format: G{vpc_base62}{attachment_base62}V
- // For simplicity, we use the hex values directly (agent converts hex to base62)
- // But the lookup uses: first 9 chars of vpc + first 3 chars of attachment + "V"
- vrfName := fmt.Sprintf("G%09s%03sV", vpcHex[len(vpcHex)-9:], attachmentHex[len(attachmentHex)-3:])
-
- fmt.Printf("\n🔧 Creating VRF: %s (table %d)\n", vrfName, tableID)
-
- // Check if VRF already exists
- checkCmd := exec.Command("ip", "link", "show", vrfName)
- if err := checkCmd.Run(); err == nil {
- fmt.Printf(" ✅ VRF %s already exists\n", vrfName)
- return vrfName, nil
- }
-
- // Create VRF interface
- // sudo ip link add type vrf table
- createCmd := exec.Command("sudo", "ip", "link", "add", vrfName, "type", "vrf", "table", fmt.Sprintf("%d", tableID))
- if output, err := createCmd.CombinedOutput(); err != nil {
- return "", fmt.Errorf("failed to create VRF: %v, output: %s", err, output)
- }
-
- // Bring VRF interface up
- upCmd := exec.Command("sudo", "ip", "link", "set", vrfName, "up")
- if output, err := upCmd.CombinedOutput(); err != nil {
- return "", fmt.Errorf("failed to bring up VRF: %v, output: %s", err, output)
- }
-
- fmt.Printf(" ✅ VRF %s created successfully\n", vrfName)
- return vrfName, nil
-}
-
-func main() {
- fmt.Println("=" + strings.Repeat("=", 69))
- fmt.Println(" Galactic Agent MQTT Route Injection Test")
- fmt.Println(" Author: Sajjad Ahmed, Multi Naturals Inc.")
- fmt.Println("=" + strings.Repeat("=", 69))
-
- // ==========================================================================
- // WHAT IS A VRF? (Virtual Routing and Forwarding)
- // ==========================================================================
- // A VRF is like a "virtual router" inside Linux. Each VRF has:
- // - Its own routing table (isolated from other VRFs)
- // - Its own interfaces
- // - Its own route policies
- //
- // PRIVATE CLOUD = VPC = VRF
- // When we say "Private Cloud", we mean your traffic is isolated from others.
- // Each customer/tenant gets their own VRF with their own routing table.
- //
- // In Datum's architecture:
- // - VPC ID identifies the customer's virtual private cloud
- // - VPCAttachment ID identifies a specific attachment point (POP location)
- // - Together they create a unique VRF: G{vpc}{attachment}V
- // ==========================================================================
-
- // ==========================================================================
- // SRv6 Endpoint Format for galactic-agent
- // ==========================================================================
- // The agent expects VPC ID (48 bits) and VPCAttachment ID (16 bits) encoded
- // in the lower 64 bits of the IPv6 address:
- // fc00:0000:0000:0000:VVVV:VVVV:VVVV:AAAA
- //
- // We use:
- // VPC ID = "000000000001" (hex) = test VPC
- // VPCAttachment ID = "0001" (hex) for AMS, "0002" for IAD
- // ==========================================================================
-
- vpcID := "000000000001" // Test VPC ID (48 bits hex)
- amsAttachment := "0001" // AMS VPCAttachment ID
- iadAttachment := "0002" // IAD VPCAttachment ID
-
- amsEndpoint := generateSRv6Endpoint(vpcID, amsAttachment)
- iadEndpoint := generateSRv6Endpoint(vpcID, iadAttachment)
-
- fmt.Printf("\n📋 SRv6 Endpoint Encoding:\n")
- fmt.Printf(" VPC ID: %s\n", vpcID)
- fmt.Printf(" AMS Attachment: %s → %s\n", amsAttachment, amsEndpoint)
- fmt.Printf(" IAD Attachment: %s → %s\n", iadAttachment, iadEndpoint)
-
- // ==========================================================================
- // STEP 0: Create VRF interfaces (simulates CNI registration)
- // ==========================================================================
- // In production, the CNI plugin creates these VRFs when pods are scheduled.
- // For testing, we create them manually to simulate a "Private Cloud" setup.
- // ==========================================================================
- fmt.Println("\n" + strings.Repeat("=", 70))
- fmt.Println("🏗️ STEP 0: Creating VRF interfaces (Private Cloud setup)")
- fmt.Println(strings.Repeat("=", 70))
-
- amsVRF, err := createVRF(vpcID, amsAttachment, 100)
- if err != nil {
- fmt.Printf(" ⚠️ Warning: %v\n", err)
- fmt.Println(" Run with sudo or create VRF manually:")
- fmt.Printf(" sudo ip link add G%09s%03sV type vrf table 100\n", vpcID[len(vpcID)-9:], amsAttachment[len(amsAttachment)-3:])
- }
-
- iadVRF, err := createVRF(vpcID, iadAttachment, 101)
- if err != nil {
- fmt.Printf(" ⚠️ Warning: %v\n", err)
- }
-
- _ = amsVRF
- _ = iadVRF
-
- // ==========================================================================
- // TEST 1: Add route to AMS (192.168.2.0/24)
- // ==========================================================================
- route1 := encodeRoute(
- "192.168.2.0/24", // network
- amsEndpoint, // srv6_endpoint (AMS with proper encoding)
- []string{amsEndpoint}, // srv6_segments
- 0, // status: ADD
- )
- envelope1 := encodeEnvelope(route1)
-
- fmt.Println("\n📤 TEST 1: Add route to AMS")
- fmt.Printf(" Network: 192.168.2.0/24\n")
- fmt.Printf(" SRv6 Endpoint: %s\n", amsEndpoint)
- fmt.Printf(" Segments: [%s]\n", amsEndpoint)
- fmt.Printf(" Status: ADD (0)\n")
- fmt.Printf(" Binary (hex): %s\n", hex.EncodeToString(envelope1))
- fmt.Printf(" Binary size: %d bytes\n", len(envelope1))
-
- // Save to file and publish via mosquitto_pub
- publishToMQTT("galactic/routes/wsl", envelope1, "route_ams.bin")
-
- // ==========================================================================
- // TEST 2: Add route to IAD (192.168.3.0/24)
- // ==========================================================================
- route2 := encodeRoute(
- "192.168.3.0/24", // network
- iadEndpoint, // srv6_endpoint (IAD with proper encoding)
- []string{iadEndpoint}, // srv6_segments
- 0, // status: ADD
- )
- envelope2 := encodeEnvelope(route2)
-
- fmt.Println("\n📤 TEST 2: Add route to IAD")
- fmt.Printf(" Network: 192.168.3.0/24\n")
- fmt.Printf(" SRv6 Endpoint: %s\n", iadEndpoint)
- fmt.Printf(" Segments: [%s]\n", iadEndpoint)
- fmt.Printf(" Status: ADD (0)\n")
- fmt.Printf(" Binary (hex): %s\n", hex.EncodeToString(envelope2))
-
- publishToMQTT("galactic/routes/wsl", envelope2, "route_iad.bin")
-
- // ==========================================================================
- // Verification commands
- // ==========================================================================
- fmt.Println("\n" + strings.Repeat("=", 70))
- fmt.Println("🔍 VERIFICATION: Run these commands to check if routes were added:")
- fmt.Println(strings.Repeat("=", 70))
- fmt.Println("")
- fmt.Println(" # Check VRF interfaces were created:")
- fmt.Println(" ip link show type vrf")
- fmt.Println("")
- fmt.Println(" # Check routes in VRF tables (100 for AMS, 101 for IAD):")
- fmt.Println(" ip -6 route show table 100")
- fmt.Println(" ip -6 route show table 101")
- fmt.Println("")
- fmt.Println(" # Check all SRv6 encapsulated routes:")
- fmt.Println(" ip -6 route show table all | grep 'encap seg6'")
- fmt.Println("")
- fmt.Println(" # Check main routing table:")
- fmt.Println(" ip -6 route show | grep -E '192.168.2|192.168.3'")
- fmt.Println(strings.Repeat("=", 70))
-}
-
-// publishToMQTT saves binary to file and publishes via mosquitto_pub
-func publishToMQTT(topic string, data []byte, filename string) {
- // Write binary to /tmp with world-writable permissions
- tmpFile := "/tmp/" + filename
-
- // Write binary data directly to file (0777 for any user to read/write)
- err := os.WriteFile(tmpFile, data, 0777)
- if err != nil {
- fmt.Printf(" ❌ Failed to create binary file: %v\n", err)
- // Provide manual command as fallback
- hexStr := ""
- for _, b := range data {
- hexStr += fmt.Sprintf("\\x%02x", b)
- }
- fmt.Printf(" Manual command: printf '%s' > %s\n", hexStr, tmpFile)
- return
- }
-
- // Publish using mosquitto_pub with file input
- cmd := exec.Command("mosquitto_pub", "-h", "localhost", "-t", topic, "-f", tmpFile)
- err = cmd.Run()
- if err != nil {
- fmt.Printf(" ❌ Failed to publish: %v\n", err)
- fmt.Printf(" Manual command: mosquitto_pub -h localhost -t %s -f %s\n", topic, tmpFile)
- return
- }
-
- fmt.Printf(" ✅ Published to topic: %s\n", topic)
-}
+// =============================================================================
+// Test MQTT Route Injection for Galactic Agent
+// =============================================================================
+// Author: Sajjad Ahmed
+// Company: Multi Naturals Inc.
+// Created: January 2026
+//
+// PURPOSE:
+// This script creates a properly encoded protobuf message and publishes it
+// to the local MQTT broker. The galactic-agent will receive this message
+// and program the route into the WSL2 Linux kernel.
+//
+// USAGE:
+// cd ~/datum/galantic-vpc
+// go run test-mqtt-route.go
+//
+// PREREQUISITES:
+// - Mosquitto MQTT broker running: sudo systemctl start mosquitto
+// - galactic-agent running: sudo ./galactic-agent/galactic-agent --config galactic-agent-config.yaml
+//
+// HOW IT WORKS:
+// The galactic-agent expects protobuf-encoded messages. This script manually
+// encodes the protobuf binary format based on the remote.proto definitions.
+//
+// Protobuf wire format:
+// - Field 1 (network): tag=0x0a, length-delimited string
+// - Field 2 (srv6_endpoint): tag=0x12, length-delimited string
+// - Field 3 (srv6_segments): tag=0x1a, length-delimited string (repeated)
+// - Field 4 (status): tag=0x20, varint (0=ADD, 1=DELETE)
+//
+// Envelope wraps Route in field 3: tag=0x1a
+//
+// =============================================================================
+
+package main
+
+import (
+ "encoding/hex"
+ "fmt"
+ "os"
+ "os/exec"
+ "strings"
+)
+
+// encodeString creates a protobuf length-delimited string field
+func encodeString(fieldNum int, value string) []byte {
+ tag := byte((fieldNum << 3) | 2) // wire type 2 = length-delimited
+ length := byte(len(value))
+ result := []byte{tag, length}
+ result = append(result, []byte(value)...)
+ return result
+}
+
+// encodeVarint creates a protobuf varint field
+func encodeVarint(fieldNum int, value int) []byte {
+ tag := byte((fieldNum << 3) | 0) // wire type 0 = varint
+ return []byte{tag, byte(value)}
+}
+
+// encodeRoute creates a protobuf-encoded Route message
+func encodeRoute(network, srv6Endpoint string, srv6Segments []string, status int) []byte {
+ var route []byte
+
+ // Field 1: network (string)
+ route = append(route, encodeString(1, network)...)
+
+ // Field 2: srv6_endpoint (string)
+ route = append(route, encodeString(2, srv6Endpoint)...)
+
+ // Field 3: srv6_segments (repeated string)
+ for _, seg := range srv6Segments {
+ route = append(route, encodeString(3, seg)...)
+ }
+
+ // Field 4: status (enum/varint, 0=ADD, 1=DELETE)
+ route = append(route, encodeVarint(4, status)...)
+
+ return route
+}
+
+// generateSRv6Endpoint creates a properly formatted SRv6 endpoint
+// The galactic-agent expects VPC ID (48 bits) and VPCAttachment ID (16 bits)
+// encoded in the lower 64 bits of the IPv6 address.
+//
+// Format: fc00:XXXX:XXXX:XXXX:VVVV:VVVV:VVVV:AAAA
+// - fc00::/16 = SRv6 prefix
+// - VVVV:VVVV:VVVV = VPC ID (48 bits, hex)
+// - AAAA = VPCAttachment ID (16 bits, hex)
+//
+// Example: fc00::0001:0000:0000:0001 = VPC=000000000001, VPCAttachment=0001
+func generateSRv6Endpoint(vpcHex string, vpcAttachmentHex string) string {
+ // Pad VPC to 12 hex chars (48 bits)
+ for len(vpcHex) < 12 {
+ vpcHex = "0" + vpcHex
+ }
+ // Pad VPCAttachment to 4 hex chars (16 bits)
+ for len(vpcAttachmentHex) < 4 {
+ vpcAttachmentHex = "0" + vpcAttachmentHex
+ }
+
+ // Build IPv6: fc00:0000:0000:0000:VVVV:VVVV:VVVV:AAAA
+ // VPC goes in bytes 8-13, VPCAttachment in bytes 14-15
+ return fmt.Sprintf("fc00::%s:%s:%s:%s",
+ vpcHex[0:4], vpcHex[4:8], vpcHex[8:12], vpcAttachmentHex)
+}
+
+// encodeEnvelope wraps a Route in an Envelope (field 3)
+func encodeEnvelope(route []byte) []byte {
+ // Envelope field 3 = Route
+ tag := byte((3 << 3) | 2) // field 3, wire type 2 (length-delimited)
+ length := byte(len(route))
+ result := []byte{tag, length}
+ result = append(result, route...)
+ return result
+}
+
+// createVRF creates a VRF interface for the given VPC and attachment
+// VRF = Virtual Routing and Forwarding - provides network isolation (Private Cloud)
+// Each VPC gets its own VRF with isolated routing table
+func createVRF(vpcHex, attachmentHex string, tableID int) (string, error) {
+ // The agent expects VRF interface name format: G{vpc_base62}{attachment_base62}V
+ // For simplicity, we use the hex values directly (agent converts hex to base62)
+ // But the lookup uses: first 9 chars of vpc + first 3 chars of attachment + "V"
+ vrfName := fmt.Sprintf("G%09s%03sV", vpcHex[len(vpcHex)-9:], attachmentHex[len(attachmentHex)-3:])
+
+ fmt.Printf("\n🔧 Creating VRF: %s (table %d)\n", vrfName, tableID)
+
+ // Check if VRF already exists
+ checkCmd := exec.Command("ip", "link", "show", vrfName)
+ if err := checkCmd.Run(); err == nil {
+ fmt.Printf(" ✅ VRF %s already exists\n", vrfName)
+ return vrfName, nil
+ }
+
+ // Create VRF interface
+ // sudo ip link add type vrf table
+ createCmd := exec.Command("sudo", "ip", "link", "add", vrfName, "type", "vrf", "table", fmt.Sprintf("%d", tableID))
+ if output, err := createCmd.CombinedOutput(); err != nil {
+ return "", fmt.Errorf("failed to create VRF: %v, output: %s", err, output)
+ }
+
+ // Bring VRF interface up
+ upCmd := exec.Command("sudo", "ip", "link", "set", vrfName, "up")
+ if output, err := upCmd.CombinedOutput(); err != nil {
+ return "", fmt.Errorf("failed to bring up VRF: %v, output: %s", err, output)
+ }
+
+ fmt.Printf(" ✅ VRF %s created successfully\n", vrfName)
+ return vrfName, nil
+}
+
+func main() {
+ fmt.Println("=" + strings.Repeat("=", 69))
+ fmt.Println(" Galactic Agent MQTT Route Injection Test")
+ fmt.Println(" Author: Sajjad Ahmed, Multi Naturals Inc.")
+ fmt.Println("=" + strings.Repeat("=", 69))
+
+ // ==========================================================================
+ // WHAT IS A VRF? (Virtual Routing and Forwarding)
+ // ==========================================================================
+ // A VRF is like a "virtual router" inside Linux. Each VRF has:
+ // - Its own routing table (isolated from other VRFs)
+ // - Its own interfaces
+ // - Its own route policies
+ //
+ // PRIVATE CLOUD = VPC = VRF
+ // When we say "Private Cloud", we mean your traffic is isolated from others.
+ // Each customer/tenant gets their own VRF with their own routing table.
+ //
+ // In Datum's architecture:
+ // - VPC ID identifies the customer's virtual private cloud
+ // - VPCAttachment ID identifies a specific attachment point (POP location)
+ // - Together they create a unique VRF: G{vpc}{attachment}V
+ // ==========================================================================
+
+ // ==========================================================================
+ // SRv6 Endpoint Format for galactic-agent
+ // ==========================================================================
+ // The agent expects VPC ID (48 bits) and VPCAttachment ID (16 bits) encoded
+ // in the lower 64 bits of the IPv6 address:
+ // fc00:0000:0000:0000:VVVV:VVVV:VVVV:AAAA
+ //
+ // We use:
+ // VPC ID = "000000000001" (hex) = test VPC
+ // VPCAttachment ID = "0001" (hex) for AMS, "0002" for IAD
+ // ==========================================================================
+
+ vpcID := "000000000001" // Test VPC ID (48 bits hex)
+ amsAttachment := "0001" // AMS VPCAttachment ID
+ iadAttachment := "0002" // IAD VPCAttachment ID
+
+ amsEndpoint := generateSRv6Endpoint(vpcID, amsAttachment)
+ iadEndpoint := generateSRv6Endpoint(vpcID, iadAttachment)
+
+ fmt.Printf("\n📋 SRv6 Endpoint Encoding:\n")
+ fmt.Printf(" VPC ID: %s\n", vpcID)
+ fmt.Printf(" AMS Attachment: %s → %s\n", amsAttachment, amsEndpoint)
+ fmt.Printf(" IAD Attachment: %s → %s\n", iadAttachment, iadEndpoint)
+
+ // ==========================================================================
+ // STEP 0: Create VRF interfaces (simulates CNI registration)
+ // ==========================================================================
+ // In production, the CNI plugin creates these VRFs when pods are scheduled.
+ // For testing, we create them manually to simulate a "Private Cloud" setup.
+ // ==========================================================================
+ fmt.Println("\n" + strings.Repeat("=", 70))
+ fmt.Println("🏗️ STEP 0: Creating VRF interfaces (Private Cloud setup)")
+ fmt.Println(strings.Repeat("=", 70))
+
+ amsVRF, err := createVRF(vpcID, amsAttachment, 100)
+ if err != nil {
+ fmt.Printf(" ⚠️ Warning: %v\n", err)
+ fmt.Println(" Run with sudo or create VRF manually:")
+ fmt.Printf(" sudo ip link add G%09s%03sV type vrf table 100\n", vpcID[len(vpcID)-9:], amsAttachment[len(amsAttachment)-3:])
+ }
+
+ iadVRF, err := createVRF(vpcID, iadAttachment, 101)
+ if err != nil {
+ fmt.Printf(" ⚠️ Warning: %v\n", err)
+ }
+
+ _ = amsVRF
+ _ = iadVRF
+
+ // ==========================================================================
+ // TEST 1: Add route to AMS (192.168.2.0/24)
+ // ==========================================================================
+ route1 := encodeRoute(
+ "192.168.2.0/24", // network
+ amsEndpoint, // srv6_endpoint (AMS with proper encoding)
+ []string{amsEndpoint}, // srv6_segments
+ 0, // status: ADD
+ )
+ envelope1 := encodeEnvelope(route1)
+
+ fmt.Println("\n📤 TEST 1: Add route to AMS")
+ fmt.Printf(" Network: 192.168.2.0/24\n")
+ fmt.Printf(" SRv6 Endpoint: %s\n", amsEndpoint)
+ fmt.Printf(" Segments: [%s]\n", amsEndpoint)
+ fmt.Printf(" Status: ADD (0)\n")
+ fmt.Printf(" Binary (hex): %s\n", hex.EncodeToString(envelope1))
+ fmt.Printf(" Binary size: %d bytes\n", len(envelope1))
+
+ // Save to file and publish via mosquitto_pub
+ publishToMQTT("galactic/routes/wsl", envelope1, "route_ams.bin")
+
+ // ==========================================================================
+ // TEST 2: Add route to IAD (192.168.3.0/24)
+ // ==========================================================================
+ route2 := encodeRoute(
+ "192.168.3.0/24", // network
+ iadEndpoint, // srv6_endpoint (IAD with proper encoding)
+ []string{iadEndpoint}, // srv6_segments
+ 0, // status: ADD
+ )
+ envelope2 := encodeEnvelope(route2)
+
+ fmt.Println("\n📤 TEST 2: Add route to IAD")
+ fmt.Printf(" Network: 192.168.3.0/24\n")
+ fmt.Printf(" SRv6 Endpoint: %s\n", iadEndpoint)
+ fmt.Printf(" Segments: [%s]\n", iadEndpoint)
+ fmt.Printf(" Status: ADD (0)\n")
+ fmt.Printf(" Binary (hex): %s\n", hex.EncodeToString(envelope2))
+
+ publishToMQTT("galactic/routes/wsl", envelope2, "route_iad.bin")
+
+ // ==========================================================================
+ // Verification commands
+ // ==========================================================================
+ fmt.Println("\n" + strings.Repeat("=", 70))
+ fmt.Println("🔍 VERIFICATION: Run these commands to check if routes were added:")
+ fmt.Println(strings.Repeat("=", 70))
+ fmt.Println("")
+ fmt.Println(" # Check VRF interfaces were created:")
+ fmt.Println(" ip link show type vrf")
+ fmt.Println("")
+ fmt.Println(" # Check routes in VRF tables (100 for AMS, 101 for IAD):")
+ fmt.Println(" ip -6 route show table 100")
+ fmt.Println(" ip -6 route show table 101")
+ fmt.Println("")
+ fmt.Println(" # Check all SRv6 encapsulated routes:")
+ fmt.Println(" ip -6 route show table all | grep 'encap seg6'")
+ fmt.Println("")
+ fmt.Println(" # Check main routing table:")
+ fmt.Println(" ip -6 route show | grep -E '192.168.2|192.168.3'")
+ fmt.Println(strings.Repeat("=", 70))
+}
+
+// publishToMQTT saves binary to file and publishes via mosquitto_pub
+func publishToMQTT(topic string, data []byte, filename string) {
+ // Write binary to /tmp with world-writable permissions
+ tmpFile := "/tmp/" + filename
+
+ // Write binary data directly to file (0777 for any user to read/write)
+ err := os.WriteFile(tmpFile, data, 0777)
+ if err != nil {
+ fmt.Printf(" ❌ Failed to create binary file: %v\n", err)
+ // Provide manual command as fallback
+ hexStr := ""
+ for _, b := range data {
+ hexStr += fmt.Sprintf("\\x%02x", b)
+ }
+ fmt.Printf(" Manual command: printf '%s' > %s\n", hexStr, tmpFile)
+ return
+ }
+
+ // Publish using mosquitto_pub with file input
+ cmd := exec.Command("mosquitto_pub", "-h", "localhost", "-t", topic, "-f", tmpFile)
+ err = cmd.Run()
+ if err != nil {
+ fmt.Printf(" ❌ Failed to publish: %v\n", err)
+ fmt.Printf(" Manual command: mosquitto_pub -h localhost -t %s -f %s\n", topic, tmpFile)
+ return
+ }
+
+ fmt.Printf(" ✅ Published to topic: %s\n", topic)
+}
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/topology.yaml b/lab/platform/wsl/srv6-vpc-lab-attachment/topology.yaml
similarity index 100%
rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/topology.yaml
rename to lab/platform/wsl/srv6-vpc-lab-attachment/topology.yaml
diff --git a/galactic-operator/api/v1alpha/groupversion_info.go b/pkg/apis/v1alpha/groupversion_info.go
similarity index 100%
rename from galactic-operator/api/v1alpha/groupversion_info.go
rename to pkg/apis/v1alpha/groupversion_info.go
diff --git a/galactic-operator/api/v1alpha/vpc_types.go b/pkg/apis/v1alpha/vpc_types.go
similarity index 100%
rename from galactic-operator/api/v1alpha/vpc_types.go
rename to pkg/apis/v1alpha/vpc_types.go
diff --git a/galactic-operator/api/v1alpha/vpcattachment_types.go b/pkg/apis/v1alpha/vpcattachment_types.go
similarity index 100%
rename from galactic-operator/api/v1alpha/vpcattachment_types.go
rename to pkg/apis/v1alpha/vpcattachment_types.go
diff --git a/galactic-operator/api/v1alpha/zz_generated.deepcopy.go b/pkg/apis/v1alpha/zz_generated.deepcopy.go
similarity index 100%
rename from galactic-operator/api/v1alpha/zz_generated.deepcopy.go
rename to pkg/apis/v1alpha/zz_generated.deepcopy.go
diff --git a/galactic-common/cni/types.go b/pkg/common/cni/types.go
similarity index 100%
rename from galactic-common/cni/types.go
rename to pkg/common/cni/types.go
diff --git a/galactic-common/sysctl/sysctl.go b/pkg/common/sysctl/sysctl.go
similarity index 100%
rename from galactic-common/sysctl/sysctl.go
rename to pkg/common/sysctl/sysctl.go
diff --git a/galactic-common/util/util.go b/pkg/common/util/util.go
similarity index 100%
rename from galactic-common/util/util.go
rename to pkg/common/util/util.go
diff --git a/galactic-common/util/util_test.go b/pkg/common/util/util_test.go
similarity index 91%
rename from galactic-common/util/util_test.go
rename to pkg/common/util/util_test.go
index 08aed52..39b2e3f 100644
--- a/galactic-common/util/util_test.go
+++ b/pkg/common/util/util_test.go
@@ -5,12 +5,17 @@ import (
"reflect"
"testing"
- "github.com/datum-cloud/galactic-common/util"
+ "go.datum.net/galactic/pkg/common/util"
+)
+
+const (
+ testVPC = "0000000jU" // 1234 dec
+ testVPCAttachment = "00G" // 42 dec
)
func TestGenerateInterfaceNameVRF(t *testing.T) {
- vpc := "0000000jU" // 1234 dec
- vpcattachment := "00G" // 42 dec
+ vpc := testVPC
+ vpcattachment := testVPCAttachment
expected := "G0000000jU00GV"
got := util.GenerateInterfaceNameVRF(vpc, vpcattachment)
if got != expected {
@@ -19,8 +24,8 @@ func TestGenerateInterfaceNameVRF(t *testing.T) {
}
func TestGenerateInterfaceNameHost(t *testing.T) {
- vpc := "0000000jU" // 1234 dec
- vpcattachment := "00G" // 42 dec
+ vpc := testVPC
+ vpcattachment := testVPCAttachment
expected := "G0000000jU00GH"
got := util.GenerateInterfaceNameHost(vpc, vpcattachment)
if got != expected {
@@ -29,8 +34,8 @@ func TestGenerateInterfaceNameHost(t *testing.T) {
}
func TestGenerateInterfaceNameGuest(t *testing.T) {
- vpc := "0000000jU" // 1234 dec
- vpcattachment := "00G" // 42 dec
+ vpc := testVPC
+ vpcattachment := testVPCAttachment
expected := "G0000000jU00GG"
got := util.GenerateInterfaceNameGuest(vpc, vpcattachment)
if got != expected {
diff --git a/galactic-common/vrf/vrf.go b/pkg/common/vrf/vrf.go
similarity index 92%
rename from galactic-common/vrf/vrf.go
rename to pkg/common/vrf/vrf.go
index eacb0ee..49b9d76 100644
--- a/galactic-common/vrf/vrf.go
+++ b/pkg/common/vrf/vrf.go
@@ -5,9 +5,11 @@ import (
"math"
"slices"
- "github.com/datum-cloud/galactic-common/sysctl"
- "github.com/datum-cloud/galactic-common/util"
+ "golang.org/x/sys/unix"
+
"github.com/vishvananda/netlink"
+ "go.datum.net/galactic/pkg/common/sysctl"
+ "go.datum.net/galactic/pkg/common/util"
)
const MinVRFId = uint32(1)
@@ -29,7 +31,7 @@ func Add(vpc, vpcAttachment string) error {
LinkAttrs: netlink.LinkAttrs{
Name: name,
},
- Table: uint32(vrfId),
+ Table: vrfId,
}
if err := netlink.LinkAdd(vrf); err != nil {
@@ -64,7 +66,7 @@ func Delete(vpc, vpcAttachment string) error {
}
func Flush(vrfId uint32) error {
- for _, family := range []int{netlink.FAMILY_V4, netlink.FAMILY_V6} {
+ for _, family := range []int{unix.AF_INET, unix.AF_INET6} {
routes, err := netlink.RouteListFiltered(
family,
&netlink.Route{Table: int(vrfId)},
diff --git a/galactic-agent/api/local/local.go b/pkg/proto/local/local.go
similarity index 100%
rename from galactic-agent/api/local/local.go
rename to pkg/proto/local/local.go
diff --git a/galactic-agent/api/local/local.pb.go b/pkg/proto/local/local.pb.go
similarity index 75%
rename from galactic-agent/api/local/local.pb.go
rename to pkg/proto/local/local.pb.go
index a6fc035..295117d 100644
--- a/galactic-agent/api/local/local.pb.go
+++ b/pkg/proto/local/local.pb.go
@@ -1,8 +1,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.7
-// protoc v3.21.12
-// source: local.proto
+// protoc-gen-go v1.36.11
+// protoc v5.29.3
+// source: pkg/proto/local/local.proto
package local
@@ -32,7 +32,7 @@ type RegisterRequest struct {
func (x *RegisterRequest) Reset() {
*x = RegisterRequest{}
- mi := &file_local_proto_msgTypes[0]
+ mi := &file_pkg_proto_local_local_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -44,7 +44,7 @@ func (x *RegisterRequest) String() string {
func (*RegisterRequest) ProtoMessage() {}
func (x *RegisterRequest) ProtoReflect() protoreflect.Message {
- mi := &file_local_proto_msgTypes[0]
+ mi := &file_pkg_proto_local_local_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -57,7 +57,7 @@ func (x *RegisterRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use RegisterRequest.ProtoReflect.Descriptor instead.
func (*RegisterRequest) Descriptor() ([]byte, []int) {
- return file_local_proto_rawDescGZIP(), []int{0}
+ return file_pkg_proto_local_local_proto_rawDescGZIP(), []int{0}
}
func (x *RegisterRequest) GetVpc() string {
@@ -90,7 +90,7 @@ type RegisterReply struct {
func (x *RegisterReply) Reset() {
*x = RegisterReply{}
- mi := &file_local_proto_msgTypes[1]
+ mi := &file_pkg_proto_local_local_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -102,7 +102,7 @@ func (x *RegisterReply) String() string {
func (*RegisterReply) ProtoMessage() {}
func (x *RegisterReply) ProtoReflect() protoreflect.Message {
- mi := &file_local_proto_msgTypes[1]
+ mi := &file_pkg_proto_local_local_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -115,7 +115,7 @@ func (x *RegisterReply) ProtoReflect() protoreflect.Message {
// Deprecated: Use RegisterReply.ProtoReflect.Descriptor instead.
func (*RegisterReply) Descriptor() ([]byte, []int) {
- return file_local_proto_rawDescGZIP(), []int{1}
+ return file_pkg_proto_local_local_proto_rawDescGZIP(), []int{1}
}
func (x *RegisterReply) GetConfirmed() bool {
@@ -136,7 +136,7 @@ type DeregisterRequest struct {
func (x *DeregisterRequest) Reset() {
*x = DeregisterRequest{}
- mi := &file_local_proto_msgTypes[2]
+ mi := &file_pkg_proto_local_local_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -148,7 +148,7 @@ func (x *DeregisterRequest) String() string {
func (*DeregisterRequest) ProtoMessage() {}
func (x *DeregisterRequest) ProtoReflect() protoreflect.Message {
- mi := &file_local_proto_msgTypes[2]
+ mi := &file_pkg_proto_local_local_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -161,7 +161,7 @@ func (x *DeregisterRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use DeregisterRequest.ProtoReflect.Descriptor instead.
func (*DeregisterRequest) Descriptor() ([]byte, []int) {
- return file_local_proto_rawDescGZIP(), []int{2}
+ return file_pkg_proto_local_local_proto_rawDescGZIP(), []int{2}
}
func (x *DeregisterRequest) GetVpc() string {
@@ -194,7 +194,7 @@ type DeregisterReply struct {
func (x *DeregisterReply) Reset() {
*x = DeregisterReply{}
- mi := &file_local_proto_msgTypes[3]
+ mi := &file_pkg_proto_local_local_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -206,7 +206,7 @@ func (x *DeregisterReply) String() string {
func (*DeregisterReply) ProtoMessage() {}
func (x *DeregisterReply) ProtoReflect() protoreflect.Message {
- mi := &file_local_proto_msgTypes[3]
+ mi := &file_pkg_proto_local_local_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -219,7 +219,7 @@ func (x *DeregisterReply) ProtoReflect() protoreflect.Message {
// Deprecated: Use DeregisterReply.ProtoReflect.Descriptor instead.
func (*DeregisterReply) Descriptor() ([]byte, []int) {
- return file_local_proto_rawDescGZIP(), []int{3}
+ return file_pkg_proto_local_local_proto_rawDescGZIP(), []int{3}
}
func (x *DeregisterReply) GetConfirmed() bool {
@@ -229,11 +229,11 @@ func (x *DeregisterReply) GetConfirmed() bool {
return false
}
-var File_local_proto protoreflect.FileDescriptor
+var File_pkg_proto_local_local_proto protoreflect.FileDescriptor
-const file_local_proto_rawDesc = "" +
+const file_pkg_proto_local_local_proto_rawDesc = "" +
"\n" +
- "\vlocal.proto\x12\blocal.v1\"e\n" +
+ "\x1bpkg/proto/local/local.proto\x12\blocal.v1\"e\n" +
"\x0fRegisterRequest\x12\x10\n" +
"\x03vpc\x18\x01 \x01(\tR\x03vpc\x12$\n" +
"\rvpcattachment\x18\x02 \x01(\tR\rvpcattachment\x12\x1a\n" +
@@ -249,28 +249,28 @@ const file_local_proto_rawDesc = "" +
"\x05Local\x12>\n" +
"\bRegister\x12\x19.local.v1.RegisterRequest\x1a\x17.local.v1.RegisterReply\x12D\n" +
"\n" +
- "Deregister\x12\x1b.local.v1.DeregisterRequest\x1a\x19.local.v1.DeregisterReplyB7Z5github.com/datum-cloud/galactic-agent/api/local;localb\x06proto3"
+ "Deregister\x12\x1b.local.v1.DeregisterRequest\x1a\x19.local.v1.DeregisterReplyB-Z+go.datum.net/galactic/pkg/proto/local;localb\x06proto3"
var (
- file_local_proto_rawDescOnce sync.Once
- file_local_proto_rawDescData []byte
+ file_pkg_proto_local_local_proto_rawDescOnce sync.Once
+ file_pkg_proto_local_local_proto_rawDescData []byte
)
-func file_local_proto_rawDescGZIP() []byte {
- file_local_proto_rawDescOnce.Do(func() {
- file_local_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_local_proto_rawDesc), len(file_local_proto_rawDesc)))
+func file_pkg_proto_local_local_proto_rawDescGZIP() []byte {
+ file_pkg_proto_local_local_proto_rawDescOnce.Do(func() {
+ file_pkg_proto_local_local_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_pkg_proto_local_local_proto_rawDesc), len(file_pkg_proto_local_local_proto_rawDesc)))
})
- return file_local_proto_rawDescData
+ return file_pkg_proto_local_local_proto_rawDescData
}
-var file_local_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
-var file_local_proto_goTypes = []any{
+var file_pkg_proto_local_local_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
+var file_pkg_proto_local_local_proto_goTypes = []any{
(*RegisterRequest)(nil), // 0: local.v1.RegisterRequest
(*RegisterReply)(nil), // 1: local.v1.RegisterReply
(*DeregisterRequest)(nil), // 2: local.v1.DeregisterRequest
(*DeregisterReply)(nil), // 3: local.v1.DeregisterReply
}
-var file_local_proto_depIdxs = []int32{
+var file_pkg_proto_local_local_proto_depIdxs = []int32{
0, // 0: local.v1.Local.Register:input_type -> local.v1.RegisterRequest
2, // 1: local.v1.Local.Deregister:input_type -> local.v1.DeregisterRequest
1, // 2: local.v1.Local.Register:output_type -> local.v1.RegisterReply
@@ -282,26 +282,26 @@ var file_local_proto_depIdxs = []int32{
0, // [0:0] is the sub-list for field type_name
}
-func init() { file_local_proto_init() }
-func file_local_proto_init() {
- if File_local_proto != nil {
+func init() { file_pkg_proto_local_local_proto_init() }
+func file_pkg_proto_local_local_proto_init() {
+ if File_pkg_proto_local_local_proto != nil {
return
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
- RawDescriptor: unsafe.Slice(unsafe.StringData(file_local_proto_rawDesc), len(file_local_proto_rawDesc)),
+ RawDescriptor: unsafe.Slice(unsafe.StringData(file_pkg_proto_local_local_proto_rawDesc), len(file_pkg_proto_local_local_proto_rawDesc)),
NumEnums: 0,
NumMessages: 4,
NumExtensions: 0,
NumServices: 1,
},
- GoTypes: file_local_proto_goTypes,
- DependencyIndexes: file_local_proto_depIdxs,
- MessageInfos: file_local_proto_msgTypes,
+ GoTypes: file_pkg_proto_local_local_proto_goTypes,
+ DependencyIndexes: file_pkg_proto_local_local_proto_depIdxs,
+ MessageInfos: file_pkg_proto_local_local_proto_msgTypes,
}.Build()
- File_local_proto = out.File
- file_local_proto_goTypes = nil
- file_local_proto_depIdxs = nil
+ File_pkg_proto_local_local_proto = out.File
+ file_pkg_proto_local_local_proto_goTypes = nil
+ file_pkg_proto_local_local_proto_depIdxs = nil
}
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.proto b/pkg/proto/local/local.proto
similarity index 86%
rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.proto
rename to pkg/proto/local/local.proto
index b45fb42..387264b 100644
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.proto
+++ b/pkg/proto/local/local.proto
@@ -1,7 +1,7 @@
syntax = "proto3";
package local.v1;
-option go_package = "github.com/datum-cloud/galactic-agent/api/local;local";
+option go_package = "go.datum.net/galactic/pkg/proto/local;local";
service Local {
rpc Register(RegisterRequest) returns (RegisterReply);
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local_grpc.pb.go b/pkg/proto/local/local_grpc.pb.go
similarity index 93%
rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local_grpc.pb.go
rename to pkg/proto/local/local_grpc.pb.go
index ec0612d..136b523 100644
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local_grpc.pb.go
+++ b/pkg/proto/local/local_grpc.pb.go
@@ -1,8 +1,8 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
-// - protoc-gen-go-grpc v1.5.1
-// - protoc v3.21.12
-// source: local.proto
+// - protoc-gen-go-grpc v1.6.1
+// - protoc v5.29.3
+// source: pkg/proto/local/local.proto
package local
@@ -76,10 +76,10 @@ type LocalServer interface {
type UnimplementedLocalServer struct{}
func (UnimplementedLocalServer) Register(context.Context, *RegisterRequest) (*RegisterReply, error) {
- return nil, status.Errorf(codes.Unimplemented, "method Register not implemented")
+ return nil, status.Error(codes.Unimplemented, "method Register not implemented")
}
func (UnimplementedLocalServer) Deregister(context.Context, *DeregisterRequest) (*DeregisterReply, error) {
- return nil, status.Errorf(codes.Unimplemented, "method Deregister not implemented")
+ return nil, status.Error(codes.Unimplemented, "method Deregister not implemented")
}
func (UnimplementedLocalServer) mustEmbedUnimplementedLocalServer() {}
func (UnimplementedLocalServer) testEmbeddedByValue() {}
@@ -92,7 +92,7 @@ type UnsafeLocalServer interface {
}
func RegisterLocalServer(s grpc.ServiceRegistrar, srv LocalServer) {
- // If the following call pancis, it indicates UnimplementedLocalServer was
+ // If the following call panics, it indicates UnimplementedLocalServer was
// embedded by pointer and is nil. This will cause panics if an
// unimplemented method is ever invoked, so we test this at initialization
// time to prevent it from happening at runtime later due to I/O.
@@ -155,5 +155,5 @@ var Local_ServiceDesc = grpc.ServiceDesc{
},
},
Streams: []grpc.StreamDesc{},
- Metadata: "local.proto",
+ Metadata: "pkg/proto/local/local.proto",
}
diff --git a/galactic-agent/api/remote/remote.go b/pkg/proto/remote/remote.go
similarity index 100%
rename from galactic-agent/api/remote/remote.go
rename to pkg/proto/remote/remote.go
diff --git a/galactic-agent/api/remote/remote.pb.go b/pkg/proto/remote/remote.pb.go
similarity index 76%
rename from galactic-agent/api/remote/remote.pb.go
rename to pkg/proto/remote/remote.pb.go
index edcce0d..6be379d 100644
--- a/galactic-agent/api/remote/remote.pb.go
+++ b/pkg/proto/remote/remote.pb.go
@@ -1,8 +1,8 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
-// protoc-gen-go v1.36.7
-// protoc v3.21.12
-// source: remote.proto
+// protoc-gen-go v1.36.11
+// protoc v5.29.3
+// source: pkg/proto/remote/remote.proto
package remote
@@ -51,11 +51,11 @@ func (x Route_Status) String() string {
}
func (Route_Status) Descriptor() protoreflect.EnumDescriptor {
- return file_remote_proto_enumTypes[0].Descriptor()
+ return file_pkg_proto_remote_remote_proto_enumTypes[0].Descriptor()
}
func (Route_Status) Type() protoreflect.EnumType {
- return &file_remote_proto_enumTypes[0]
+ return &file_pkg_proto_remote_remote_proto_enumTypes[0]
}
func (x Route_Status) Number() protoreflect.EnumNumber {
@@ -64,7 +64,7 @@ func (x Route_Status) Number() protoreflect.EnumNumber {
// Deprecated: Use Route_Status.Descriptor instead.
func (Route_Status) EnumDescriptor() ([]byte, []int) {
- return file_remote_proto_rawDescGZIP(), []int{3, 0}
+ return file_pkg_proto_remote_remote_proto_rawDescGZIP(), []int{3, 0}
}
type Envelope struct {
@@ -81,7 +81,7 @@ type Envelope struct {
func (x *Envelope) Reset() {
*x = Envelope{}
- mi := &file_remote_proto_msgTypes[0]
+ mi := &file_pkg_proto_remote_remote_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -93,7 +93,7 @@ func (x *Envelope) String() string {
func (*Envelope) ProtoMessage() {}
func (x *Envelope) ProtoReflect() protoreflect.Message {
- mi := &file_remote_proto_msgTypes[0]
+ mi := &file_pkg_proto_remote_remote_proto_msgTypes[0]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -106,7 +106,7 @@ func (x *Envelope) ProtoReflect() protoreflect.Message {
// Deprecated: Use Envelope.ProtoReflect.Descriptor instead.
func (*Envelope) Descriptor() ([]byte, []int) {
- return file_remote_proto_rawDescGZIP(), []int{0}
+ return file_pkg_proto_remote_remote_proto_rawDescGZIP(), []int{0}
}
func (x *Envelope) GetKind() isEnvelope_Kind {
@@ -175,7 +175,7 @@ type Register struct {
func (x *Register) Reset() {
*x = Register{}
- mi := &file_remote_proto_msgTypes[1]
+ mi := &file_pkg_proto_remote_remote_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -187,7 +187,7 @@ func (x *Register) String() string {
func (*Register) ProtoMessage() {}
func (x *Register) ProtoReflect() protoreflect.Message {
- mi := &file_remote_proto_msgTypes[1]
+ mi := &file_pkg_proto_remote_remote_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -200,7 +200,7 @@ func (x *Register) ProtoReflect() protoreflect.Message {
// Deprecated: Use Register.ProtoReflect.Descriptor instead.
func (*Register) Descriptor() ([]byte, []int) {
- return file_remote_proto_rawDescGZIP(), []int{1}
+ return file_pkg_proto_remote_remote_proto_rawDescGZIP(), []int{1}
}
func (x *Register) GetNetwork() string {
@@ -227,7 +227,7 @@ type Deregister struct {
func (x *Deregister) Reset() {
*x = Deregister{}
- mi := &file_remote_proto_msgTypes[2]
+ mi := &file_pkg_proto_remote_remote_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -239,7 +239,7 @@ func (x *Deregister) String() string {
func (*Deregister) ProtoMessage() {}
func (x *Deregister) ProtoReflect() protoreflect.Message {
- mi := &file_remote_proto_msgTypes[2]
+ mi := &file_pkg_proto_remote_remote_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -252,7 +252,7 @@ func (x *Deregister) ProtoReflect() protoreflect.Message {
// Deprecated: Use Deregister.ProtoReflect.Descriptor instead.
func (*Deregister) Descriptor() ([]byte, []int) {
- return file_remote_proto_rawDescGZIP(), []int{2}
+ return file_pkg_proto_remote_remote_proto_rawDescGZIP(), []int{2}
}
func (x *Deregister) GetNetwork() string {
@@ -281,7 +281,7 @@ type Route struct {
func (x *Route) Reset() {
*x = Route{}
- mi := &file_remote_proto_msgTypes[3]
+ mi := &file_pkg_proto_remote_remote_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -293,7 +293,7 @@ func (x *Route) String() string {
func (*Route) ProtoMessage() {}
func (x *Route) ProtoReflect() protoreflect.Message {
- mi := &file_remote_proto_msgTypes[3]
+ mi := &file_pkg_proto_remote_remote_proto_msgTypes[3]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -306,7 +306,7 @@ func (x *Route) ProtoReflect() protoreflect.Message {
// Deprecated: Use Route.ProtoReflect.Descriptor instead.
func (*Route) Descriptor() ([]byte, []int) {
- return file_remote_proto_rawDescGZIP(), []int{3}
+ return file_pkg_proto_remote_remote_proto_rawDescGZIP(), []int{3}
}
func (x *Route) GetNetwork() string {
@@ -337,11 +337,11 @@ func (x *Route) GetStatus() Route_Status {
return Route_ADD
}
-var File_remote_proto protoreflect.FileDescriptor
+var File_pkg_proto_remote_remote_proto protoreflect.FileDescriptor
-const file_remote_proto_rawDesc = "" +
+const file_pkg_proto_remote_remote_proto_rawDesc = "" +
"\n" +
- "\fremote.proto\x12\tremote.v1\"\xa8\x01\n" +
+ "\x1dpkg/proto/remote/remote.proto\x12\tremote.v1\"\xa8\x01\n" +
"\bEnvelope\x121\n" +
"\bregister\x18\x01 \x01(\v2\x13.remote.v1.RegisterH\x00R\bregister\x127\n" +
"\n" +
@@ -364,30 +364,30 @@ const file_remote_proto_rawDesc = "" +
"\x06Status\x12\a\n" +
"\x03ADD\x10\x00\x12\n" +
"\n" +
- "\x06DELETE\x10\x01B9Z7github.com/datum-cloud/galactic-agent/api/remote;remoteb\x06proto3"
+ "\x06DELETE\x10\x01B/Z-go.datum.net/galactic/pkg/proto/remote;remoteb\x06proto3"
var (
- file_remote_proto_rawDescOnce sync.Once
- file_remote_proto_rawDescData []byte
+ file_pkg_proto_remote_remote_proto_rawDescOnce sync.Once
+ file_pkg_proto_remote_remote_proto_rawDescData []byte
)
-func file_remote_proto_rawDescGZIP() []byte {
- file_remote_proto_rawDescOnce.Do(func() {
- file_remote_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_remote_proto_rawDesc), len(file_remote_proto_rawDesc)))
+func file_pkg_proto_remote_remote_proto_rawDescGZIP() []byte {
+ file_pkg_proto_remote_remote_proto_rawDescOnce.Do(func() {
+ file_pkg_proto_remote_remote_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_pkg_proto_remote_remote_proto_rawDesc), len(file_pkg_proto_remote_remote_proto_rawDesc)))
})
- return file_remote_proto_rawDescData
+ return file_pkg_proto_remote_remote_proto_rawDescData
}
-var file_remote_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_remote_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
-var file_remote_proto_goTypes = []any{
+var file_pkg_proto_remote_remote_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_pkg_proto_remote_remote_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
+var file_pkg_proto_remote_remote_proto_goTypes = []any{
(Route_Status)(0), // 0: remote.v1.Route.Status
(*Envelope)(nil), // 1: remote.v1.Envelope
(*Register)(nil), // 2: remote.v1.Register
(*Deregister)(nil), // 3: remote.v1.Deregister
(*Route)(nil), // 4: remote.v1.Route
}
-var file_remote_proto_depIdxs = []int32{
+var file_pkg_proto_remote_remote_proto_depIdxs = []int32{
2, // 0: remote.v1.Envelope.register:type_name -> remote.v1.Register
3, // 1: remote.v1.Envelope.deregister:type_name -> remote.v1.Deregister
4, // 2: remote.v1.Envelope.route:type_name -> remote.v1.Route
@@ -399,12 +399,12 @@ var file_remote_proto_depIdxs = []int32{
0, // [0:4] is the sub-list for field type_name
}
-func init() { file_remote_proto_init() }
-func file_remote_proto_init() {
- if File_remote_proto != nil {
+func init() { file_pkg_proto_remote_remote_proto_init() }
+func file_pkg_proto_remote_remote_proto_init() {
+ if File_pkg_proto_remote_remote_proto != nil {
return
}
- file_remote_proto_msgTypes[0].OneofWrappers = []any{
+ file_pkg_proto_remote_remote_proto_msgTypes[0].OneofWrappers = []any{
(*Envelope_Register)(nil),
(*Envelope_Deregister)(nil),
(*Envelope_Route)(nil),
@@ -413,18 +413,18 @@ func file_remote_proto_init() {
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
- RawDescriptor: unsafe.Slice(unsafe.StringData(file_remote_proto_rawDesc), len(file_remote_proto_rawDesc)),
+ RawDescriptor: unsafe.Slice(unsafe.StringData(file_pkg_proto_remote_remote_proto_rawDesc), len(file_pkg_proto_remote_remote_proto_rawDesc)),
NumEnums: 1,
NumMessages: 4,
NumExtensions: 0,
NumServices: 0,
},
- GoTypes: file_remote_proto_goTypes,
- DependencyIndexes: file_remote_proto_depIdxs,
- EnumInfos: file_remote_proto_enumTypes,
- MessageInfos: file_remote_proto_msgTypes,
+ GoTypes: file_pkg_proto_remote_remote_proto_goTypes,
+ DependencyIndexes: file_pkg_proto_remote_remote_proto_depIdxs,
+ EnumInfos: file_pkg_proto_remote_remote_proto_enumTypes,
+ MessageInfos: file_pkg_proto_remote_remote_proto_msgTypes,
}.Build()
- File_remote_proto = out.File
- file_remote_proto_goTypes = nil
- file_remote_proto_depIdxs = nil
+ File_pkg_proto_remote_remote_proto = out.File
+ file_pkg_proto_remote_remote_proto_goTypes = nil
+ file_pkg_proto_remote_remote_proto_depIdxs = nil
}
diff --git a/galactic-router/galactic_router/proto/remote.proto b/pkg/proto/remote/remote.proto
similarity index 86%
rename from galactic-router/galactic_router/proto/remote.proto
rename to pkg/proto/remote/remote.proto
index 87ad223..fd88514 100644
--- a/galactic-router/galactic_router/proto/remote.proto
+++ b/pkg/proto/remote/remote.proto
@@ -1,7 +1,7 @@
syntax = "proto3";
package remote.v1;
-option go_package = "github.com/datum-cloud/galactic-agent/api/remote;remote";
+option go_package = "go.datum.net/galactic/pkg/proto/remote;remote";
message Envelope {
oneof kind {
diff --git a/galactic-router/.flake8 b/router/.flake8
similarity index 83%
rename from galactic-router/.flake8
rename to router/.flake8
index 12198d2..d11634b 100644
--- a/galactic-router/.flake8
+++ b/router/.flake8
@@ -17,3 +17,5 @@ extend-ignore =
WPS476,
# InitModuleHasLogicViolation
WPS412,
+ # SimplifiableMatchStatementViolation (match for clarity)
+ WPS365,
diff --git a/galactic-router/Dockerfile b/router/Dockerfile
similarity index 100%
rename from galactic-router/Dockerfile
rename to router/Dockerfile
diff --git a/galactic-router/Dockerfile.test b/router/Dockerfile.test
similarity index 100%
rename from galactic-router/Dockerfile.test
rename to router/Dockerfile.test
diff --git a/galactic-router/README.md b/router/README.md
similarity index 100%
rename from galactic-router/README.md
rename to router/README.md
diff --git a/galactic-router/alembic/alembic.ini b/router/alembic/alembic.ini
similarity index 100%
rename from galactic-router/alembic/alembic.ini
rename to router/alembic/alembic.ini
diff --git a/galactic-router/alembic/env.py b/router/alembic/env.py
similarity index 100%
rename from galactic-router/alembic/env.py
rename to router/alembic/env.py
diff --git a/galactic-router/alembic/script.py.mako b/router/alembic/script.py.mako
similarity index 100%
rename from galactic-router/alembic/script.py.mako
rename to router/alembic/script.py.mako
diff --git a/galactic-router/alembic/versions/042d8775f6e0_add_created_field_to_registration_table.py b/router/alembic/versions/042d8775f6e0_add_created_field_to_registration_table.py
similarity index 100%
rename from galactic-router/alembic/versions/042d8775f6e0_add_created_field_to_registration_table.py
rename to router/alembic/versions/042d8775f6e0_add_created_field_to_registration_table.py
diff --git a/galactic-router/alembic/versions/0e50c4ae5859_init.py b/router/alembic/versions/0e50c4ae5859_init.py
similarity index 100%
rename from galactic-router/alembic/versions/0e50c4ae5859_init.py
rename to router/alembic/versions/0e50c4ae5859_init.py
diff --git a/galactic-router/config/base/deployment.yaml b/router/config/base/deployment.yaml
similarity index 100%
rename from galactic-router/config/base/deployment.yaml
rename to router/config/base/deployment.yaml
diff --git a/galactic-router/config/base/kustomization.yaml b/router/config/base/kustomization.yaml
similarity index 100%
rename from galactic-router/config/base/kustomization.yaml
rename to router/config/base/kustomization.yaml
diff --git a/galactic-router/features/deregister.feature b/router/features/deregister.feature
similarity index 100%
rename from galactic-router/features/deregister.feature
rename to router/features/deregister.feature
diff --git a/galactic-router/features/duplicate.feature b/router/features/duplicate.feature
similarity index 100%
rename from galactic-router/features/duplicate.feature
rename to router/features/duplicate.feature
diff --git a/galactic-router/features/environment.py b/router/features/environment.py
similarity index 100%
rename from galactic-router/features/environment.py
rename to router/features/environment.py
diff --git a/galactic-router/features/move.feature b/router/features/move.feature
similarity index 100%
rename from galactic-router/features/move.feature
rename to router/features/move.feature
diff --git a/galactic-router/features/multiple_networks.feature b/router/features/multiple_networks.feature
similarity index 100%
rename from galactic-router/features/multiple_networks.feature
rename to router/features/multiple_networks.feature
diff --git a/galactic-router/features/multiple_networks_deregister.feature b/router/features/multiple_networks_deregister.feature
similarity index 100%
rename from galactic-router/features/multiple_networks_deregister.feature
rename to router/features/multiple_networks_deregister.feature
diff --git a/galactic-router/features/register-with-vpc-details.feature b/router/features/register-with-vpc-details.feature
similarity index 100%
rename from galactic-router/features/register-with-vpc-details.feature
rename to router/features/register-with-vpc-details.feature
diff --git a/galactic-router/features/register.feature b/router/features/register.feature
similarity index 100%
rename from galactic-router/features/register.feature
rename to router/features/register.feature
diff --git a/galactic-router/features/rejoin.feature b/router/features/rejoin.feature
similarity index 100%
rename from galactic-router/features/rejoin.feature
rename to router/features/rejoin.feature
diff --git a/galactic-router/features/steps/router_steps.py b/router/features/steps/router_steps.py
similarity index 100%
rename from galactic-router/features/steps/router_steps.py
rename to router/features/steps/router_steps.py
diff --git a/galactic-router/galactic_router/__init__.py b/router/galactic_router/__init__.py
similarity index 100%
rename from galactic-router/galactic_router/__init__.py
rename to router/galactic_router/__init__.py
diff --git a/galactic-router/galactic_router/bus.py b/router/galactic_router/bus.py
similarity index 100%
rename from galactic-router/galactic_router/bus.py
rename to router/galactic_router/bus.py
diff --git a/galactic-router/galactic_router/events.py b/router/galactic_router/events.py
similarity index 100%
rename from galactic-router/galactic_router/events.py
rename to router/galactic_router/events.py
diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.proto b/router/galactic_router/proto/remote.proto
similarity index 86%
rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.proto
rename to router/galactic_router/proto/remote.proto
index 87ad223..fd88514 100644
--- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.proto
+++ b/router/galactic_router/proto/remote.proto
@@ -1,7 +1,7 @@
syntax = "proto3";
package remote.v1;
-option go_package = "github.com/datum-cloud/galactic-agent/api/remote;remote";
+option go_package = "go.datum.net/galactic/pkg/proto/remote;remote";
message Envelope {
oneof kind {
diff --git a/galactic-router/galactic_router/proto/remote_pb2.py b/router/galactic_router/proto/remote_pb2.py
similarity index 54%
rename from galactic-router/galactic_router/proto/remote_pb2.py
rename to router/galactic_router/proto/remote_pb2.py
index 4132062..af8e44f 100644
--- a/galactic-router/galactic_router/proto/remote_pb2.py
+++ b/router/galactic_router/proto/remote_pb2.py
@@ -1,11 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
+# NO CHECKED-IN PROTOBUF GENCODE
# source: remote.proto
+# Protobuf Python Version: 5.29.3
"""Generated protocol buffer code."""
-from google.protobuf.internal import builder as _builder
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
+from google.protobuf import runtime_version as _runtime_version
from google.protobuf import symbol_database as _symbol_database
+from google.protobuf.internal import builder as _builder
+_runtime_version.ValidateProtobufRuntimeVersion(
+ _runtime_version.Domain.PUBLIC,
+ 5,
+ 29,
+ 3,
+ '',
+ 'remote.proto'
+)
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
@@ -13,22 +24,22 @@
-DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0cremote.proto\x12\tremote.v1\"\x8b\x01\n\x08\x45nvelope\x12\'\n\x08register\x18\x01 \x01(\x0b\x32\x13.remote.v1.RegisterH\x00\x12+\n\nderegister\x18\x02 \x01(\x0b\x32\x15.remote.v1.DeregisterH\x00\x12!\n\x05route\x18\x03 \x01(\x0b\x32\x10.remote.v1.RouteH\x00\x42\x06\n\x04kind\"2\n\x08Register\x12\x0f\n\x07network\x18\x01 \x01(\t\x12\x15\n\rsrv6_endpoint\x18\x02 \x01(\t\"4\n\nDeregister\x12\x0f\n\x07network\x18\x01 \x01(\t\x12\x15\n\rsrv6_endpoint\x18\x02 \x01(\t\"\x8e\x01\n\x05Route\x12\x0f\n\x07network\x18\x01 \x01(\t\x12\x15\n\rsrv6_endpoint\x18\x02 \x01(\t\x12\x15\n\rsrv6_segments\x18\x03 \x03(\t\x12\'\n\x06status\x18\x04 \x01(\x0e\x32\x17.remote.v1.Route.Status\"\x1d\n\x06Status\x12\x07\n\x03\x41\x44\x44\x10\x00\x12\n\n\x06\x44\x45LETE\x10\x01\x42\x39Z7github.com/datum-cloud/galactic-agent/api/remote;remoteb\x06proto3')
-
-_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
-_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'remote_pb2', globals())
-if _descriptor._USE_C_DESCRIPTORS == False:
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0cremote.proto\x12\tremote.v1\"\x8b\x01\n\x08\x45nvelope\x12\'\n\x08register\x18\x01 \x01(\x0b\x32\x13.remote.v1.RegisterH\x00\x12+\n\nderegister\x18\x02 \x01(\x0b\x32\x15.remote.v1.DeregisterH\x00\x12!\n\x05route\x18\x03 \x01(\x0b\x32\x10.remote.v1.RouteH\x00\x42\x06\n\x04kind\"2\n\x08Register\x12\x0f\n\x07network\x18\x01 \x01(\t\x12\x15\n\rsrv6_endpoint\x18\x02 \x01(\t\"4\n\nDeregister\x12\x0f\n\x07network\x18\x01 \x01(\t\x12\x15\n\rsrv6_endpoint\x18\x02 \x01(\t\"\x8e\x01\n\x05Route\x12\x0f\n\x07network\x18\x01 \x01(\t\x12\x15\n\rsrv6_endpoint\x18\x02 \x01(\t\x12\x15\n\rsrv6_segments\x18\x03 \x03(\t\x12\'\n\x06status\x18\x04 \x01(\x0e\x32\x17.remote.v1.Route.Status\"\x1d\n\x06Status\x12\x07\n\x03\x41\x44\x44\x10\x00\x12\n\n\x06\x44\x45LETE\x10\x01\x42/Z-go.datum.net/galactic/pkg/proto/remote;remoteb\x06proto3')
- DESCRIPTOR._options = None
- DESCRIPTOR._serialized_options = b'Z7github.com/datum-cloud/galactic-agent/api/remote;remote'
- _ENVELOPE._serialized_start=28
- _ENVELOPE._serialized_end=167
- _REGISTER._serialized_start=169
- _REGISTER._serialized_end=219
- _DEREGISTER._serialized_start=221
- _DEREGISTER._serialized_end=273
- _ROUTE._serialized_start=276
- _ROUTE._serialized_end=418
- _ROUTE_STATUS._serialized_start=389
- _ROUTE_STATUS._serialized_end=418
+_globals = globals()
+_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
+_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'remote_pb2', _globals)
+if not _descriptor._USE_C_DESCRIPTORS:
+ _globals['DESCRIPTOR']._loaded_options = None
+ _globals['DESCRIPTOR']._serialized_options = b'Z-go.datum.net/galactic/pkg/proto/remote;remote'
+ _globals['_ENVELOPE']._serialized_start=28
+ _globals['_ENVELOPE']._serialized_end=167
+ _globals['_REGISTER']._serialized_start=169
+ _globals['_REGISTER']._serialized_end=219
+ _globals['_DEREGISTER']._serialized_start=221
+ _globals['_DEREGISTER']._serialized_end=273
+ _globals['_ROUTE']._serialized_start=276
+ _globals['_ROUTE']._serialized_end=418
+ _globals['_ROUTE_STATUS']._serialized_start=389
+ _globals['_ROUTE_STATUS']._serialized_end=418
# @@protoc_insertion_point(module_scope)
diff --git a/galactic-router/galactic_router/router/__init__.py b/router/galactic_router/router/__init__.py
similarity index 100%
rename from galactic-router/galactic_router/router/__init__.py
rename to router/galactic_router/router/__init__.py
diff --git a/galactic-router/galactic_router/router/mqtt.py b/router/galactic_router/router/mqtt.py
similarity index 100%
rename from galactic-router/galactic_router/router/mqtt.py
rename to router/galactic_router/router/mqtt.py
diff --git a/galactic-router/galactic_router/router/static.py b/router/galactic_router/router/static.py
similarity index 100%
rename from galactic-router/galactic_router/router/static.py
rename to router/galactic_router/router/static.py
diff --git a/galactic-router/pyproject.toml b/router/pyproject.toml
similarity index 100%
rename from galactic-router/pyproject.toml
rename to router/pyproject.toml
diff --git a/scripts/test-local.sh b/scripts/test-local.sh
new file mode 100755
index 0000000..48f5290
--- /dev/null
+++ b/scripts/test-local.sh
@@ -0,0 +1,92 @@
+#!/bin/bash
+# Local testing script for Galactic
+# Runs tests in Docker to ensure Linux compatibility
+
+set -e
+
+REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
+IMAGE="golang:1.24"
+
+echo "=== Galactic Local Test Runner ==="
+echo "Repository: $REPO_ROOT"
+echo ""
+
+# Parse arguments
+TEST_TYPE="${1:-unit}"
+
+case "$TEST_TYPE" in
+ unit)
+ echo "Running unit tests (no K8s required)..."
+ docker run --rm \
+ -v "$REPO_ROOT":/workspace \
+ -w /workspace \
+ "$IMAGE" \
+ go test -v \
+ ./internal/operator/identifier/... \
+ ./internal/operator/cniconfig/... \
+ ./pkg/common/util/...
+ ;;
+
+ operator)
+ echo "Running operator tests with envtest..."
+ docker run --rm \
+ -v "$REPO_ROOT":/workspace \
+ -w /workspace \
+ "$IMAGE" \
+ sh -c '
+ # Install setup-envtest
+ go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
+
+ # Setup envtest binaries
+ KUBEBUILDER_ASSETS=$(setup-envtest use 1.31.0 --bin-dir /workspace/bin/k8s -p path)
+ export KUBEBUILDER_ASSETS
+
+ # Run tests
+ go test -v ./internal/operator/...
+ '
+ ;;
+
+ router)
+ echo "Running router BDD tests..."
+ docker run --rm \
+ -v "$REPO_ROOT":/workspace \
+ -w /workspace/router \
+ python:3.13 \
+ sh -c '
+ pip install -e .[test] -q
+ behave
+ '
+ ;;
+
+ build)
+ echo "Building galactic binary..."
+ docker run --rm \
+ -v "$REPO_ROOT":/workspace \
+ -w /workspace \
+ "$IMAGE" \
+ go build -o bin/galactic ./cmd/galactic/...
+ echo "Binary built: bin/galactic"
+ file "$REPO_ROOT/bin/galactic"
+ ;;
+
+ all)
+ echo "Running all tests..."
+ "$0" unit
+ "$0" router
+ "$0" operator
+ ;;
+
+ *)
+ echo "Usage: $0 {unit|operator|router|build|all}"
+ echo ""
+ echo " unit - Run unit tests (fast, no K8s)"
+ echo " operator - Run operator tests with envtest"
+ echo " router - Run Python router BDD tests"
+ echo " build - Build the galactic binary"
+ echo " all - Run all tests"
+ exit 1
+ ;;
+esac
+
+echo ""
+echo "=== Done ==="