From b8add408eac997c4e6c82c09eb63bdd7a5baee14 Mon Sep 17 00:00:00 2001 From: Scot Wells Date: Fri, 6 Mar 2026 13:19:44 -0600 Subject: [PATCH 01/18] Consolidate repository into unified monorepo structure Merge galactic-operator, galactic-agent, galactic-cni, galactic-common, galactic-router, and galactic-lab into a single consolidated repository with unified Go module path go.datum.net/galactic. Key changes: - Single `galactic` binary with operator/agent/cni/version subcommands - CNI auto-detection via CNI_COMMAND environment variable - Unified directory structure following Go project layout - Preserved full git history from all original repositories Directory structure: - cmd/galactic/ - Unified binary entry point - pkg/apis/ - Kubernetes CRD types (VPC, VPCAttachment) - pkg/common/ - Shared utilities (sysctl, vrf, util) - pkg/proto/ - Protocol Buffer definitions - internal/operator/ - Kubernetes operator implementation - internal/agent/ - Network agent implementation - internal/cni/ - CNI plugin implementation - internal/cmd/ - Subcommand implementations - config/ - Kubernetes manifests - router/ - Python routing engine - lab/ - Testing infrastructure - build/ - Dockerfiles - hack/ - Build scripts Migration paths: - galactic-common/* -> pkg/common/ - galactic-operator/api/* -> pkg/apis/ - galactic-operator/internal/ -> internal/operator/ - galactic-agent/api/* -> pkg/proto/ - galactic-agent/srv6/* -> internal/agent/srv6/ - galactic-cni/cni/* -> internal/cni/ - galactic-router/* -> router/ - galactic-lab/* -> lab/ Co-Authored-By: Claude Opus 4.5 --- .claude/settings.local.json | 23 + .gitignore | 39 + .../.golangci.yml => .golangci.yml | 0 galactic-operator/Makefile => Makefile | 50 +- {galactic-operator => build}/Dockerfile | 14 +- cmd/galactic/main.go | 65 ++ .../base => config/agent}/daemonset.yaml | 0 .../base => config/agent}/kustomization.yaml | 0 .../certmanager/certificate-metrics.yaml | 0 .../certmanager/certificate-webhook.yaml | 0 .../config => config}/certmanager/issuer.yaml | 0 .../certmanager/kustomization.yaml | 0 .../certmanager/kustomizeconfig.yaml | 0 ...galactic.datumapis.com_vpcattachments.yaml | 0 .../bases/galactic.datumapis.com_vpcs.yaml | 0 ...ncf.io_network-attachment-definitions.yaml | 0 .../config => config}/crd/kustomization.yaml | 0 .../crd/kustomizeconfig.yaml | 0 .../default/cert_metrics_manager_patch.yaml | 0 .../default/kustomization.yaml | 0 .../default/manager_metrics_patch.yaml | 0 .../default/manager_webhook_patch.yaml | 0 .../default/metrics_service.yaml | 0 .../manager/kustomization.yaml | 0 .../config => config}/manager/manager.yaml | 0 .../network-policy/allow-metrics-traffic.yaml | 0 .../network-policy/allow-webhook-traffic.yaml | 0 .../network-policy/kustomization.yaml | 0 .../prometheus/kustomization.yaml | 0 .../config => config}/prometheus/monitor.yaml | 0 .../prometheus/monitor_tls_patch.yaml | 0 .../config => config}/rbac/kustomization.yaml | 0 .../rbac/leader_election_role.yaml | 0 .../rbac/leader_election_role_binding.yaml | 0 .../rbac/metrics_auth_role.yaml | 0 .../rbac/metrics_auth_role_binding.yaml | 0 .../rbac/metrics_reader_role.yaml | 0 .../config => config}/rbac/role.yaml | 0 .../config => config}/rbac/role_binding.yaml | 0 .../rbac/service_account.yaml | 0 .../rbac/vpc_admin_role.yaml | 0 .../rbac/vpc_editor_role.yaml | 0 .../rbac/vpc_viewer_role.yaml | 0 .../rbac/vpcattachment_admin_role.yaml | 0 .../rbac/vpcattachment_editor_role.yaml | 0 .../rbac/vpcattachment_viewer_role.yaml | 0 .../samples/galactic_v1alpha_vpc.yaml | 0 .../galactic_v1alpha_vpcattachment.yaml | 0 .../samples/kustomization.yaml | 0 .../config => config}/samples/pod.yaml | 0 .../webhook/kustomization.yaml | 0 .../webhook/kustomizeconfig.yaml | 0 .../config => config}/webhook/manifests.yaml | 0 .../config => config}/webhook/service.yaml | 0 galactic-agent/main.go | 167 ---- galactic-cni/.github/workflows/build.yml | 59 -- galactic-cni/.github/workflows/release.yml | 41 - galactic-cni/.golangci.yml | 5 - galactic-cni/README.md | 3 - galactic-cni/go.mod | 35 - galactic-cni/go.sum | 98 --- galactic-cni/main.go | 32 - galactic-common/.github/workflows/build.yml | 42 - galactic-common/LICENSE | 661 -------------- galactic-common/go.mod | 20 - galactic-common/go.sum | 36 - .../galactic-agent/.github/workflows/lint.yml | 16 - .../.github/workflows/publish.yml | 34 - .../galactic-agent/.github/workflows/test.yml | 18 - .../galactic-agent/.golangci.yml | 5 - .../galactic-agent/Dockerfile | 14 - .../galactic-agent/LICENSE | 661 -------------- .../galactic-agent/README.md | 3 - .../galactic-agent/generate.sh | 24 - .../galactic-agent/go.mod | 44 - .../galactic-agent/go.sum | 127 --- .../.devcontainer/devcontainer.json | 25 - .../.devcontainer/post-install.sh | 23 - galactic-operator/.dockerignore | 3 - galactic-operator/.github/workflows/lint.yml | 23 - .../.github/workflows/publish.yml | 34 - .../.github/workflows/test-e2e.yml | 32 - galactic-operator/.github/workflows/test.yml | 23 - galactic-operator/.gitignore | 27 - galactic-operator/LICENSE | 661 -------------- galactic-operator/PROJECT | 39 - galactic-operator/README.md | 117 --- galactic-operator/cmd/main.go | 265 ------ galactic-operator/dist/install.yaml | 804 ------------------ galactic-operator/test/e2e/e2e_suite_test.go | 89 -- galactic-operator/test/e2e/e2e_test.go | 368 -------- galactic-operator/test/utils/utils.go | 267 ------ galactic-router/LICENSE | 661 -------------- galactic-operator/go.mod => go.mod | 86 +- galactic-operator/go.sum => go.sum | 173 ++-- .../hack => hack}/boilerplate.go.txt | 0 .../srv6/neighborproxy/neighborproxy.go | 2 +- .../agent}/srv6/routeegress/routeegress.go | 2 +- .../agent}/srv6/routeingress/routeingress.go | 4 +- .../agent}/srv6/srv6.go | 8 +- internal/cmd/agent/agent.go | 221 +++++ internal/cmd/cni/cni.go | 43 + internal/cmd/operator/operator.go | 181 ++++ internal/cmd/version/version.go | 50 ++ {galactic-cni => internal}/cni/cni.go | 14 +- {galactic-cni => internal/cni}/debug/debug.go | 0 .../cni/registration/registration.go | 2 +- {galactic-cni => internal}/cni/route/route.go | 4 +- {galactic-cni => internal}/cni/veth/veth.go | 4 +- .../operator}/cniconfig/cniconfig.go | 6 +- .../operator}/cniconfig/cniconfig_test.go | 6 +- .../operator}/controller/suite_test.go | 2 +- .../operator}/controller/vpc_controller.go | 4 +- .../controller/vpc_controller_test.go | 4 +- .../controller/vpcattachment_controller.go | 6 +- .../vpcattachment_controller_test.go | 4 +- .../operator}/identifier/identifier.go | 0 .../operator}/identifier/identifier_test.go | 2 +- .../operator}/webhook/v1/pod_webhook.go | 2 +- .../operator}/webhook/v1/pod_webhook_test.go | 2 +- .../webhook/v1/webhook_suite_test.go | 0 .../.devcontainer/devcontainer.json | 0 {galactic-lab => lab}/Dockerfile | 0 {galactic-cni => lab}/LICENSE | 0 {galactic-lab => lab}/README.md | 0 {galactic-lab => lab}/basic/.gitignore | 0 {galactic-lab => lab}/basic/README.md | 0 .../basic/deployment.k8s.yml | 0 {galactic-lab => lab}/basic/k01-config.yml | 0 {galactic-lab => lab}/basic/topology.svg | 0 {galactic-lab => lab}/basic/topology.yml | 0 {galactic-lab => lab}/basic/vpc.k8s.yml | 0 .../galactic-lab.code-workspace | 0 {galactic-lab => lab}/geo/.gitignore | 0 {galactic-lab => lab}/geo/README.md | 0 {galactic-lab => lab}/geo/deployment.k8s.yml | 0 {galactic-lab => lab}/geo/k01-config.yml | 0 {galactic-lab => lab}/geo/topology.svg | 0 {galactic-lab => lab}/geo/topology.yml | 0 {galactic-lab => lab}/geo/vpc.k8s.yml | 0 .../kindest-node-galactic/Dockerfile | 0 .../kindest-node-galactic/agent.k8s.yml | 0 .../kindest-node-galactic/install.sh | 0 .../kindest-node-galactic/mqtt.k8s.yml | 0 .../kindest-node-galactic/router.k8s.yml | 0 .../wsl/srv6-vpc-lab-attachment/.gitignore | 0 .../wsl/srv6-vpc-lab-attachment/CHANGELOG.md | 0 .../wsl/srv6-vpc-lab-attachment/README.md | 0 .../wsl/srv6-vpc-lab-attachment/TUTORIAL.md | 0 .../wsl/srv6-vpc-lab-attachment/agent.yaml | 0 .../filter_plugins/netlab_filters.py | 0 .../galactic-agent-config.yaml | 0 .../.github/workflows/lint.yml | 0 .../.github/workflows/publish.yml | 0 .../.github/workflows/test.yml | 0 .../galactic-agent}/.golangci.yml | 0 .../galactic-agent}/Dockerfile | 0 .../galactic-agent}/LICENSE | 0 .../galactic-agent}/README.md | 0 .../galactic-agent}/api/local/local.go | 0 .../galactic-agent}/api/local/local.pb.go | 2 +- .../galactic-agent/api/local/local.proto | 2 +- .../api/local/local_grpc.pb.go | 0 .../galactic-agent}/api/remote/remote.go | 0 .../galactic-agent/api/remote/remote.pb.go | 2 +- .../galactic-agent/api/remote}/remote.proto | 2 +- .../galactic-agent/config.yaml | 0 .../galactic-agent/config/base/daemonset.yaml | 0 .../config/base/kustomization.yaml | 0 .../galactic-agent}/generate.sh | 0 .../galactic-agent}/go.mod | 0 .../galactic-agent}/go.sum | 0 .../galactic-agent/main.go | 8 +- .../srv6/neighborproxy/neighborproxy.go | 2 +- .../srv6/routeegress/routeegress.go | 2 +- .../srv6/routeingress/routeingress.go | 4 +- .../galactic-agent}/srv6/srv6.go | 8 +- .../galactic-manifest.yaml | 0 .../srv6-vpc-lab-attachment/run_lab_demo.py | 0 .../srv6-vpc-lab-attachment/setup_wsl_lab.py | 0 .../test-mqtt-route.go | 0 .../wsl/srv6-vpc-lab-attachment/topology.yaml | 0 .../apis}/v1alpha/groupversion_info.go | 0 .../api => pkg/apis}/v1alpha/vpc_types.go | 0 .../apis}/v1alpha/vpcattachment_types.go | 0 .../apis}/v1alpha/zz_generated.deepcopy.go | 0 {galactic-common => pkg/common}/cni/types.go | 0 .../common}/sysctl/sysctl.go | 0 {galactic-common => pkg/common}/util/util.go | 0 .../common}/util/util_test.go | 2 +- {galactic-common => pkg/common}/vrf/vrf.go | 8 +- .../api => pkg/proto}/local/local.go | 0 .../api => pkg/proto}/local/local.pb.go | 2 +- .../api => pkg/proto}/local/local.proto | 2 +- .../api => pkg/proto}/local/local_grpc.pb.go | 0 .../api => pkg/proto}/remote/remote.go | 0 .../api => pkg/proto}/remote/remote.pb.go | 2 +- .../api => pkg/proto}/remote/remote.proto | 2 +- {galactic-router => router}/.flake8 | 0 .../.github/workflows/publish.yml | 0 .../.github/workflows/test.yml | 0 {galactic-router => router}/Dockerfile | 0 {galactic-router => router}/Dockerfile.test | 0 {galactic-lab => router}/LICENSE | 0 {galactic-router => router}/README.md | 0 .../alembic/alembic.ini | 0 {galactic-router => router}/alembic/env.py | 0 .../alembic/script.py.mako | 0 ...add_created_field_to_registration_table.py | 0 .../alembic/versions/0e50c4ae5859_init.py | 0 .../config/base/deployment.yaml | 0 .../config/base/kustomization.yaml | 0 .../features/deregister.feature | 0 .../features/duplicate.feature | 0 .../features/environment.py | 0 .../features/move.feature | 0 .../features/multiple_networks.feature | 0 .../multiple_networks_deregister.feature | 0 .../register-with-vpc-details.feature | 0 .../features/register.feature | 0 .../features/rejoin.feature | 0 .../features/steps/router_steps.py | 0 .../galactic_router/__init__.py | 0 .../galactic_router/bus.py | 0 .../galactic_router/events.py | 0 .../galactic_router/proto}/remote.proto | 2 +- .../galactic_router/proto/remote_pb2.py | 0 .../galactic_router/router/__init__.py | 0 .../galactic_router/router/mqtt.py | 0 .../galactic_router/router/static.py | 0 {galactic-router => router}/pyproject.toml | 0 231 files changed, 864 insertions(+), 5817 deletions(-) create mode 100644 .claude/settings.local.json create mode 100644 .gitignore rename galactic-operator/.golangci.yml => .golangci.yml (100%) rename galactic-operator/Makefile => Makefile (87%) rename {galactic-operator => build}/Dockerfile (80%) create mode 100644 cmd/galactic/main.go rename {galactic-agent/config/base => config/agent}/daemonset.yaml (100%) rename {galactic-agent/config/base => config/agent}/kustomization.yaml (100%) rename {galactic-operator/config => config}/certmanager/certificate-metrics.yaml (100%) rename {galactic-operator/config => config}/certmanager/certificate-webhook.yaml (100%) rename {galactic-operator/config => config}/certmanager/issuer.yaml (100%) rename {galactic-operator/config => config}/certmanager/kustomization.yaml (100%) rename {galactic-operator/config => config}/certmanager/kustomizeconfig.yaml (100%) rename {galactic-operator/config => config}/crd/bases/galactic.datumapis.com_vpcattachments.yaml (100%) rename {galactic-operator/config => config}/crd/bases/galactic.datumapis.com_vpcs.yaml (100%) rename {galactic-operator/config => config}/crd/bases/k8s.cni.cncf.io_network-attachment-definitions.yaml (100%) rename {galactic-operator/config => config}/crd/kustomization.yaml (100%) rename {galactic-operator/config => config}/crd/kustomizeconfig.yaml (100%) rename {galactic-operator/config => config}/default/cert_metrics_manager_patch.yaml (100%) rename {galactic-operator/config => config}/default/kustomization.yaml (100%) rename {galactic-operator/config => config}/default/manager_metrics_patch.yaml (100%) rename {galactic-operator/config => config}/default/manager_webhook_patch.yaml (100%) rename {galactic-operator/config => config}/default/metrics_service.yaml (100%) rename {galactic-operator/config => config}/manager/kustomization.yaml (100%) rename {galactic-operator/config => config}/manager/manager.yaml (100%) rename {galactic-operator/config => config}/network-policy/allow-metrics-traffic.yaml (100%) rename {galactic-operator/config => config}/network-policy/allow-webhook-traffic.yaml (100%) rename {galactic-operator/config => config}/network-policy/kustomization.yaml (100%) rename {galactic-operator/config => config}/prometheus/kustomization.yaml (100%) rename {galactic-operator/config => config}/prometheus/monitor.yaml (100%) rename {galactic-operator/config => config}/prometheus/monitor_tls_patch.yaml (100%) rename {galactic-operator/config => config}/rbac/kustomization.yaml (100%) rename {galactic-operator/config => config}/rbac/leader_election_role.yaml (100%) rename {galactic-operator/config => config}/rbac/leader_election_role_binding.yaml (100%) rename {galactic-operator/config => config}/rbac/metrics_auth_role.yaml (100%) rename {galactic-operator/config => config}/rbac/metrics_auth_role_binding.yaml (100%) rename {galactic-operator/config => config}/rbac/metrics_reader_role.yaml (100%) rename {galactic-operator/config => config}/rbac/role.yaml (100%) rename {galactic-operator/config => config}/rbac/role_binding.yaml (100%) rename {galactic-operator/config => config}/rbac/service_account.yaml (100%) rename {galactic-operator/config => config}/rbac/vpc_admin_role.yaml (100%) rename {galactic-operator/config => config}/rbac/vpc_editor_role.yaml (100%) rename {galactic-operator/config => config}/rbac/vpc_viewer_role.yaml (100%) rename {galactic-operator/config => config}/rbac/vpcattachment_admin_role.yaml (100%) rename {galactic-operator/config => config}/rbac/vpcattachment_editor_role.yaml (100%) rename {galactic-operator/config => config}/rbac/vpcattachment_viewer_role.yaml (100%) rename {galactic-operator/config => config}/samples/galactic_v1alpha_vpc.yaml (100%) rename {galactic-operator/config => config}/samples/galactic_v1alpha_vpcattachment.yaml (100%) rename {galactic-operator/config => config}/samples/kustomization.yaml (100%) rename {galactic-operator/config => config}/samples/pod.yaml (100%) rename {galactic-operator/config => config}/webhook/kustomization.yaml (100%) rename {galactic-operator/config => config}/webhook/kustomizeconfig.yaml (100%) rename {galactic-operator/config => config}/webhook/manifests.yaml (100%) rename {galactic-operator/config => config}/webhook/service.yaml (100%) delete mode 100644 galactic-agent/main.go delete mode 100644 galactic-cni/.github/workflows/build.yml delete mode 100644 galactic-cni/.github/workflows/release.yml delete mode 100644 galactic-cni/.golangci.yml delete mode 100644 galactic-cni/README.md delete mode 100644 galactic-cni/go.mod delete mode 100644 galactic-cni/go.sum delete mode 100644 galactic-cni/main.go delete mode 100644 galactic-common/.github/workflows/build.yml delete mode 100644 galactic-common/LICENSE delete mode 100644 galactic-common/go.mod delete mode 100644 galactic-common/go.sum delete mode 100644 galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/lint.yml delete mode 100644 galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/publish.yml delete mode 100644 galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/test.yml delete mode 100644 galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.golangci.yml delete mode 100644 galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/Dockerfile delete mode 100644 galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/LICENSE delete mode 100644 galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/README.md delete mode 100644 galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/generate.sh delete mode 100644 galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/go.mod delete mode 100644 galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/go.sum delete mode 100644 galactic-operator/.devcontainer/devcontainer.json delete mode 100644 galactic-operator/.devcontainer/post-install.sh delete mode 100644 galactic-operator/.dockerignore delete mode 100644 galactic-operator/.github/workflows/lint.yml delete mode 100644 galactic-operator/.github/workflows/publish.yml delete mode 100644 galactic-operator/.github/workflows/test-e2e.yml delete mode 100644 galactic-operator/.github/workflows/test.yml delete mode 100644 galactic-operator/.gitignore delete mode 100644 galactic-operator/LICENSE delete mode 100644 galactic-operator/PROJECT delete mode 100644 galactic-operator/README.md delete mode 100644 galactic-operator/cmd/main.go delete mode 100644 galactic-operator/dist/install.yaml delete mode 100644 galactic-operator/test/e2e/e2e_suite_test.go delete mode 100644 galactic-operator/test/e2e/e2e_test.go delete mode 100644 galactic-operator/test/utils/utils.go delete mode 100644 galactic-router/LICENSE rename galactic-operator/go.mod => go.mod (53%) rename galactic-operator/go.sum => go.sum (66%) rename {galactic-operator/hack => hack}/boilerplate.go.txt (100%) rename {galactic-agent => internal/agent}/srv6/neighborproxy/neighborproxy.go (94%) rename {galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent => internal/agent}/srv6/routeegress/routeegress.go (95%) rename {galactic-agent => internal/agent}/srv6/routeingress/routeingress.go (92%) rename {galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent => internal/agent}/srv6/srv6.go (94%) create mode 100644 internal/cmd/agent/agent.go create mode 100644 internal/cmd/cni/cni.go create mode 100644 internal/cmd/operator/operator.go create mode 100644 internal/cmd/version/version.go rename {galactic-cni => internal}/cni/cni.go (93%) rename {galactic-cni => internal/cni}/debug/debug.go (100%) rename {galactic-cni => internal}/cni/registration/registration.go (96%) rename {galactic-cni => internal}/cni/route/route.go (92%) rename {galactic-cni => internal}/cni/veth/veth.go (95%) rename {galactic-operator/internal => internal/operator}/cniconfig/cniconfig.go (94%) rename {galactic-operator/internal => internal/operator}/cniconfig/cniconfig_test.go (93%) rename {galactic-operator/internal => internal/operator}/controller/suite_test.go (97%) rename {galactic-operator/internal => internal/operator}/controller/vpc_controller.go (94%) rename {galactic-operator/internal => internal/operator}/controller/vpc_controller_test.go (95%) rename {galactic-operator/internal => internal/operator}/controller/vpcattachment_controller.go (95%) rename {galactic-operator/internal => internal/operator}/controller/vpcattachment_controller_test.go (97%) rename {galactic-operator/internal => internal/operator}/identifier/identifier.go (100%) rename {galactic-operator/internal => internal/operator}/identifier/identifier_test.go (96%) rename {galactic-operator/internal => internal/operator}/webhook/v1/pod_webhook.go (98%) rename {galactic-operator/internal => internal/operator}/webhook/v1/pod_webhook_test.go (97%) rename {galactic-operator/internal => internal/operator}/webhook/v1/webhook_suite_test.go (100%) rename {galactic-lab => lab}/.devcontainer/devcontainer.json (100%) rename {galactic-lab => lab}/Dockerfile (100%) rename {galactic-cni => lab}/LICENSE (100%) rename {galactic-lab => lab}/README.md (100%) rename {galactic-lab => lab}/basic/.gitignore (100%) rename {galactic-lab => lab}/basic/README.md (100%) rename {galactic-lab => lab}/basic/deployment.k8s.yml (100%) rename {galactic-lab => lab}/basic/k01-config.yml (100%) rename {galactic-lab => lab}/basic/topology.svg (100%) rename {galactic-lab => lab}/basic/topology.yml (100%) rename {galactic-lab => lab}/basic/vpc.k8s.yml (100%) rename {galactic-lab => lab}/galactic-lab.code-workspace (100%) rename {galactic-lab => lab}/geo/.gitignore (100%) rename {galactic-lab => lab}/geo/README.md (100%) rename {galactic-lab => lab}/geo/deployment.k8s.yml (100%) rename {galactic-lab => lab}/geo/k01-config.yml (100%) rename {galactic-lab => lab}/geo/topology.svg (100%) rename {galactic-lab => lab}/geo/topology.yml (100%) rename {galactic-lab => lab}/geo/vpc.k8s.yml (100%) rename {galactic-lab => lab}/kindest-node-galactic/Dockerfile (100%) rename {galactic-lab => lab}/kindest-node-galactic/agent.k8s.yml (100%) rename {galactic-lab => lab}/kindest-node-galactic/install.sh (100%) rename {galactic-lab => lab}/kindest-node-galactic/mqtt.k8s.yml (100%) rename {galactic-lab => lab}/kindest-node-galactic/router.k8s.yml (100%) rename {galactic-lab => lab}/platform/wsl/srv6-vpc-lab-attachment/.gitignore (100%) rename {galactic-lab => lab}/platform/wsl/srv6-vpc-lab-attachment/CHANGELOG.md (100%) rename {galactic-lab => lab}/platform/wsl/srv6-vpc-lab-attachment/README.md (100%) rename {galactic-lab => lab}/platform/wsl/srv6-vpc-lab-attachment/TUTORIAL.md (100%) rename {galactic-lab => lab}/platform/wsl/srv6-vpc-lab-attachment/agent.yaml (100%) rename {galactic-lab => lab}/platform/wsl/srv6-vpc-lab-attachment/filter_plugins/netlab_filters.py (100%) rename {galactic-lab => lab}/platform/wsl/srv6-vpc-lab-attachment/galactic-agent-config.yaml (100%) rename {galactic-agent => lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent}/.github/workflows/lint.yml (100%) rename {galactic-agent => lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent}/.github/workflows/publish.yml (100%) rename {galactic-agent => lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent}/.github/workflows/test.yml (100%) rename {galactic-agent => lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent}/.golangci.yml (100%) rename {galactic-agent => lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent}/Dockerfile (100%) rename {galactic-agent => lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent}/LICENSE (100%) rename {galactic-agent => lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent}/README.md (100%) rename {galactic-agent => lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent}/api/local/local.go (100%) rename {galactic-agent => lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent}/api/local/local.pb.go (99%) rename {galactic-lab => lab}/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.proto (86%) rename {galactic-agent => lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent}/api/local/local_grpc.pb.go (100%) rename {galactic-agent => lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent}/api/remote/remote.go (100%) rename {galactic-lab => lab}/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.pb.go (99%) rename {galactic-router/galactic_router/proto => lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote}/remote.proto (86%) rename {galactic-lab => lab}/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config.yaml (100%) rename {galactic-lab => lab}/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config/base/daemonset.yaml (100%) rename {galactic-lab => lab}/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config/base/kustomization.yaml (100%) rename {galactic-agent => lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent}/generate.sh (100%) rename {galactic-agent => lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent}/go.mod (100%) rename {galactic-agent => lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent}/go.sum (100%) rename {galactic-lab => lab}/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/main.go (95%) rename {galactic-lab => lab}/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/neighborproxy/neighborproxy.go (94%) rename {galactic-agent => lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent}/srv6/routeegress/routeegress.go (95%) rename {galactic-lab => lab}/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/routeingress/routeingress.go (92%) rename {galactic-agent => lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent}/srv6/srv6.go (94%) rename {galactic-lab => lab}/platform/wsl/srv6-vpc-lab-attachment/galactic-manifest.yaml (100%) rename {galactic-lab => lab}/platform/wsl/srv6-vpc-lab-attachment/run_lab_demo.py (100%) rename {galactic-lab => lab}/platform/wsl/srv6-vpc-lab-attachment/setup_wsl_lab.py (100%) rename {galactic-lab => lab}/platform/wsl/srv6-vpc-lab-attachment/test-mqtt-route.go (100%) rename {galactic-lab => lab}/platform/wsl/srv6-vpc-lab-attachment/topology.yaml (100%) rename {galactic-operator/api => pkg/apis}/v1alpha/groupversion_info.go (100%) rename {galactic-operator/api => pkg/apis}/v1alpha/vpc_types.go (100%) rename {galactic-operator/api => pkg/apis}/v1alpha/vpcattachment_types.go (100%) rename {galactic-operator/api => pkg/apis}/v1alpha/zz_generated.deepcopy.go (100%) rename {galactic-common => pkg/common}/cni/types.go (100%) rename {galactic-common => pkg/common}/sysctl/sysctl.go (100%) rename {galactic-common => pkg/common}/util/util.go (100%) rename {galactic-common => pkg/common}/util/util_test.go (98%) rename {galactic-common => pkg/common}/vrf/vrf.go (93%) rename {galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api => pkg/proto}/local/local.go (100%) rename {galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api => pkg/proto}/local/local.pb.go (99%) rename {galactic-agent/api => pkg/proto}/local/local.proto (86%) rename {galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api => pkg/proto}/local/local_grpc.pb.go (100%) rename {galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api => pkg/proto}/remote/remote.go (100%) rename {galactic-agent/api => pkg/proto}/remote/remote.pb.go (99%) rename {galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api => pkg/proto}/remote/remote.proto (86%) rename {galactic-router => router}/.flake8 (100%) rename {galactic-router => router}/.github/workflows/publish.yml (100%) rename {galactic-router => router}/.github/workflows/test.yml (100%) rename {galactic-router => router}/Dockerfile (100%) rename {galactic-router => router}/Dockerfile.test (100%) rename {galactic-lab => router}/LICENSE (100%) rename {galactic-router => router}/README.md (100%) rename {galactic-router => router}/alembic/alembic.ini (100%) rename {galactic-router => router}/alembic/env.py (100%) rename {galactic-router => router}/alembic/script.py.mako (100%) rename {galactic-router => router}/alembic/versions/042d8775f6e0_add_created_field_to_registration_table.py (100%) rename {galactic-router => router}/alembic/versions/0e50c4ae5859_init.py (100%) rename {galactic-router => router}/config/base/deployment.yaml (100%) rename {galactic-router => router}/config/base/kustomization.yaml (100%) rename {galactic-router => router}/features/deregister.feature (100%) rename {galactic-router => router}/features/duplicate.feature (100%) rename {galactic-router => router}/features/environment.py (100%) rename {galactic-router => router}/features/move.feature (100%) rename {galactic-router => router}/features/multiple_networks.feature (100%) rename {galactic-router => router}/features/multiple_networks_deregister.feature (100%) rename {galactic-router => router}/features/register-with-vpc-details.feature (100%) rename {galactic-router => router}/features/register.feature (100%) rename {galactic-router => router}/features/rejoin.feature (100%) rename {galactic-router => router}/features/steps/router_steps.py (100%) rename {galactic-router => router}/galactic_router/__init__.py (100%) rename {galactic-router => router}/galactic_router/bus.py (100%) rename {galactic-router => router}/galactic_router/events.py (100%) rename {galactic-agent/api/remote => router/galactic_router/proto}/remote.proto (86%) rename {galactic-router => router}/galactic_router/proto/remote_pb2.py (100%) rename {galactic-router => router}/galactic_router/router/__init__.py (100%) rename {galactic-router => router}/galactic_router/router/mqtt.py (100%) rename {galactic-router => router}/galactic_router/router/static.py (100%) rename {galactic-router => router}/pyproject.toml (100%) diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..ac6841f --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,23 @@ +{ + "permissions": { + "allow": [ + "Bash(git commit:*)", + "Bash(git mv:*)", + "Bash(tree:*)", + "Bash(find:*)", + "Bash(grep:*)", + "Bash(if grep -r \"github\\\\.com/datum-cloud/galactic\" --include=\"*.go\" --include=\"*.proto\" /Users/scotwells/repos/datum-cloud/galactic)", + "Bash(then echo \"WARNING: Found old import paths above\")", + "Bash(else echo \"✓ No old import paths found\")", + "Bash(fi)", + "Bash(go build:*)", + "Bash(go mod tidy:*)", + "Bash(go list:*)", + "Bash(go vet:*)", + "Bash(go tool compile:*)", + "Bash(gofmt:*)", + "Bash(git checkout:*)", + "Bash(git add:*)" + ] + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6e1fb01 --- /dev/null +++ b/.gitignore @@ -0,0 +1,39 @@ +# 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 +*~ + +# OS +.DS_Store + +# 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 100% rename from galactic-operator/.golangci.yml rename to .golangci.yml 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/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 100% rename from galactic-agent/config/base/daemonset.yaml rename to config/agent/daemonset.yaml 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 100% rename from galactic-operator/config/manager/manager.yaml rename to config/manager/manager.yaml 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/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-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/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/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-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/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-agent/srv6/neighborproxy/neighborproxy.go b/internal/agent/srv6/neighborproxy/neighborproxy.go similarity index 94% rename from galactic-agent/srv6/neighborproxy/neighborproxy.go rename to internal/agent/srv6/neighborproxy/neighborproxy.go index 6c35ad5..23e7059 100644 --- a/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..4b2fa84 --- /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..3a41127 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/registration" + "go.datum.net/galactic/internal/cni/route" + "go.datum.net/galactic/internal/cni/veth" + "go.datum.net/galactic/internal/cni/debug" + "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..ab4ac59 100644 --- a/galactic-cni/cni/veth/veth.go +++ b/internal/cni/veth/veth.go @@ -4,8 +4,8 @@ import ( "fmt" "github.com/coreos/go-iptables/iptables" - "github.com/datum-cloud/galactic-common/sysctl" - "github.com/datum-cloud/galactic-common/util" + "go.datum.net/galactic/pkg/common/sysctl" + "go.datum.net/galactic/pkg/common/util" "github.com/vishvananda/netlink" ) 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..c52f2c3 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/pkg/common/cni" + "go.datum.net/galactic/internal/operator/cniconfig" ) func TestCNIConfigForVPCAttachment(t *testing.T) { diff --git a/galactic-operator/internal/controller/suite_test.go b/internal/operator/controller/suite_test.go similarity index 97% rename from galactic-operator/internal/controller/suite_test.go rename to internal/operator/controller/suite_test.go index 0bd35b1..ccf961d 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 ) 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..a7fc6b0 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" + galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha" + "go.datum.net/galactic/internal/operator/identifier" ) 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..c4a0357 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" + galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha" + "go.datum.net/galactic/internal/operator/identifier" ) 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..b078230 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" + galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha" nadv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" - "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..d416ace 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" + galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha" nadv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" - "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 100% rename from galactic-operator/internal/webhook/v1/webhook_suite_test.go rename to internal/operator/webhook/v1/webhook_suite_test.go diff --git a/galactic-lab/.devcontainer/devcontainer.json b/lab/.devcontainer/devcontainer.json similarity index 100% rename from galactic-lab/.devcontainer/devcontainer.json rename to lab/.devcontainer/devcontainer.json 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-cni/LICENSE b/lab/LICENSE similarity index 100% rename from galactic-cni/LICENSE rename to lab/LICENSE diff --git a/galactic-lab/README.md b/lab/README.md similarity index 100% rename from galactic-lab/README.md rename to lab/README.md 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 100% rename from galactic-lab/kindest-node-galactic/install.sh rename to lab/kindest-node-galactic/install.sh 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 100% rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/README.md rename to lab/platform/wsl/srv6-vpc-lab-attachment/README.md 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 100% rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/TUTORIAL.md rename to lab/platform/wsl/srv6-vpc-lab-attachment/TUTORIAL.md 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 100% 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 diff --git a/galactic-agent/.github/workflows/lint.yml b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/lint.yml similarity index 100% rename from galactic-agent/.github/workflows/lint.yml rename to lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/lint.yml diff --git a/galactic-agent/.github/workflows/publish.yml b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/publish.yml similarity index 100% rename from galactic-agent/.github/workflows/publish.yml rename to lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/publish.yml diff --git a/galactic-agent/.github/workflows/test.yml b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/test.yml similarity index 100% rename from galactic-agent/.github/workflows/test.yml rename to lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/test.yml diff --git a/galactic-agent/.golangci.yml b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.golangci.yml similarity index 100% rename from galactic-agent/.golangci.yml rename to lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.golangci.yml diff --git a/galactic-agent/Dockerfile b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/Dockerfile similarity index 100% rename from galactic-agent/Dockerfile rename to lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/Dockerfile diff --git a/galactic-agent/LICENSE b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/LICENSE similarity index 100% rename from galactic-agent/LICENSE rename to lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/LICENSE diff --git a/galactic-agent/README.md b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/README.md similarity index 100% rename from galactic-agent/README.md rename to lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/README.md diff --git a/galactic-agent/api/local/local.go b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.go similarity index 100% rename from galactic-agent/api/local/local.go rename to lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.go diff --git a/galactic-agent/api/local/local.pb.go b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.pb.go similarity index 99% rename from galactic-agent/api/local/local.pb.go rename to lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.pb.go index a6fc035..3706265 100644 --- a/galactic-agent/api/local/local.pb.go +++ b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.pb.go @@ -249,7 +249,7 @@ 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.DeregisterReplyB7Z5go.datum.net/galactic/pkg/proto/local;localb\x06proto3" var ( file_local_proto_rawDescOnce sync.Once diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.proto b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.proto similarity index 86% rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.proto rename to lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.proto index b45fb42..387264b 100644 --- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.proto +++ b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/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-agent/api/local/local_grpc.pb.go b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local_grpc.pb.go similarity index 100% rename from galactic-agent/api/local/local_grpc.pb.go rename to lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local_grpc.pb.go diff --git a/galactic-agent/api/remote/remote.go b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.go similarity index 100% rename from galactic-agent/api/remote/remote.go rename to lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.go diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.pb.go b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.pb.go similarity index 99% rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.pb.go rename to lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.pb.go index edcce0d..d88da2f 100644 --- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.pb.go +++ b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.pb.go @@ -364,7 +364,7 @@ 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\x01B9Z7go.datum.net/galactic/pkg/proto/remote;remoteb\x06proto3" var ( file_remote_proto_rawDescOnce sync.Once diff --git a/galactic-router/galactic_router/proto/remote.proto b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.proto similarity index 86% rename from galactic-router/galactic_router/proto/remote.proto rename to lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.proto index 87ad223..fd88514 100644 --- a/galactic-router/galactic_router/proto/remote.proto +++ b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/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-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 100% 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 diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config/base/daemonset.yaml b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config/base/daemonset.yaml similarity index 100% rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config/base/daemonset.yaml rename to lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config/base/daemonset.yaml diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config/base/kustomization.yaml b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config/base/kustomization.yaml similarity index 100% rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config/base/kustomization.yaml rename to lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config/base/kustomization.yaml diff --git a/galactic-agent/generate.sh b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/generate.sh similarity index 100% rename from galactic-agent/generate.sh rename to lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/generate.sh diff --git a/galactic-agent/go.mod b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/go.mod similarity index 100% rename from galactic-agent/go.mod rename to lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/go.mod diff --git a/galactic-agent/go.sum b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/go.sum similarity index 100% rename from galactic-agent/go.sum rename to lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/go.sum diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/main.go b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/main.go similarity index 95% rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/main.go rename to lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/main.go index 9726b12..60f9531 100644 --- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/main.go +++ b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/main.go @@ -14,10 +14,10 @@ import ( "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" + "go.datum.net/galactic/pkg/proto/local" + "go.datum.net/galactic/pkg/proto/remote" + "go.datum.net/galactic/internal/agent/srv6" + "go.datum.net/galactic/pkg/common/util" ) var configFile string diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/neighborproxy/neighborproxy.go b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-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 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-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-agent/srv6/routeegress/routeegress.go b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/routeegress/routeegress.go similarity index 95% rename from galactic-agent/srv6/routeegress/routeegress.go rename to lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/routeegress/routeegress.go index 80ec67a..479ee1d 100644 --- a/galactic-agent/srv6/routeegress/routeegress.go +++ b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-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-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/routeingress/routeingress.go b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/routeingress/routeingress.go similarity index 92% rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/routeingress/routeingress.go rename to lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/routeingress/routeingress.go index 00ffbdc..b4e4393 100644 --- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/routeingress/routeingress.go +++ b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-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-agent/srv6/srv6.go b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/srv6.go similarity index 94% rename from galactic-agent/srv6/srv6.go rename to lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/srv6.go index 6b6cecf..e6fab25 100644 --- a/galactic-agent/srv6/srv6.go +++ b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-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/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 100% 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 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 100% 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 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 98% rename from galactic-common/util/util_test.go rename to pkg/common/util/util_test.go index 08aed52..c2f76c1 100644 --- a/galactic-common/util/util_test.go +++ b/pkg/common/util/util_test.go @@ -5,7 +5,7 @@ import ( "reflect" "testing" - "github.com/datum-cloud/galactic-common/util" + "go.datum.net/galactic/pkg/common/util" ) func TestGenerateInterfaceNameVRF(t *testing.T) { diff --git a/galactic-common/vrf/vrf.go b/pkg/common/vrf/vrf.go similarity index 93% rename from galactic-common/vrf/vrf.go rename to pkg/common/vrf/vrf.go index eacb0ee..8cda3a2 100644 --- a/galactic-common/vrf/vrf.go +++ b/pkg/common/vrf/vrf.go @@ -5,8 +5,10 @@ import ( "math" "slices" - "github.com/datum-cloud/galactic-common/sysctl" - "github.com/datum-cloud/galactic-common/util" + "golang.org/x/sys/unix" + + "go.datum.net/galactic/pkg/common/sysctl" + "go.datum.net/galactic/pkg/common/util" "github.com/vishvananda/netlink" ) @@ -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-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.go b/pkg/proto/local/local.go similarity index 100% rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.go rename to pkg/proto/local/local.go diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.pb.go b/pkg/proto/local/local.pb.go similarity index 99% rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.pb.go rename to pkg/proto/local/local.pb.go index a6fc035..3706265 100644 --- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.pb.go +++ b/pkg/proto/local/local.pb.go @@ -249,7 +249,7 @@ 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.DeregisterReplyB7Z5go.datum.net/galactic/pkg/proto/local;localb\x06proto3" var ( file_local_proto_rawDescOnce sync.Once diff --git a/galactic-agent/api/local/local.proto b/pkg/proto/local/local.proto similarity index 86% rename from galactic-agent/api/local/local.proto rename to pkg/proto/local/local.proto index b45fb42..387264b 100644 --- a/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 100% 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 diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.go b/pkg/proto/remote/remote.go similarity index 100% rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/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 99% rename from galactic-agent/api/remote/remote.pb.go rename to pkg/proto/remote/remote.pb.go index edcce0d..d88da2f 100644 --- a/galactic-agent/api/remote/remote.pb.go +++ b/pkg/proto/remote/remote.pb.go @@ -364,7 +364,7 @@ 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\x01B9Z7go.datum.net/galactic/pkg/proto/remote;remoteb\x06proto3" var ( file_remote_proto_rawDescOnce sync.Once diff --git a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.proto b/pkg/proto/remote/remote.proto similarity index 86% rename from galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.proto rename to pkg/proto/remote/remote.proto index 87ad223..fd88514 100644 --- a/galactic-lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/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 100% rename from galactic-router/.flake8 rename to router/.flake8 diff --git a/galactic-router/.github/workflows/publish.yml b/router/.github/workflows/publish.yml similarity index 100% rename from galactic-router/.github/workflows/publish.yml rename to router/.github/workflows/publish.yml diff --git a/galactic-router/.github/workflows/test.yml b/router/.github/workflows/test.yml similarity index 100% rename from galactic-router/.github/workflows/test.yml rename to router/.github/workflows/test.yml 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-lab/LICENSE b/router/LICENSE similarity index 100% rename from galactic-lab/LICENSE rename to router/LICENSE 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-agent/api/remote/remote.proto b/router/galactic_router/proto/remote.proto similarity index 86% rename from galactic-agent/api/remote/remote.proto rename to router/galactic_router/proto/remote.proto index 87ad223..fd88514 100644 --- a/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 100% rename from galactic-router/galactic_router/proto/remote_pb2.py rename to router/galactic_router/proto/remote_pb2.py 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 From b000cd26e62e9061de7f6a04635f79e4b434de2d Mon Sep 17 00:00:00 2001 From: Scot Wells Date: Fri, 6 Mar 2026 13:28:37 -0600 Subject: [PATCH 02/18] Add unified devcontainer for full development environment Provides a complete Linux development environment with: - Go 1.24 with gopls, delve, golangci-lint - Python 3.13 for router development - Docker-in-Docker for Kind clusters - Network tools (iproute2, iptables, tcpdump) for SRv6/CNI testing - kubectl, kustomize, kind for Kubernetes development - protoc for Protocol Buffer compilation Runs with elevated privileges (NET_ADMIN, SYS_ADMIN) required for network namespace operations, VRF configuration, and CNI testing. Co-Authored-By: Claude Opus 4.5 --- .devcontainer/README.md | 222 ++++++++++++++++++++++++++++++++ .devcontainer/devcontainer.json | 136 +++++++++++++++++++ .devcontainer/post-create.sh | 91 +++++++++++++ 3 files changed, 449 insertions(+) create mode 100644 .devcontainer/README.md create mode 100644 .devcontainer/devcontainer.json create mode 100755 .devcontainer/post-create.sh 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..5266ea6 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,136 @@ +{ + "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" + } + }, + "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" + ], + "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..98306f3 --- /dev/null +++ b/.devcontainer/post-create.sh @@ -0,0 +1,91 @@ +#!/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 + +# 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 "" From e7f7d36784cf4bcd526906e823173ee55198e4f9 Mon Sep 17 00:00:00 2001 From: Scot Wells Date: Fri, 6 Mar 2026 13:30:26 -0600 Subject: [PATCH 03/18] Remove lab devcontainer in favor of unified root devcontainer The root .devcontainer/ now provides all development capabilities including Docker-in-Docker for lab testing. Co-Authored-By: Claude Opus 4.5 --- lab/.devcontainer/devcontainer.json | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 lab/.devcontainer/devcontainer.json diff --git a/lab/.devcontainer/devcontainer.json b/lab/.devcontainer/devcontainer.json deleted file mode 100644 index eaa59d4..0000000 --- a/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" - } - } -} From 8353a917c8621431144764050622affa2b622fff Mon Sep 17 00:00:00 2001 From: Scot Wells Date: Fri, 6 Mar 2026 13:37:04 -0600 Subject: [PATCH 04/18] Remove duplicate galactic-agent from WSL lab The standalone agent in lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/ is now redundant since the agent code exists in the main repo at internal/agent/. The WSL lab should use the consolidated galactic binary instead. Co-Authored-By: Claude Opus 4.5 --- .../galactic-agent/.github/workflows/lint.yml | 16 - .../.github/workflows/publish.yml | 34 - .../galactic-agent/.github/workflows/test.yml | 18 - .../galactic-agent/.golangci.yml | 5 - .../galactic-agent/Dockerfile | 14 - .../galactic-agent/LICENSE | 661 ------------------ .../galactic-agent/README.md | 3 - .../galactic-agent/api/local/local.go | 66 -- .../galactic-agent/api/local/local.pb.go | 307 -------- .../galactic-agent/api/local/local.proto | 29 - .../galactic-agent/api/local/local_grpc.pb.go | 159 ----- .../galactic-agent/api/remote/remote.go | 76 -- .../galactic-agent/api/remote/remote.pb.go | 430 ------------ .../galactic-agent/api/remote/remote.proto | 34 - .../galactic-agent/config.yaml | 19 - .../galactic-agent/config/base/daemonset.yaml | 46 -- .../config/base/kustomization.yaml | 2 - .../galactic-agent/generate.sh | 24 - .../galactic-agent/go.mod | 44 -- .../galactic-agent/go.sum | 127 ---- .../galactic-agent/main.go | 167 ----- .../srv6/neighborproxy/neighborproxy.go | 43 -- .../srv6/routeegress/routeegress.go | 55 -- .../srv6/routeingress/routeingress.go | 54 -- .../galactic-agent/srv6/srv6.go | 145 ---- 25 files changed, 2578 deletions(-) delete mode 100644 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/lint.yml delete mode 100644 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/publish.yml delete mode 100644 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/test.yml delete mode 100644 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.golangci.yml delete mode 100644 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/Dockerfile delete mode 100644 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/LICENSE delete mode 100644 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/README.md delete mode 100644 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.go delete mode 100644 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.pb.go delete mode 100644 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.proto delete mode 100644 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local_grpc.pb.go delete mode 100644 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.go delete mode 100644 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.pb.go delete mode 100644 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.proto delete mode 100644 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config.yaml delete mode 100644 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config/base/daemonset.yaml delete mode 100644 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config/base/kustomization.yaml delete mode 100644 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/generate.sh delete mode 100644 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/go.mod delete mode 100644 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/go.sum delete mode 100644 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/main.go delete mode 100644 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/neighborproxy/neighborproxy.go delete mode 100644 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/routeegress/routeegress.go delete mode 100644 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/routeingress/routeingress.go delete mode 100644 lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/srv6.go diff --git a/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/lint.yml b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/lint.yml deleted file mode 100644 index 7f54b02..0000000 --- a/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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/publish.yml b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/publish.yml deleted file mode 100644 index d3a8553..0000000 --- a/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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/test.yml b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.github/workflows/test.yml deleted file mode 100644 index e606f10..0000000 --- a/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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.golangci.yml b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/.golangci.yml deleted file mode 100644 index 366252d..0000000 --- a/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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/Dockerfile b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/Dockerfile deleted file mode 100644 index 96460f2..0000000 --- a/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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/LICENSE b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/LICENSE deleted file mode 100644 index 0ad25db..0000000 --- a/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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/README.md b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/README.md deleted file mode 100644 index ffbb99d..0000000 --- a/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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.go b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.go deleted file mode 100644 index b718373..0000000 --- a/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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.pb.go b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.pb.go deleted file mode 100644 index 3706265..0000000 --- a/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.DeregisterReplyB7Z5go.datum.net/galactic/pkg/proto/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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.proto b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.proto deleted file mode 100644 index 387264b..0000000 --- a/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local.proto +++ /dev/null @@ -1,29 +0,0 @@ -syntax = "proto3"; - -package local.v1; -option go_package = "go.datum.net/galactic/pkg/proto/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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local_grpc.pb.go b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/local/local_grpc.pb.go deleted file mode 100644 index ec0612d..0000000 --- a/lab/platform/wsl/srv6-vpc-lab-attachment/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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.go b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.go deleted file mode 100644 index 775c55f..0000000 --- a/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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.pb.go b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.pb.go deleted file mode 100644 index d88da2f..0000000 --- a/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\x01B9Z7go.datum.net/galactic/pkg/proto/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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.proto b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.proto deleted file mode 100644 index fd88514..0000000 --- a/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/api/remote/remote.proto +++ /dev/null @@ -1,34 +0,0 @@ -syntax = "proto3"; - -package remote.v1; -option go_package = "go.datum.net/galactic/pkg/proto/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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config.yaml b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config.yaml deleted file mode 100644 index c6f48fe..0000000 --- a/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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config/base/daemonset.yaml b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config/base/daemonset.yaml deleted file mode 100644 index ca8b0a0..0000000 --- a/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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config/base/kustomization.yaml b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/config/base/kustomization.yaml deleted file mode 100644 index 0987901..0000000 --- a/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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/generate.sh b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/generate.sh deleted file mode 100644 index 98b4df0..0000000 --- a/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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/go.mod b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/go.mod deleted file mode 100644 index cf3ae3c..0000000 --- a/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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/go.sum b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/go.sum deleted file mode 100644 index e5b60d8..0000000 --- a/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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/main.go b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/main.go deleted file mode 100644 index 60f9531..0000000 --- a/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" - - "go.datum.net/galactic/pkg/proto/local" - "go.datum.net/galactic/pkg/proto/remote" - "go.datum.net/galactic/internal/agent/srv6" - "go.datum.net/galactic/pkg/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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/neighborproxy/neighborproxy.go b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/neighborproxy/neighborproxy.go deleted file mode 100644 index 23e7059..0000000 --- a/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/neighborproxy/neighborproxy.go +++ /dev/null @@ -1,43 +0,0 @@ -package neighborproxy - -import ( - "net" - - "github.com/vishvananda/netlink" - - "go.datum.net/galactic/pkg/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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/routeegress/routeegress.go b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/routeegress/routeegress.go deleted file mode 100644 index 479ee1d..0000000 --- a/lab/platform/wsl/srv6-vpc-lab-attachment/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" - - "go.datum.net/galactic/pkg/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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/routeingress/routeingress.go b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/routeingress/routeingress.go deleted file mode 100644 index b4e4393..0000000 --- a/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" - - "go.datum.net/galactic/pkg/common/util" - "go.datum.net/galactic/pkg/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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/srv6.go b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/srv6.go deleted file mode 100644 index e6fab25..0000000 --- a/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent/srv6/srv6.go +++ /dev/null @@ -1,145 +0,0 @@ -package srv6 - -import ( - "errors" - "fmt" - - "github.com/vishvananda/netlink" - - "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 { - 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 -} From c6c18552ff4651fe2b5f924162fb4849730addc5 Mon Sep 17 00:00:00 2001 From: Scot Wells Date: Fri, 6 Mar 2026 15:00:03 -0600 Subject: [PATCH 05/18] Add local test runner script Provides Docker-based testing for macOS development: - ./scripts/test-local.sh unit - Fast unit tests - ./scripts/test-local.sh router - Python BDD tests - ./scripts/test-local.sh operator - Full operator tests with envtest - ./scripts/test-local.sh build - Build Linux binary - ./scripts/test-local.sh all - Run everything Co-Authored-By: Claude Opus 4.5 --- scripts/test-local.sh | 92 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100755 scripts/test-local.sh 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 ===" From c61bd7a2ef121c578af3e1efcd30ad91cbed0de8 Mon Sep 17 00:00:00 2001 From: Scot Wells Date: Fri, 6 Mar 2026 15:08:26 -0600 Subject: [PATCH 06/18] Add GitHub Actions CI/CD workflows CI workflow (.github/workflows/ci.yml): - Tier 1 (every PR): - Lint with golangci-lint - Unit tests for operator and common packages - Operator tests with envtest - Router BDD tests with Behave - Build verification - Docker image build (no push) - Tier 2 (main branch/releases): - E2E tests with Kind cluster - CRD installation verification - Operator deployment validation - Sample resource creation Release workflow (.github/workflows/release.yml): - Triggered on version tags (v*) - Multi-arch build (amd64, arm64) - Push to ghcr.io - Generate install manifest - Create GitHub release Also adds Dependabot configuration for: - Go modules (weekly) - GitHub Actions (weekly) - Python dependencies (weekly) - Docker base images (weekly) Co-Authored-By: Claude Opus 4.5 --- .github/dependabot.yml | 34 ++++++ .github/workflows/ci.yml | 192 ++++++++++++++++++++++++++++++++++ .github/workflows/release.yml | 74 +++++++++++++ 3 files changed, 300 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/release.yml 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..9b2d401 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,192 @@ +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@v6 + with: + version: v1.61 + 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: Install envtest + run: | + go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest + setup-envtest use 1.31.0 --bin-dir ./bin/k8s + + - name: Run operator tests + run: | + export KUBEBUILDER_ASSETS=$(setup-envtest use 1.31.0 --bin-dir ./bin/k8s -p path) + 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 From 7ea13c097494dcb158c4a885bf4f6c0c4486a624 Mon Sep 17 00:00:00 2001 From: Scot Wells Date: Fri, 6 Mar 2026 15:10:23 -0600 Subject: [PATCH 07/18] Remove redundant router GitHub workflows These are superseded by the root CI/CD workflows: - router/.github/workflows/test.yml -> .github/workflows/ci.yml (test-router job) - router/.github/workflows/publish.yml -> .github/workflows/release.yml Co-Authored-By: Claude Opus 4.5 --- router/.github/workflows/publish.yml | 34 ---------------------------- router/.github/workflows/test.yml | 20 ---------------- 2 files changed, 54 deletions(-) delete mode 100644 router/.github/workflows/publish.yml delete mode 100644 router/.github/workflows/test.yml diff --git a/router/.github/workflows/publish.yml b/router/.github/workflows/publish.yml deleted file mode 100644 index a1c12a7..0000000 --- a/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/router/.github/workflows/test.yml b/router/.github/workflows/test.yml deleted file mode 100644 index 2dcf069..0000000 --- a/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 From b8efc24f858fbec3e7b8df78f287c96b89004b9d Mon Sep 17 00:00:00 2001 From: Scot Wells Date: Fri, 6 Mar 2026 15:16:14 -0600 Subject: [PATCH 08/18] Add project README with high-level overview Introduces a concise README that explains Galactic's purpose as a multi-cloud networking solution for Kubernetes, the problem it solves, and the value it provides to developers, platform teams, and organizations. Co-Authored-By: Claude Opus 4.5 --- README.md | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 README.md 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).* From 6d273459652780c1fad4c6b6db8ef088aeee9e52 Mon Sep 17 00:00:00 2001 From: Scot Wells Date: Fri, 6 Mar 2026 15:30:55 -0600 Subject: [PATCH 09/18] Clean up old repo references and consolidate LICENSE - Move LICENSE to repo root (was lab/LICENSE) - Remove duplicate router/LICENSE - Update config/manager/manager.yaml with consolidated image and command - Update config/agent/daemonset.yaml with consolidated image and command - Update lab documentation to reference consolidated repo - Update lab/kindest-node-galactic/install.sh for unified binary - Update WSL lab setup scripts and config files - Regenerate router protobuf with correct go_package path - Fix remaining import paths in internal packages Co-Authored-By: Claude Opus 4.5 --- lab/LICENSE => LICENSE | 0 config/agent/daemonset.yaml | 3 +- config/manager/manager.yaml | 5 +- internal/cmd/agent/agent.go | 2 +- internal/cni/cni.go | 2 +- internal/cni/veth/veth.go | 2 +- internal/operator/cniconfig/cniconfig_test.go | 2 +- .../operator/controller/vpc_controller.go | 2 +- .../controller/vpc_controller_test.go | 2 +- .../controller/vpcattachment_controller.go | 2 +- .../vpcattachment_controller_test.go | 2 +- lab/README.md | 4 +- lab/kindest-node-galactic/install.sh | 17 +- .../wsl/srv6-vpc-lab-attachment/README.md | 6 +- .../wsl/srv6-vpc-lab-attachment/TUTORIAL.md | 18 +- .../galactic-agent-config.yaml | 2 +- .../srv6-vpc-lab-attachment/setup_wsl_lab.py | 34 +- .../test-mqtt-route.go | 634 ++++++++--------- pkg/common/vrf/vrf.go | 2 +- router/LICENSE | 661 ------------------ router/galactic_router/proto/remote_pb2.py | 47 +- 21 files changed, 399 insertions(+), 1050 deletions(-) rename lab/LICENSE => LICENSE (100%) delete mode 100644 router/LICENSE diff --git a/lab/LICENSE b/LICENSE similarity index 100% rename from lab/LICENSE rename to LICENSE diff --git a/config/agent/daemonset.yaml b/config/agent/daemonset.yaml index ca8b0a0..8b3ba3a 100644 --- a/config/agent/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/config/manager/manager.yaml b/config/manager/manager.yaml index 3d3a7bb..5792355 100644 --- a/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/internal/cmd/agent/agent.go b/internal/cmd/agent/agent.go index 4b2fa84..25422dc 100644 --- a/internal/cmd/agent/agent.go +++ b/internal/cmd/agent/agent.go @@ -19,7 +19,7 @@ package agent import ( "context" "log" - + "os/signal" "syscall" diff --git a/internal/cni/cni.go b/internal/cni/cni.go index 3a41127..3ad9e38 100644 --- a/internal/cni/cni.go +++ b/internal/cni/cni.go @@ -16,10 +16,10 @@ import ( type100 "github.com/containernetworking/cni/pkg/types/100" "github.com/containernetworking/cni/pkg/version" + "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/internal/cni/debug" "go.datum.net/galactic/pkg/common/cni" "go.datum.net/galactic/pkg/common/util" "go.datum.net/galactic/pkg/common/vrf" diff --git a/internal/cni/veth/veth.go b/internal/cni/veth/veth.go index ab4ac59..6753a9b 100644 --- a/internal/cni/veth/veth.go +++ b/internal/cni/veth/veth.go @@ -4,9 +4,9 @@ import ( "fmt" "github.com/coreos/go-iptables/iptables" + "github.com/vishvananda/netlink" "go.datum.net/galactic/pkg/common/sysctl" "go.datum.net/galactic/pkg/common/util" - "github.com/vishvananda/netlink" ) func updateForwardRule(interfaceName string, action string) error { diff --git a/internal/operator/cniconfig/cniconfig_test.go b/internal/operator/cniconfig/cniconfig_test.go index c52f2c3..774a634 100644 --- a/internal/operator/cniconfig/cniconfig_test.go +++ b/internal/operator/cniconfig/cniconfig_test.go @@ -9,8 +9,8 @@ import ( galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha" - "go.datum.net/galactic/pkg/common/cni" "go.datum.net/galactic/internal/operator/cniconfig" + "go.datum.net/galactic/pkg/common/cni" ) func TestCNIConfigForVPCAttachment(t *testing.T) { diff --git a/internal/operator/controller/vpc_controller.go b/internal/operator/controller/vpc_controller.go index a7fc6b0..4929427 100644 --- a/internal/operator/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 "go.datum.net/galactic/pkg/apis/v1alpha" "go.datum.net/galactic/internal/operator/identifier" + galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha" ) const MaxIdentifierAttemptsVPC = 100 diff --git a/internal/operator/controller/vpc_controller_test.go b/internal/operator/controller/vpc_controller_test.go index c4a0357..95e29c3 100644 --- a/internal/operator/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 "go.datum.net/galactic/pkg/apis/v1alpha" "go.datum.net/galactic/internal/operator/identifier" + galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha" ) var _ = Describe("VPC Controller", func() { diff --git a/internal/operator/controller/vpcattachment_controller.go b/internal/operator/controller/vpcattachment_controller.go index b078230..b336c51 100644 --- a/internal/operator/controller/vpcattachment_controller.go +++ b/internal/operator/controller/vpcattachment_controller.go @@ -15,8 +15,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha" nadv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" + galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha" "go.datum.net/galactic/internal/operator/cniconfig" "go.datum.net/galactic/internal/operator/identifier" diff --git a/internal/operator/controller/vpcattachment_controller_test.go b/internal/operator/controller/vpcattachment_controller_test.go index d416ace..83d69d1 100644 --- a/internal/operator/controller/vpcattachment_controller_test.go +++ b/internal/operator/controller/vpcattachment_controller_test.go @@ -13,8 +13,8 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha" nadv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" + galacticv1alpha "go.datum.net/galactic/pkg/apis/v1alpha" "go.datum.net/galactic/internal/operator/identifier" ) diff --git a/lab/README.md b/lab/README.md index fd1eba1..36a852f 100644 --- a/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/lab/kindest-node-galactic/install.sh b/lab/kindest-node-galactic/install.sh index f53bf8c..6c13963 100644 --- a/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/lab/platform/wsl/srv6-vpc-lab-attachment/README.md b/lab/platform/wsl/srv6-vpc-lab-attachment/README.md index b22f18d..38fff41 100755 --- a/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/lab/platform/wsl/srv6-vpc-lab-attachment/TUTORIAL.md b/lab/platform/wsl/srv6-vpc-lab-attachment/TUTORIAL.md index 8656801..124e4b2 100755 --- a/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/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent-config.yaml b/lab/platform/wsl/srv6-vpc-lab-attachment/galactic-agent-config.yaml index 947a2ae..c2b2ae7 100755 --- a/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/lab/platform/wsl/srv6-vpc-lab-attachment/setup_wsl_lab.py b/lab/platform/wsl/srv6-vpc-lab-attachment/setup_wsl_lab.py index 2160d09..f117de3 100755 --- a/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/lab/platform/wsl/srv6-vpc-lab-attachment/test-mqtt-route.go b/lab/platform/wsl/srv6-vpc-lab-attachment/test-mqtt-route.go index c4072b7..4d97303 100755 --- a/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/pkg/common/vrf/vrf.go b/pkg/common/vrf/vrf.go index 8cda3a2..64b87b4 100644 --- a/pkg/common/vrf/vrf.go +++ b/pkg/common/vrf/vrf.go @@ -7,9 +7,9 @@ import ( "golang.org/x/sys/unix" + "github.com/vishvananda/netlink" "go.datum.net/galactic/pkg/common/sysctl" "go.datum.net/galactic/pkg/common/util" - "github.com/vishvananda/netlink" ) const MinVRFId = uint32(1) diff --git a/router/LICENSE b/router/LICENSE deleted file mode 100644 index bae94e1..0000000 --- a/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/router/galactic_router/proto/remote_pb2.py b/router/galactic_router/proto/remote_pb2.py index 4132062..af8e44f 100644 --- a/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) From 4f79dd31d69196c3d89cc8a4c31d11c9802d708c Mon Sep 17 00:00:00 2001 From: Scot Wells Date: Fri, 6 Mar 2026 15:31:16 -0600 Subject: [PATCH 10/18] Add Python cache patterns to .gitignore Co-Authored-By: Claude Opus 4.5 --- .gitignore | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.gitignore b/.gitignore index 6e1fb01..b7476df 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,14 @@ go.work # OS .DS_Store +# Python +__pycache__/ +*.py[cod] +*$py.class +.Python +*.egg-info/ +.eggs/ + # kubebuilder testbin/ From aaa486012b7c47000c6dcdf476b739f28702c8d5 Mon Sep 17 00:00:00 2001 From: Scot Wells Date: Fri, 6 Mar 2026 15:42:20 -0600 Subject: [PATCH 11/18] Fix CI workflow issues - Update golangci-lint to v2.1.6 (supports Go 1.24) - Add WPS365 to flake8 ignore list (match statement used intentionally) - Regenerate Go protobuf with correct tooling Co-Authored-By: Claude Opus 4.5 --- .github/workflows/ci.yml | 2 +- pkg/proto/remote/remote.pb.go | 88 +++++++++++++++++------------------ router/.flake8 | 2 + 3 files changed, 47 insertions(+), 45 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9b2d401..727aaed 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: - name: Run golangci-lint uses: golangci/golangci-lint-action@v6 with: - version: v1.61 + version: v2.1.6 args: --timeout=5m test-unit: diff --git a/pkg/proto/remote/remote.pb.go b/pkg/proto/remote/remote.pb.go index d88da2f..6be379d 100644 --- a/pkg/proto/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\x01B9Z7go.datum.net/galactic/pkg/proto/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/router/.flake8 b/router/.flake8 index 12198d2..d11634b 100644 --- a/router/.flake8 +++ b/router/.flake8 @@ -17,3 +17,5 @@ extend-ignore = WPS476, # InitModuleHasLogicViolation WPS412, + # SimplifiableMatchStatementViolation (match for clarity) + WPS365, From 67d1cacd2815be2dcd08b2ef58c6ece3651d07b2 Mon Sep 17 00:00:00 2001 From: Scot Wells Date: Fri, 6 Mar 2026 15:47:32 -0600 Subject: [PATCH 12/18] Fix CI: upgrade golangci-lint action, fix envtest, regenerate protos - Use golangci-lint-action v7 (required for golangci-lint v2.x) - Fix KUBEBUILDER_ASSETS setup in operator tests - Regenerate local.pb.go and local_grpc.pb.go with correct tooling Co-Authored-By: Claude Opus 4.5 --- .github/workflows/ci.yml | 10 ++--- pkg/proto/local/local.pb.go | 76 ++++++++++++++++---------------- pkg/proto/local/local_grpc.pb.go | 14 +++--- 3 files changed, 50 insertions(+), 50 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 727aaed..04d6acb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: go-version: ${{ env.GO_VERSION }} - name: Run golangci-lint - uses: golangci/golangci-lint-action@v6 + uses: golangci/golangci-lint-action@v7 with: version: v2.1.6 args: --timeout=5m @@ -62,13 +62,13 @@ jobs: go-version: ${{ env.GO_VERSION }} - name: Install envtest - run: | - go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest - setup-envtest use 1.31.0 --bin-dir ./bin/k8s + run: go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest - name: Run operator tests run: | - export KUBEBUILDER_ASSETS=$(setup-envtest use 1.31.0 --bin-dir ./bin/k8s -p path) + 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 diff --git a/pkg/proto/local/local.pb.go b/pkg/proto/local/local.pb.go index 3706265..295117d 100644 --- a/pkg/proto/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.DeregisterReplyB7Z5go.datum.net/galactic/pkg/proto/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/pkg/proto/local/local_grpc.pb.go b/pkg/proto/local/local_grpc.pb.go index ec0612d..136b523 100644 --- a/pkg/proto/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", } From c081d9176ad321f3db46d2a5e206a41009f85a28 Mon Sep 17 00:00:00 2001 From: Scot Wells Date: Fri, 6 Mar 2026 15:54:08 -0600 Subject: [PATCH 13/18] Fix remaining CI lint and operator test failures - Add manifest generation step to operator tests workflow - Fix errcheck errors by explicitly ignoring viper.BindPFlag returns - Remove unnecessary uint32 conversion in vrf.go - Exclude lab directory from golangci-lint checks Co-Authored-By: Claude Opus 4.5 --- .github/workflows/ci.yml | 3 +++ .golangci.yml | 1 + internal/cmd/agent/agent.go | 18 +++++++++--------- pkg/common/vrf/vrf.go | 2 +- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 04d6acb..9396a83 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -61,6 +61,9 @@ jobs: 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 diff --git a/.golangci.yml b/.golangci.yml index e5b21b0..e48464a 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -40,6 +40,7 @@ linters: - third_party$ - builtin$ - examples$ + - lab$ formatters: enable: - gofmt diff --git a/internal/cmd/agent/agent.go b/internal/cmd/agent/agent.go index 25422dc..30c1dcb 100644 --- a/internal/cmd/agent/agent.go +++ b/internal/cmd/agent/agent.go @@ -66,15 +66,15 @@ It communicates with the CNI plugin via a local gRPC socket and with the router 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")) + _ = 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 } diff --git a/pkg/common/vrf/vrf.go b/pkg/common/vrf/vrf.go index 64b87b4..49b9d76 100644 --- a/pkg/common/vrf/vrf.go +++ b/pkg/common/vrf/vrf.go @@ -31,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 { From a24c28c8439bc70fcd22aefaf95d5db1f1e18782 Mon Sep 17 00:00:00 2001 From: Scot Wells Date: Fri, 6 Mar 2026 15:59:07 -0600 Subject: [PATCH 14/18] Fix CI lint errors and test path issues - Exclude lab/ directory from golangci-lint with ^lab/ pattern - Add constants for repeated test strings in util_test.go - Update relative paths in controller suite_test.go for monorepo structure - Update relative paths in webhook suite_test.go for monorepo structure Co-Authored-By: Claude Opus 4.5 --- .golangci.yml | 2 +- internal/operator/controller/suite_test.go | 4 ++-- .../operator/webhook/v1/webhook_suite_test.go | 6 +++--- pkg/common/util/util_test.go | 17 +++++++++++------ 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index e48464a..21045c1 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -40,7 +40,7 @@ linters: - third_party$ - builtin$ - examples$ - - lab$ + - ^lab/ formatters: enable: - gofmt diff --git a/internal/operator/controller/suite_test.go b/internal/operator/controller/suite_test.go index ccf961d..4a72563 100644 --- a/internal/operator/controller/suite_test.go +++ b/internal/operator/controller/suite_test.go @@ -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/internal/operator/webhook/v1/webhook_suite_test.go b/internal/operator/webhook/v1/webhook_suite_test.go index c1b2e5c..c853384 100644 --- a/internal/operator/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/pkg/common/util/util_test.go b/pkg/common/util/util_test.go index c2f76c1..39b2e3f 100644 --- a/pkg/common/util/util_test.go +++ b/pkg/common/util/util_test.go @@ -8,9 +8,14 @@ import ( "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 { From c1574700dcfc6b17bee08a86c3457de9b430b5b1 Mon Sep 17 00:00:00 2001 From: Scot Schuchert-Wells Date: Fri, 6 Mar 2026 23:51:09 +0000 Subject: [PATCH 15/18] Add Claude Code CLI and host git config to devcontainer Install Claude Code via npm in post-create script and mount the host's .gitconfig into the container so git identity is inherited automatically. Co-Authored-By: Claude Opus 4.6 --- .devcontainer/devcontainer.json | 6 +++++- .devcontainer/post-create.sh | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 5266ea6..6c27c2b 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -29,6 +29,9 @@ }, "ghcr.io/devcontainers/features/git:1": { "version": "latest" + }, + "ghcr.io/devcontainers/features/node:1": { + "version": "lts" } }, "customizations": { @@ -125,7 +128,8 @@ "CGO_ENABLED": "1" }, "mounts": [ - "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind" + "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": [ diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh index 98306f3..93871a6 100755 --- a/.devcontainer/post-create.sh +++ b/.devcontainer/post-create.sh @@ -64,6 +64,10 @@ make manifests generate echo "Configuring git safe directory..." git config --global --add safe.directory /workspaces/galactic +# Install Claude Code CLI +echo "Installing Claude Code..." +npm install -g @anthropic-ai/claude-code + # Verify installations echo "" echo "Verifying installations..." From 434dc8ce9641675031290c8c564765853264ed90 Mon Sep 17 00:00:00 2001 From: Scot Wells Date: Sat, 7 Mar 2026 00:02:05 +0000 Subject: [PATCH 16/18] Add Claude Code settings and improve devcontainer setup - Add shared Claude Code settings with plugins config - Exclude local Claude settings from version control - Switch Claude Code install to native installer (curl) - Mount host SSH keys into devcontainer Co-Authored-By: Claude Opus 4.6 --- .claude/settings.json | 14 ++++++++++++++ .devcontainer/devcontainer.json | 3 ++- .devcontainer/post-create.sh | 2 +- .gitignore | 3 +++ 4 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 .claude/settings.json diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..97f9f1b --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,14 @@ +{ + "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/devcontainer.json b/.devcontainer/devcontainer.json index 6c27c2b..49a00ce 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -129,7 +129,8 @@ }, "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" + "source=${localEnv:HOME}${localEnv:USERPROFILE}/.gitconfig,target=/home/vscode/.gitconfig,type=bind,consistency=cached", + "source=${localEnv:HOME}${localEnv:USERPROFILE}/.ssh,target=/home/vscode/.ssh,type=bind,readonly" ], "postCreateCommand": "bash .devcontainer/post-create.sh", "runArgs": [ diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh index 93871a6..d541058 100755 --- a/.devcontainer/post-create.sh +++ b/.devcontainer/post-create.sh @@ -66,7 +66,7 @@ git config --global --add safe.directory /workspaces/galactic # Install Claude Code CLI echo "Installing Claude Code..." -npm install -g @anthropic-ai/claude-code +curl -fsSL https://claude.ai/install.sh | bash # Verify installations echo "" diff --git a/.gitignore b/.gitignore index b7476df..bb71bf7 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,9 @@ go.work *.swo *~ +# Claude Code +.claude/settings.local.json + # OS .DS_Store From 270acd52b667c1c1b6010ac4f77baea0181286c0 Mon Sep 17 00:00:00 2001 From: Scot Wells Date: Sat, 7 Mar 2026 00:09:17 +0000 Subject: [PATCH 17/18] Add shared permissions and use SSH agent forwarding - Move common allow permissions (git, go, web) to project settings - Remove .ssh mount in favor of automatic SSH agent forwarding Co-Authored-By: Claude Opus 4.6 --- .claude/settings.json | 17 +++++++++++++++++ .devcontainer/devcontainer.json | 3 +-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/.claude/settings.json b/.claude/settings.json index 97f9f1b..44a2983 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -1,4 +1,21 @@ { + "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": { diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 49a00ce..6c27c2b 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -129,8 +129,7 @@ }, "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", - "source=${localEnv:HOME}${localEnv:USERPROFILE}/.ssh,target=/home/vscode/.ssh,type=bind,readonly" + "source=${localEnv:HOME}${localEnv:USERPROFILE}/.gitconfig,target=/home/vscode/.gitconfig,type=bind,consistency=cached" ], "postCreateCommand": "bash .devcontainer/post-create.sh", "runArgs": [ From bab265e95dba0efe966e115b491594887a69c102 Mon Sep 17 00:00:00 2001 From: Scot Wells Date: Sat, 7 Mar 2026 00:09:44 +0000 Subject: [PATCH 18/18] Remove local Claude settings from version control The file is now covered by .gitignore. Co-Authored-By: Claude Opus 4.6 --- .claude/settings.local.json | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 .claude/settings.local.json diff --git a/.claude/settings.local.json b/.claude/settings.local.json deleted file mode 100644 index ac6841f..0000000 --- a/.claude/settings.local.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "permissions": { - "allow": [ - "Bash(git commit:*)", - "Bash(git mv:*)", - "Bash(tree:*)", - "Bash(find:*)", - "Bash(grep:*)", - "Bash(if grep -r \"github\\\\.com/datum-cloud/galactic\" --include=\"*.go\" --include=\"*.proto\" /Users/scotwells/repos/datum-cloud/galactic)", - "Bash(then echo \"WARNING: Found old import paths above\")", - "Bash(else echo \"✓ No old import paths found\")", - "Bash(fi)", - "Bash(go build:*)", - "Bash(go mod tidy:*)", - "Bash(go list:*)", - "Bash(go vet:*)", - "Bash(go tool compile:*)", - "Bash(gofmt:*)", - "Bash(git checkout:*)", - "Bash(git add:*)" - ] - } -}