From e993995ec7bfd603821104c908ba796b05d8b1f4 Mon Sep 17 00:00:00 2001 From: Magyari Sandor Szilard Date: Tue, 28 Oct 2025 12:35:16 +0100 Subject: [PATCH 1/3] feat: refactor topology test to deploy slim clusters and run latest examples Signed-off-by: Magyari Sandor Szilard --- .github/actions/deploy-components/action.yaml | 12 +- .github/workflows/test-integrations.yaml | 125 +----------------- integrations/agntcy-slim/Taskfile.yml | 35 ++--- .../components/config/spire/helper.conf | 4 +- .../agntcy-slim/config/controller-values.yaml | 45 +++++++ .../agntcy-slim/config/fire-and-forget.yaml | 30 ----- .../agntcy-slim/config/peer-to-peer.yaml | 22 +++ .../agntcy-slim/config/server-config.tpl | 17 ++- .../agntcy-slim/config/server-conn-config.tpl | 31 ----- .../tests/config/main/generate_configs.go | 41 +++--- .../tests/config/topology_parser.go | 54 ++------ .../agntcy-slim/tests/mcp_proxy_test.go | 13 +- integrations/agntcy-slim/tests/sanity_test.go | 9 +- .../agntcy-slim/tests/topology_test.go | 67 ++++------ integrations/testutils/k8shelper/k8shelper.go | 50 +++++-- integrations/testutils/k8shelper/pod.go | 8 ++ .../testutils/k8shelper/spire_helper.go | 117 +++++++++++++++- 17 files changed, 343 insertions(+), 337 deletions(-) create mode 100644 integrations/agntcy-slim/config/controller-values.yaml delete mode 100644 integrations/agntcy-slim/config/fire-and-forget.yaml create mode 100644 integrations/agntcy-slim/config/peer-to-peer.yaml delete mode 100644 integrations/agntcy-slim/config/server-conn-config.tpl diff --git a/.github/actions/deploy-components/action.yaml b/.github/actions/deploy-components/action.yaml index 30fd7341..cc549a9d 100644 --- a/.github/actions/deploy-components/action.yaml +++ b/.github/actions/deploy-components/action.yaml @@ -116,6 +116,12 @@ runs: task -d ./${{ inputs.checkout-path }} integrations:kind:create \ KIND_CLUSTER_NAME=${{ inputs.kind-cluster-name }} + - name: Deploy SPIRE + if: ${{ inputs.deploy-spire != 'false' }} + shell: bash + run: | + task -d ./${{ inputs.checkout-path }} integrations:slim:spire:deploy + - name: Deploy SLIM topology if: ${{ inputs.deploy-slim-topology != 'false' }} shell: bash @@ -132,12 +138,6 @@ runs: KIND_CLUSTER_NAME=${{ inputs.kind-cluster-name }} \ HELM_NAMESPACE=${{ inputs.kind-cluster-namespace }} - - name: Deploy SPIRE - if: ${{ inputs.deploy-spire != 'false' }} - shell: bash - run: | - task -d ./${{ inputs.checkout-path }} integrations:slim:spire:deploy - - name: Deploy Slim if: ${{ inputs.deploy-slim != 'false' }} shell: bash diff --git a/.github/workflows/test-integrations.yaml b/.github/workflows/test-integrations.yaml index cc748971..5b53d579 100644 --- a/.github/workflows/test-integrations.yaml +++ b/.github/workflows/test-integrations.yaml @@ -77,69 +77,6 @@ jobs: echo "Set KinD version to: $KIND_VERSION" echo "kind-version=$KIND_VERSION" >> "$GITHUB_OUTPUT" - run-tests-slim: - if: ${{ !inputs.skip_slim_test }} - needs: [set-kind-version] - runs-on: ubuntu-latest - - permissions: - contents: "read" - id-token: "write" - packages: "read" - attestations: "read" - - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Setup Environment - uses: ./.github/actions/setup-env - with: - python: true - go: false - - - name: Setup K8S Tools - uses: ./.github/actions/setup-k8s - with: - kind-version: ${{ needs.set-kind-version.outputs.kind-version }} - - - name: Deploy Slim - uses: ./.github/actions/deploy-components - with: - deploy-spire: "true" - deploy-slim: "true" - slim-image-tag: ${{ inputs.override_slim_image_tag }} - slim-chart-tag: ${{ inputs.override_slim_chart_tag }} - - - name: Run slim sanity tests - env: - AZURE_OPENAI_ENDPOINT: ${{ vars.AZURE_OPENAI_ENDPOINT }} - AZURE_MODEL_VERSION: ${{ vars.AZURE_MODEL_VERSION }} - AZURE_DEPLOYMENT_NAME: ${{ vars.AZURE_DEPLOYMENT_NAME }} - AZURE_OPENAI_API_VERSION: ${{ vars.AZURE_OPENAI_API_VERSION }} - AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }} - run: task integrations:slim:test:sanity - shell: bash - - # - name: Run slim MCP integration tests - # env: - # AZURE_OPENAI_ENDPOINT: ${{ vars.AZURE_OPENAI_ENDPOINT }} - # AZURE_MODEL_VERSION: ${{ vars.AZURE_MODEL_VERSION }} - # AZURE_DEPLOYMENT_NAME: ${{ vars.AZURE_DEPLOYMENT_NAME }} - # AZURE_OPENAI_API_VERSION: ${{ vars.AZURE_OPENAI_API_VERSION }} - # AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }} - # run: task integrations:slim:test:mcp-server - # shell: bash - run-tests-slim-topology: if: ${{ !inputs.skip_slim_test }} needs: [set-kind-version] @@ -179,7 +116,7 @@ jobs: uses: ./.github/actions/deploy-components with: deploy-slim: "false" - deploy-spire: "false" + deploy-spire: "true" deploy-slim-topology: "true" slim-config: "spire" slim-image-tag: ${{ inputs.override_slim_image_tag }} @@ -194,66 +131,6 @@ jobs: with: artifact-name: "slim-test-result" - run-tests-slim-spire: - if: ${{ !inputs.skip_slim_spire_test }} - needs: [set-kind-version] - runs-on: ubuntu-latest - - permissions: - contents: "read" - id-token: "write" - packages: "read" - attestations: "read" - - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Setup Environment - uses: ./.github/actions/setup-env - with: - python: true - go: false - - - name: Setup K8S Tools - uses: ./.github/actions/setup-k8s - with: - kind-version: ${{ needs.set-kind-version.outputs.kind-version }} - - - name: Deploy Slim with SPIRE - uses: ./.github/actions/deploy-components - with: - deploy-slim: "true" - deploy-spire: "true" - slim-config: "spire" - slim-image-tag: ${{ inputs.override_slim_image_tag }} - slim-chart-tag: ${{ inputs.override_slim_chart_tag }} - - - name: Run slim sanity tests (mtls with SPIRE) - env: - AZURE_OPENAI_ENDPOINT: ${{ vars.AZURE_OPENAI_ENDPOINT }} - AZURE_MODEL_VERSION: ${{ vars.AZURE_MODEL_VERSION }} - AZURE_DEPLOYMENT_NAME: ${{ vars.AZURE_DEPLOYMENT_NAME }} - AZURE_OPENAI_API_VERSION: ${{ vars.AZURE_OPENAI_API_VERSION }} - AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }} - SLIM_CONFIG: "spire" - run: task integrations:slim:test:sanity - shell: bash - - - name: Create artifact from integrations test reports - uses: ./.github/actions/create-artifact - with: - artifact-name: "slim-spire-test-result" - run-tests-directory: if: ${{ !inputs.skip_directory_test }} needs: [set-kind-version] diff --git a/integrations/agntcy-slim/Taskfile.yml b/integrations/agntcy-slim/Taskfile.yml index a16d204b..887537f1 100644 --- a/integrations/agntcy-slim/Taskfile.yml +++ b/integrations/agntcy-slim/Taskfile.yml @@ -10,15 +10,17 @@ vars: KIND_CLUSTER_NAME: '{{ .KIND_CLUSTER_NAME | default "agntcy-test" }}' ## Image config - IMAGE_REPO: '{{ .IMAGE_REPO | default "ghcr.io/agntcy" }}' - SLIM_IMAGE_TAG: '{{ .SLIM_IMAGE_TAG | default "0.4.0" }}' + IMAGE_REPO: '{{ .IMAGE_REPO | default "ghcr.io/agntcy" }}' MCP_PROXY_IMAGE_TAG: '{{ .MCP_PROXY_IMAGE_TAG | default "0.1.5" }}' - SLIM_CHART_TAG: '{{ .SLIM_CHART_TAG | default "v0.1.9" }}' SLIM_CONFIG: '{{ .SLIM_CONFIG | default "base" }}' - SLIM_CONTROLLER_CHART_TAG: '{{ .SLIM_CONTROLLER_CHART_TAG | default "0.1.2" }}' - SLIM_CONTROLLER_IMAGE_TAG: '{{ .SLIM_CONTROLLER_IMAGE_TAG | default "0.1.0" }}' - SLIM_CONTROLLER_ENDPOINT: '{{ .SLIM_CONTROLLER_ENDPOINT | default "http://slim-control:50052" }}' + SLIM_CHART_TAG: '{{ .SLIM_CHART_TAG | default "v0.6.0" }}' + SLIM_IMAGE_TAG: '{{ .SLIM_IMAGE_TAG | default "0.6.0" }}' + + SLIM_CONTROLLER_CHART_TAG: '{{ .SLIM_CONTROLLER_CHART_TAG | default "v0.6.0" }}' + SLIM_CONTROLLER_IMAGE_TAG: '{{ .SLIM_CONTROLLER_IMAGE_TAG | default "0.6.0" }}' + + SLIM_CONTROLLER_ENDPOINT: '{{ .SLIM_CONTROLLER_ENDPOINT | default "https://slim-control.admin.svc.cluster.local:50052" }}' SLIM_CONTROLLER_LOCAL_ENDPOINT: '{{ .SLIM_CONTROLLER_LOCAL_ENDPOINT | default "localhost:50051" }}' SLIMCTL_VERSION: '{{ .SLIMCTL_VERSION | default "v0.2.1" }}' SLIMCTL_PATH: '{{ .SLIMCTL_PATH | default "./bin/slimctl" }}' @@ -39,9 +41,9 @@ vars: RUNNER_TYPE: '{{ .RUNNER_TYPE | default "docker" }}' - SPIRE_NAMESPACE: '{{ .SPIRE_NAMESPACE | default "spire-server" }}' + SPIRE_NAMESPACE: '{{ .SPIRE_NAMESPACE | default "spire" }}' - TOPOLOGY_CONFIG: '{{ .TOPOLOGY_CONFIG | default "config/fire-and-forget.yaml" }}' + TOPOLOGY_CONFIG: '{{ .TOPOLOGY_CONFIG | default "config/peer-to-peer.yaml" }}' tasks: k8s:port-forward:setup: @@ -94,18 +96,19 @@ tasks: oci://{{ .IMAGE_REPO }}/slim/helm/slim-control-plane \ --version {{ .SLIM_CONTROLLER_CHART_TAG }} \ --set image.tag="{{ .SLIM_CONTROLLER_IMAGE_TAG }}" \ - --namespace {{ .HELM_NAMESPACE }} \ + -f ./config/controller-values.yaml \ + --namespace "admin" \ --create-namespace \ --install \ --wait \ --wait-for-jobs \ --timeout "15m" - test-env:cleanup:contoroller: + test-env:cleanup:controller: desc: Remove agent slim test env cmds: - task k8s:port-forward:controller:teardown - - helm delete --namespace {{ .HELM_NAMESPACE }} slim-controller + - helm delete --namespace "admin" slim-controller test-env:deploy:generated: desc: Deploy agntcy slim test env for each values file in config/.generated @@ -119,7 +122,7 @@ tasks: --version {{ .SLIM_CHART_TAG }} \ --set slim.image.tag="{{ .SLIM_IMAGE_TAG }}" \ -f "$file" \ - --namespace {{ .HELM_NAMESPACE }} \ + --namespace $(basename "$file" .yaml) \ --create-namespace \ --install \ --wait \ @@ -133,7 +136,7 @@ tasks: cmd: | #!/bin/sh for file in "./config/.gen"/*.yaml ;do - helm delete --namespace {{ .HELM_NAMESPACE }} agntcy-$(basename "$file" .yaml) + helm delete --namespace $(basename "$file" .yaml) agntcy-$(basename "$file" .yaml) echo "Deleted agntcy-slim-$(basename "$file" .yaml) with config $(basename "$file")" done @@ -230,10 +233,10 @@ tasks: test:topology: desc: Slim topology test - deps: - - test:slimctl-download + # deps: + # - test:slimctl-download cmds: - - task k8s:port-forward:controller:setup + # - task k8s:port-forward:controller:setup - NAMESPACE={{.HELM_NAMESPACE}} SLIMCTL_PATH=../{{.SLIMCTL_PATH}} TOPOLOGY_CONFIG=../{{.TOPOLOGY_CONFIG}} SLIM_CONTROLLER_LOCAL_ENDPOINT={{.SLIM_CONTROLLER_LOCAL_ENDPOINT}} go test ./tests -v -failfast -test.v -test.paniconexit0 -ginkgo.timeout 30m -timeout 30m -ginkgo.v -ginkgo.focus "Slim topology test" --ginkgo.json-report=../reports/report-slim-topology.json --ginkgo.junit-report=../reports/report-slim-topology.xml test:mcp-server: diff --git a/integrations/agntcy-slim/components/config/spire/helper.conf b/integrations/agntcy-slim/components/config/spire/helper.conf index ba8b34db..cf678e5f 100644 --- a/integrations/agntcy-slim/components/config/spire/helper.conf +++ b/integrations/agntcy-slim/components/config/spire/helper.conf @@ -6,10 +6,10 @@ renew_signal = "" svid_file_name = "tls.crt" svid_key_file_name = "tls.key" svid_bundle_file_name = "svid_bundle.pem" -jwt_bundle_file_name = "cert.jwt" +jwt_bundle_file_name = "key.jwt" cert_file_mode = 0644 key_file_mode = 0644 jwt_svid_file_mode = 0644 jwt_bundle_file_mode = 0644 -jwt_svids = [{jwt_audience="test", jwt_svid_file_name="jwt_svid.token"}] +jwt_svids = [{jwt_audience="slim-demo", jwt_svid_file_name="jwt_svid.token"}] daemon_mode = false \ No newline at end of file diff --git a/integrations/agntcy-slim/config/controller-values.yaml b/integrations/agntcy-slim/config/controller-values.yaml new file mode 100644 index 00000000..78f30fe5 --- /dev/null +++ b/integrations/agntcy-slim/config/controller-values.yaml @@ -0,0 +1,45 @@ +# Copyright AGNTCY Contributors (https://github.com/agntcy) +# SPDX-License-Identifier: Apache-2.0 + +# Default values for slim-control-plane. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/ +replicaCount: 1 + +# This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/ +image: + repository: "ghcr.io/agntcy/slim/control-plane" + # This sets the pull policy for images. + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +fullnameOverride: "slim-control" + +config: + northbound: + httpHost: 0.0.0.0 + httpPort: "{{ .Values.service.north.port }}" + + southbound: + httpHost: 0.0.0.0 + httpPort: "{{ .Values.service.south.port }}" + tls: + useSpiffe: true + spire: + socketPath: "unix:///run/spire/agent-sockets/api.sock" + + logging: + level: DEBUG + +spire: + enabled: true + +service: + type: ClusterIP + south: + port: 50052 + north: + port: 50051 diff --git a/integrations/agntcy-slim/config/fire-and-forget.yaml b/integrations/agntcy-slim/config/fire-and-forget.yaml deleted file mode 100644 index d6bc9682..00000000 --- a/integrations/agntcy-slim/config/fire-and-forget.yaml +++ /dev/null @@ -1,30 +0,0 @@ -topology: - clients: - "alice": - # auth: - # spireJwt: true - connectedTo: - - "slim-1" - image: ghcr.io/agntcy/slim/bindings-examples:latest - args: ["ff", "--local", "org/ns/alice", "--shared-secret","secret123"] - assertFor: "replies: hello from" - "bob": - # auth: - # spireJwt: true - connectedTo: - - "slim-2" - image: ghcr.io/agntcy/slim/bindings-examples:latest - args: ["ff", "--message", "hello", "--iterations", "10", "--local", "org/ns/bob", "--remote", "org/ns/alice", "--shared-secret","secret123"] - assertFor: "Sent message hello - 10/10" - servers: - "slim-0": - spireMtls: false - routes: - - "org/ns/bob > slim-2" - - "org/ns/alice > slim-1" - "slim-1": - routes: - - "org/ns/bob > slim-0" - "slim-2": - routes: - - "org/ns/alice > slim-0" diff --git a/integrations/agntcy-slim/config/peer-to-peer.yaml b/integrations/agntcy-slim/config/peer-to-peer.yaml new file mode 100644 index 00000000..cd029ce6 --- /dev/null +++ b/integrations/agntcy-slim/config/peer-to-peer.yaml @@ -0,0 +1,22 @@ +topology: + clients: + "alice": + spireMtls: true + connectedTo: + - "cluster-b" + image: ghcr.io/agntcy/slim/bindings-examples:0.6.0 + args: ["p2p", "--local", "org/ns/alice", "--shared-secret","secret123"] + assertFor: "received: hello" + "bob": + spireMtls: true + connectedTo: + - "cluster-a" + image: ghcr.io/agntcy/slim/bindings-examples:0.6.0 + args: ["p2p", "--local", "org/ns/bob", "--remote", "org/ns/alice", "--shared-secret","secret123","--message","hello","--iterations","10"] + assertFor: "Sent message hello - 10/10" + clusters: + "cluster-a": + spireMtls: true + #daemonSet: false + "cluster-b": + spireMtls: true \ No newline at end of file diff --git a/integrations/agntcy-slim/config/server-config.tpl b/integrations/agntcy-slim/config/server-config.tpl index 86410e27..e350efc3 100644 --- a/integrations/agntcy-slim/config/server-config.tpl +++ b/integrations/agntcy-slim/config/server-config.tpl @@ -20,10 +20,15 @@ slim: drain_timeout: 10s services: - slim/{{.ServiceName }}: - pubsub: + slim/0: + node_id: ${env:SLIM_SVC_ID} + group_name: "{{ .ClusterName }}" + dataplane: servers: - endpoint: "0.0.0.0:{{ .SlimPort }}" + metadata: + local_endpoint: ${env:MY_POD_IP} + external_endpoint: "{{ .ServiceName }}:{{ .SlimPort }}" tls: {{- if .Spire.Enabled }} cert_file: "/svids/tls.crt" @@ -31,9 +36,15 @@ slim: ca_file: "/svids/svid_bundle.pem" {{- else }} insecure: true - {{- end }} + {{- end }} controller: clients: - endpoint: "{{ .SlimControllerEndpoint }}" tls: + {{- if .Spire.Enabled }} + cert_file: "/svids/tls.crt" + key_file: "/svids/tls.key" + ca_file: "/svids/svid_bundle.pem" + {{- else }} insecure: true + {{- end }} diff --git a/integrations/agntcy-slim/config/server-conn-config.tpl b/integrations/agntcy-slim/config/server-conn-config.tpl deleted file mode 100644 index b4da8865..00000000 --- a/integrations/agntcy-slim/config/server-conn-config.tpl +++ /dev/null @@ -1,31 +0,0 @@ -{ - "endpoint": "http://{{ .SlimHost }}:{{ .SlimPort }}", - "auth": { - "basic": { - "username": "testuser", - "password": "secret123" - } - }, - "buffer_size": 1024, - "compression": "Gzip", - "connect_timeout": "10s", - "headers": { - "x-custom-header": "value" - }, - "keepalive": { - "http2_keepalive": "2h", - "keep_alive_while_idle": false, - "tcp_keepalive": "20s", - "timeout": "20s" - }, - "origin": "https://client.example.com", - "rate_limit": "20/60", - {{- if .Spire.Enabled }} - "tls": { - "cert_file": "/svids/tls.crt", - "key_file": "/svids/tls.key", - "ca_file": "/svids/svid_bundle.pem" - }, - {{- end }} - "request_timeout": "30s" -} \ No newline at end of file diff --git a/integrations/agntcy-slim/tests/config/main/generate_configs.go b/integrations/agntcy-slim/tests/config/main/generate_configs.go index 0fe09792..c393c97a 100644 --- a/integrations/agntcy-slim/tests/config/main/generate_configs.go +++ b/integrations/agntcy-slim/tests/config/main/generate_configs.go @@ -11,9 +11,8 @@ import ( ) const ( - SlimMessagingPort = "46357" - ServerConfigTemplatePath = "config/server-config.tpl" - ServerConnConfigTemplatePath = "config/server-conn-config.tpl" + SlimMessagingPort = "46357" + ServerConfigTemplatePath = "config/server-config.tpl" ) // SpireConfig represents the spire configuration section @@ -24,9 +23,9 @@ type SpireConfig struct { // ServerConfigData represents the data structure for the server-config.tpl template type ServerConfigData struct { Spire SpireConfig `yaml:"spire"` - SlimHost string `yaml:"slimHost"` SlimPort string `yaml:"slimPort"` SlimControllerEndpoint string `yaml:"slimControllerEndpoint"` + ClusterName string `yaml:"clusterName"` ServiceName string `yaml:"serviceName"` } @@ -53,37 +52,31 @@ func GenerateConfigFromTemplate(templatePath, outputPath string, data ServerConf return nil } -// GenerateServerConfigs generates server configs for each server in the topology -func GenerateServerConfigs(topology *config.Config, slimControllerEndpoint string, outputDir string) error { - // Generate a config file for each server - for serverName, serverConfig := range topology.Topology.Servers { +// GenerateClusterConfigs generates cluster configs for each cluster in the topology +func GenerateClusterConfigs(topology *config.Config, slimControllerEndpoint string, outputDir string) error { + // Generate a config file for each cluster + for clusterName, clusterConfig := range topology.Topology.Clusters { // Determine spire settings based on auth configuration - spireEnabled := serverConfig.SpireMtls || serverConfig.Auth.SpireJwt + spireEnabled := clusterConfig.SpireMtls || clusterConfig.Auth.SpireJwt // Create template data data := ServerConfigData{ Spire: SpireConfig{ Enabled: spireEnabled, }, - SlimHost: fmt.Sprintf("agntcy-%s", serverName), SlimPort: SlimMessagingPort, SlimControllerEndpoint: slimControllerEndpoint, - ServiceName: serverName, + ClusterName: clusterName, + ServiceName: fmt.Sprintf("agntcy-%s-slim.%s.svc.cluster.local", clusterName, clusterName), } // Generate server config file - outputPath := filepath.Join(outputDir, fmt.Sprintf("%s.yaml", serverName)) + outputPath := filepath.Join(outputDir, fmt.Sprintf("%s.yaml", clusterName)) if err := GenerateConfigFromTemplate(ServerConfigTemplatePath, outputPath, data); err != nil { - return fmt.Errorf("failed to generate config for server %s: %w", serverName, err) + return fmt.Errorf("failed to generate config for server %s: %w", clusterName, err) } - // Generate connection config file - outputPath = filepath.Join(outputDir, fmt.Sprintf("%s-conn-config.json", serverName)) - if err := GenerateConfigFromTemplate(ServerConnConfigTemplatePath, outputPath, data); err != nil { - return fmt.Errorf("failed to generate config for server %s: %w", serverName, err) - } - - fmt.Printf("Generated config for server '%s' at: %s\n", serverName, outputPath) + fmt.Printf("Generated config for cluster '%s' at: %s\n", clusterName, outputPath) } return nil @@ -105,7 +98,7 @@ func main() { } fmt.Println("Configuration loaded successfully!") - fmt.Printf("Found %d servers in topology\n", len(topology.Topology.Servers)) + fmt.Printf("Found %d clusters in topology\n", len(topology.Topology.Clusters)) outputPath := "config/.gen" // Create the output directory if it doesn't exist @@ -113,10 +106,10 @@ func main() { log.Fatalf("Failed to create output directory: %v", err) } - // Generate server configs from topology - err = GenerateServerConfigs(topology, slimControllerEndpoint, outputPath) + // Generate cluster configs from topology + err = GenerateClusterConfigs(topology, slimControllerEndpoint, outputPath) if err != nil { - log.Fatalf("Failed to generate server configs: %v", err) + log.Fatalf("Failed to generate cluster configs: %v", err) } fmt.Println("All configurations generated successfully!") diff --git a/integrations/agntcy-slim/tests/config/topology_parser.go b/integrations/agntcy-slim/tests/config/topology_parser.go index 535bcd6d..7c8a1129 100644 --- a/integrations/agntcy-slim/tests/config/topology_parser.go +++ b/integrations/agntcy-slim/tests/config/topology_parser.go @@ -3,7 +3,6 @@ package config import ( "fmt" "io/ioutil" - "strings" "gopkg.in/yaml.v3" ) @@ -26,15 +25,14 @@ type Client struct { // Server represents a server configuration in the topology type Server struct { - Auth Auth `yaml:"auth"` - SpireMtls bool `yaml:"spireMtls,omitempty"` - Routes []string `yaml:"routes"` + Auth Auth `yaml:"auth"` + SpireMtls bool `yaml:"spireMtls,omitempty"` } // Topology represents the topology configuration type Topology struct { - Clients map[string]Client `yaml:"clients"` - Servers map[string]Server `yaml:"servers"` + Clients map[string]Client `yaml:"clients"` + Clusters map[string]Server `yaml:"clusters"` } // Config represents the root configuration structure @@ -78,10 +76,10 @@ func (c *Config) GetClient(name string) (Client, bool) { return client, exists } -// GetServer returns a server by name -func (c *Config) GetServer(name string) (Server, bool) { - server, exists := c.Topology.Servers[name] - return server, exists +// GetCluster returns a cluster by name +func (c *Config) GetCluster(name string) (Server, bool) { + cluster, exists := c.Topology.Clusters[name] + return cluster, exists } // ListClients returns a slice of all client names @@ -93,35 +91,11 @@ func (c *Config) ListClients() []string { return clients } -// ListServers returns a slice of all server names -func (c *Config) ListServers() []string { - servers := make([]string, 0, len(c.Topology.Servers)) - for name := range c.Topology.Servers { - servers = append(servers, name) +// ListClusters returns a slice of all cluster names +func (c *Config) ListClusters() []string { + clusters := make([]string, 0, len(c.Topology.Clusters)) + for name := range c.Topology.Clusters { + clusters = append(clusters, name) } - return servers -} - -func ParseRoute(route string) (string, string) { - // Assuming route is in the format "channelName > destinationServerName" - parts := strings.Split(route, ">") - if len(parts) != 2 { - return "", "" - } - return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]) -} - -func (c *Config) ValidateRoutes() error { - for serverName, server := range c.Topology.Servers { - for _, route := range server.Routes { - channelName, destServerName := ParseRoute(route) - if channelName == "" || destServerName == "" { - return fmt.Errorf("invalid route '%s' in server '%s'", route, serverName) - } - if _, exists := c.Topology.Servers[destServerName]; !exists { - return fmt.Errorf("destination server '%s' does not exist for route '%s'", destServerName, route) - } - } - } - return nil + return clusters } diff --git a/integrations/agntcy-slim/tests/mcp_proxy_test.go b/integrations/agntcy-slim/tests/mcp_proxy_test.go index 50590554..a2daeb6d 100644 --- a/integrations/agntcy-slim/tests/mcp_proxy_test.go +++ b/integrations/agntcy-slim/tests/mcp_proxy_test.go @@ -12,6 +12,7 @@ import ( ginkgo "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" "github.com/agntcy/csit/integrations/testutils/k8shelper" @@ -24,6 +25,7 @@ var _ = ginkgo.Describe("MCP over Slim test", func() { azure_openapi_api_key string azure_openapi_endpoint string clientset kubernetes.Interface + dynamicClient dynamic.Interface namespace string ) @@ -41,6 +43,9 @@ var _ = ginkgo.Describe("MCP over Slim test", func() { clientset, err = k8shelper.CreateK8sClientSet() gomega.Expect(err).NotTo(gomega.HaveOccurred(), "unable to create a client") + dynamicClient, err = k8shelper.CreateDynamicK8sClient() + gomega.Expect(err).NotTo(gomega.HaveOccurred(), "unable to create a dynamic client") + namespace = os.Getenv("NAMESPACE") }) @@ -49,7 +54,7 @@ var _ = ginkgo.Describe("MCP over Slim test", func() { // The client can address the MCP server as if it was a normal agent. ginkgo.BeforeAll(func() { podName := "mcp-server" - k8sHelper := k8shelper.NewK8sHelper(podName, namespace, mcpServerTimeImage, clientset) + k8sHelper := k8shelper.NewK8sHelper(podName, namespace, mcpServerTimeImage, clientset, dynamicClient) createdPod, err := k8sHelper.WithArgs([]string{ "--local-timezone", @@ -73,7 +78,7 @@ var _ = ginkgo.Describe("MCP over Slim test", func() { ginkgo.It("Create Llamaindex time agent Job", func() { jobName := "llamaindex-time-agent" - k8sHelper := k8shelper.NewK8sHelper(jobName, namespace, llamaindexTimeAgentImage, clientset) + k8sHelper := k8shelper.NewK8sHelper(jobName, namespace, llamaindexTimeAgentImage, clientset, dynamicClient) createdJob, err := k8sHelper.WithEnvVars(map[string]string{ "AZURE_OPENAI_ENDPOINT": azure_openapi_endpoint, @@ -103,7 +108,7 @@ var _ = ginkgo.Describe("MCP over Slim test", func() { // The MCP server works on top of SSE and we can access it using the MCP proxy ginkgo.BeforeAll(func() { podName := "mcp-server-proxy" - k8sHelper := k8shelper.NewK8sHelper(podName, namespace, mcpServerTimeImage, clientset) + k8sHelper := k8shelper.NewK8sHelper(podName, namespace, mcpServerTimeImage, clientset, dynamicClient) createdPod, err := k8sHelper.WithArgs([]string{ "--local-timezone", @@ -140,7 +145,7 @@ var _ = ginkgo.Describe("MCP over Slim test", func() { ginkgo.It("Create Llamaindex time agent Job", func() { jobName := "llamaindex-time-agent" - k8sHelper := k8shelper.NewK8sHelper(jobName, namespace, llamaindexTimeAgentImage, clientset) + k8sHelper := k8shelper.NewK8sHelper(jobName, namespace, llamaindexTimeAgentImage, clientset, dynamicClient) createdJob, err := k8sHelper.WithEnvVars(map[string]string{ "AZURE_OPENAI_ENDPOINT": azure_openapi_endpoint, diff --git a/integrations/agntcy-slim/tests/sanity_test.go b/integrations/agntcy-slim/tests/sanity_test.go index 4399bdb1..9c49bc63 100644 --- a/integrations/agntcy-slim/tests/sanity_test.go +++ b/integrations/agntcy-slim/tests/sanity_test.go @@ -11,6 +11,7 @@ import ( ginkgo "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" + "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" "github.com/agntcy/csit/integrations/testutils/k8shelper" @@ -25,6 +26,7 @@ var _ = ginkgo.Describe("Agntcy slim sanity test", func() { namespace string slimConfig string clientset kubernetes.Interface + dynamicClient dynamic.Interface ) ginkgo.BeforeEach(func() { @@ -43,13 +45,16 @@ var _ = ginkgo.Describe("Agntcy slim sanity test", func() { clientset, err = k8shelper.CreateK8sClientSet() gomega.Expect(err).NotTo(gomega.HaveOccurred(), "unable to create a client") + dynamicClient, err = k8shelper.CreateDynamicK8sClient() + gomega.Expect(err).NotTo(gomega.HaveOccurred(), "unable to create a dynamic client") + namespace = os.Getenv("NAMESPACE") }) ginkgo.Context("Slim sanity test", ginkgo.Ordered, func() { ginkgo.BeforeAll(func() { podName := "autogen-agent" - k8sHelper := k8shelper.NewK8sHelper(podName, namespace, autogenImage, clientset).WithEnvVars( + k8sHelper := k8shelper.NewK8sHelper(podName, namespace, autogenImage, clientset, dynamicClient).WithEnvVars( map[string]string{ "AZURE_OPENAI_ENDPOINT": azure_openapi_endpoint, "AZURE_OPENAI_API_KEY": azure_openapi_api_key, @@ -127,7 +132,7 @@ var _ = ginkgo.Describe("Agntcy slim sanity test", func() { ginkgo.It("Create langchain agent Job", func() { jobName := "langchain-agent" - k8sHelper := k8shelper.NewK8sHelper(jobName, namespace, langchainImage, clientset).WithEnvVars(map[string]string{ + k8sHelper := k8shelper.NewK8sHelper(jobName, namespace, langchainImage, clientset, dynamicClient).WithEnvVars(map[string]string{ "AZURE_OPENAI_ENDPOINT": azure_openapi_endpoint, "AZURE_OPENAI_API_KEY": azure_openapi_api_key, }) diff --git a/integrations/agntcy-slim/tests/topology_test.go b/integrations/agntcy-slim/tests/topology_test.go index 202f94d1..7595c662 100644 --- a/integrations/agntcy-slim/tests/topology_test.go +++ b/integrations/agntcy-slim/tests/topology_test.go @@ -4,12 +4,10 @@ package tests import ( - "bytes" "context" "encoding/json" "fmt" "log" - "os/exec" "sort" "time" @@ -17,6 +15,7 @@ import ( ginkgo "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" + "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" "github.com/agntcy/csit/integrations/agntcy-slim/tests/config" @@ -45,7 +44,8 @@ var _ = ginkgo.Describe("Agntcy slim topology test", func() { topologyConfig string topology *config.Topology clientset kubernetes.Interface - slimController string + dynamicClient dynamic.Interface + //slimController string ) ginkgo.BeforeEach(func() { @@ -55,18 +55,17 @@ var _ = ginkgo.Describe("Agntcy slim topology test", func() { clientset, err = k8shelper.CreateK8sClientSet() gomega.Expect(err).NotTo(gomega.HaveOccurred(), "unable to create a client") + dynamicClient, err = k8shelper.CreateDynamicK8sClient() + gomega.Expect(err).NotTo(gomega.HaveOccurred(), "unable to create a dynamic client") + namespace = os.Getenv("NAMESPACE") slimctlPath = os.Getenv("SLIMCTL_PATH") topologyConfig = os.Getenv("TOPOLOGY_CONFIG") - slimController = os.Getenv("SLIM_CONTROLLER_LOCAL_ENDPOINT") + //slimController = os.Getenv("SLIM_CONTROLLER_LOCAL_ENDPOINT") // Parse the topology configuration config, err := config.ParseTopology(topologyConfig) gomega.Expect(err).NotTo(gomega.HaveOccurred(), "unable to parse topology configuration") - // expect topology.ValidateRoutes() to not return an error - err = config.ValidateRoutes() - gomega.Expect(err).NotTo(gomega.HaveOccurred(), "failed to validate routes") - gomega.Expect(config).NotTo(gomega.BeNil(), "topology configuration should not be nil") topology = &config.Topology }) @@ -74,33 +73,6 @@ var _ = ginkgo.Describe("Agntcy slim topology test", func() { ginkgo.Context("Slim topology test", ginkgo.Ordered, func() { ginkgo.BeforeAll(func() { log.Print(slimctlPath) - // setup routes using the topology configuration - - // wait for SLIM instances to start - time.Sleep(2000 * time.Millisecond) - - for serverName, server := range topology.Servers { - for _, route := range server.Routes { - channelName, destServerName := config.ParseRoute(route) - log.Printf("Adding route on server %s for channel %s > %s", serverName, channelName, destServerName) - - // add route using slimctl - var out bytes.Buffer - cmd := exec.Command(slimctlPath, - "route", "add", fmt.Sprintf("%s/0", channelName), - "via", fmt.Sprintf("../config/.gen/%s-conn-config.json", destServerName), - "--node-id", fmt.Sprintf("slim/%s", serverName), - "--server", slimController) - cmd.Stdout = &out - cmd.Stderr = &out - - err := cmd.Run() - fmt.Println("Command output:", out.String()) - gomega.Expect(err).To(gomega.Succeed()) - - } - } - }) ginkgo.It("Create SLIM client Pods", func() { @@ -122,7 +94,7 @@ var _ = ginkgo.Describe("Agntcy slim topology test", func() { "PYTHONUNBUFFERED": "1", } args := client.Args - k8sHelper := k8shelper.NewK8sHelper(jobName, namespace, imageName, clientset).WithEnvVars(envVars) + k8sHelper := k8shelper.NewK8sHelper(jobName, namespace, imageName, clientset, dynamicClient).WithEnvVars(envVars) // expect client.ConnectedTo is not empty gomega.Expect(len(client.ConnectedTo)).NotTo(gomega.BeZero(), "client %s must be connected to at least one server", clientName) @@ -130,15 +102,30 @@ var _ = ginkgo.Describe("Agntcy slim topology test", func() { if client.SpireMtls { createdConfigMap, err := k8sHelper.CreateConfigMapFromFile("helper.conf", "../components/config/spire/helper.conf") gomega.Expect(err).NotTo(gomega.HaveOccurred(), createdConfigMap) - // Register cleanup to run after all the spec is done ginkgo.DeferCleanup(func(ctx context.Context) { err := k8sHelper.CleanupConfigMap(ctx) gomega.Expect(err).NotTo(gomega.HaveOccurred(), "failed to delete config map") }) + err = k8sHelper.CreateServiceAccount() + gomega.Expect(err).NotTo(gomega.HaveOccurred(), "failed to create service account") + // Register cleanup to run after all the spec is done + ginkgo.DeferCleanup(func(ctx context.Context) { + err := k8sHelper.CleanupServiceAccount() + gomega.Expect(err).NotTo(gomega.HaveOccurred(), "failed to delete service account") + }) + + err = k8sHelper.CreateClusterSPIFFEID() + gomega.Expect(err).NotTo(gomega.HaveOccurred(), "failed to create spiffee ID") + // Register cleanup to run after all the spec is done + ginkgo.DeferCleanup(func(ctx context.Context) { + err := k8sHelper.CleanupClusterSPIFFEID() + gomega.Expect(err).NotTo(gomega.HaveOccurred(), "failed to delete spiffee ID") + }) + cfg := ClientConfig{ - Endpoint: fmt.Sprintf("https://agntcy-%s:46357", client.ConnectedTo[0]), + Endpoint: fmt.Sprintf("https://agntcy-%s-slim.%s.svc.cluster.local:46357", client.ConnectedTo[0], client.ConnectedTo[0]), TLS: TLSConfig{ InsecureSkipVerify: false, CertFile: "/svids/tls.crt", @@ -149,11 +136,11 @@ var _ = ginkgo.Describe("Agntcy slim topology test", func() { cfgJSON, err := json.Marshal(cfg) gomega.Expect(err).NotTo(gomega.HaveOccurred(), "failed to marshal client config") - args := append(args, "--config", string(cfgJSON)) + args := append(args, "--slim", string(cfgJSON)) k8sHelper = k8sHelper.WithArgs(args).WithSpireHelper() } else { - endpoint := fmt.Sprintf("http://agntcy-%s:46357", client.ConnectedTo[0]) + endpoint := fmt.Sprintf("https://agntcy-%s-slim.%s.svc.cluster.local:46357", client.ConnectedTo[0], client.ConnectedTo[0]) cfg := ClientConfig{ Endpoint: endpoint, TLS: TLSConfig{ diff --git a/integrations/testutils/k8shelper/k8shelper.go b/integrations/testutils/k8shelper/k8shelper.go index 98361f49..f3501c69 100644 --- a/integrations/testutils/k8shelper/k8shelper.go +++ b/integrations/testutils/k8shelper/k8shelper.go @@ -10,6 +10,7 @@ import ( "github.com/onsi/gomega" corev1 "k8s.io/api/core/v1" + "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" ) @@ -21,27 +22,30 @@ type SecretVolume struct { } type k8sHelper struct { - clientset kubernetes.Interface - name string - namespace string - imageName string - envVars map[string]string - command []string - args []string - containerPorts []int32 - secretVolumes []SecretVolume + clientset kubernetes.Interface + dynamicClient dynamic.Interface + name string + namespace string + imageName string + envVars map[string]string + command []string + args []string + containerPorts []int32 + secretVolumes []SecretVolume + serviceAccountName string volumes []corev1.Volume volumeMounts []corev1.VolumeMount initContainer corev1.Container } -func NewK8sHelper(name, namespace, imageName string, c kubernetes.Interface) *k8sHelper { +func NewK8sHelper(name, namespace, imageName string, c kubernetes.Interface, dynamicClient dynamic.Interface) *k8sHelper { return &k8sHelper{ - clientset: c, - name: name, - namespace: namespace, - imageName: imageName, + clientset: c, + dynamicClient: dynamicClient, + name: name, + namespace: namespace, + imageName: imageName, } } @@ -57,6 +61,12 @@ func (k *k8sHelper) WithCommand(command []string) *k8sHelper { return k } +func (k *k8sHelper) WithServiceAccountName(name string) *k8sHelper { + k.serviceAccountName = name + + return k +} + func (k *k8sHelper) WithArgs(args []string) *k8sHelper { k.args = args @@ -103,3 +113,15 @@ func CreateK8sClientSet() (*kubernetes.Clientset, error) { return kubernetes.NewForConfig(config) } + +func CreateDynamicK8sClient() (*dynamic.DynamicClient, error) { + kubeconfig := filepath.Join(os.Getenv("HOME"), ".kube", "config") + config, err := clientcmd.BuildConfigFromFlags("", kubeconfig) + if err != nil { + return nil, fmt.Errorf("unable to load kubeconfig %w", err) + } + gomega.Expect(err).NotTo(gomega.HaveOccurred(), "unable to load kubeconfig") + + // Create dynamic client for custom resources + return dynamic.NewForConfig(config) +} diff --git a/integrations/testutils/k8shelper/pod.go b/integrations/testutils/k8shelper/pod.go index da8a4cbc..e84db0e6 100644 --- a/integrations/testutils/k8shelper/pod.go +++ b/integrations/testutils/k8shelper/pod.go @@ -44,6 +44,10 @@ func (k *k8sHelper) CreatePod() (*corev1.Pod, error) { ObjectMeta: metav1.ObjectMeta{ Name: k.name, Namespace: k.namespace, + Labels: map[string]string{ + "app.kubernetes.io/name": "slim-client", + "app.kubernetes.io/component": k.name, + }, }, Spec: corev1.PodSpec{ Containers: []corev1.Container{ @@ -56,6 +60,10 @@ func (k *k8sHelper) CreatePod() (*corev1.Pod, error) { }, } + if k.serviceAccountName != "" { + pod.Spec.ServiceAccountName = k.serviceAccountName + } + if k.secretVolumes != nil { var volumes []corev1.Volume var volumeMounts []corev1.VolumeMount diff --git a/integrations/testutils/k8shelper/spire_helper.go b/integrations/testutils/k8shelper/spire_helper.go index af3277ea..539d472a 100644 --- a/integrations/testutils/k8shelper/spire_helper.go +++ b/integrations/testutils/k8shelper/spire_helper.go @@ -4,7 +4,13 @@ package k8shelper import ( + "context" + "fmt" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" ) func (k *k8sHelper) WithSpireHelper() *k8sHelper { @@ -66,6 +72,115 @@ func (k *k8sHelper) WithSpireHelper() *k8sHelper { ReadOnly: false, }, }, - }) + }).WithServiceAccountName(k.name) + +} + +func (k *k8sHelper) CreateServiceAccount() error { + serviceAccount := &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: k.name, + Namespace: k.namespace, + Labels: map[string]string{ + "app.kubernetes.io/name": "slim-client", + "app.kubernetes.io/component": k.name, + }, + }, + } + + _, err := k.clientset.CoreV1().ServiceAccounts(k.namespace).Create( + context.TODO(), + serviceAccount, + metav1.CreateOptions{}, + ) + if err != nil { + return fmt.Errorf("failed to create service account %s: %v", k.name, err) + } + + return nil +} + +func (k *k8sHelper) CleanupServiceAccount() error { + err := k.clientset.CoreV1().ServiceAccounts(k.namespace).Delete( + context.TODO(), + k.name, + metav1.DeleteOptions{}, + ) + if err != nil { + return fmt.Errorf("failed to delete service account %s: %v", k.name, err) + } + + return nil +} + +func (k *k8sHelper) CreateClusterSPIFFEID() error { + // Create ClusterSPIFFEID custom resource + clusterSPIFFEID := &unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "spire.spiffe.io/v1alpha1", + "kind": "ClusterSPIFFEID", + "metadata": map[string]interface{}{ + "name": k.name, + "labels": map[string]string{ + "app.kubernetes.io/name": "slim-client", + "app.kubernetes.io/component": k.name, + }, + }, + "spec": map[string]interface{}{ + "className": "spire-spire", + "podSelector": map[string]interface{}{ + "matchExpressions": []interface{}{ + map[string]interface{}{ + "key": "app.kubernetes.io/component", + "operator": "In", + "values": []interface{}{k.name}, + }, + }, + }, + "workloadSelectorTemplates": []interface{}{ + fmt.Sprintf("k8s:sa:%s", k.name), + }, + "spiffeIDTemplate": fmt.Sprintf("spiffe://{{ .TrustDomain }}/ns/%s/sa/%s", k.namespace, k.name), + }, + }, + } + + // Define the GVR for ClusterSPIFFEID + clusterSPIFFEIDGVR := schema.GroupVersionResource{ + Group: "spire.spiffe.io", + Version: "v1alpha1", + Resource: "clusterspiffeids", + } + + _, err := k.dynamicClient.Resource(clusterSPIFFEIDGVR).Create( + context.TODO(), + clusterSPIFFEID, + metav1.CreateOptions{}, + ) + if err != nil { + return fmt.Errorf("failed to create ClusterSPIFFEID %s: %v", k.name, err) + } + + return nil +} + +func (k *k8sHelper) CleanupClusterSPIFFEID() error { + + // Define the GVR for ClusterSPIFFEID + clusterSPIFFEIDGVR := schema.GroupVersionResource{ + Group: "spire.spiffe.io", + Version: "v1alpha1", + Resource: "clusterspiffeids", + } + + err := k.dynamicClient.Resource(clusterSPIFFEIDGVR).Delete( + context.TODO(), + k.name, + metav1.DeleteOptions{}, + ) + if err != nil { + return fmt.Errorf("failed to delete ClusterSPIFFEID %s: %v", k.name, err) + } + return nil } From 236eebcf0f4caa8d7b6a1d360784efe3d0bd0853 Mon Sep 17 00:00:00 2001 From: Magyari Sandor Szilard Date: Tue, 28 Oct 2025 12:54:05 +0100 Subject: [PATCH 2/3] fix: run only slim topology test Signed-off-by: Magyari Sandor Szilard --- .github/workflows/test-integrations.yaml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/test-integrations.yaml b/.github/workflows/test-integrations.yaml index 5b53d579..8e1ae3ee 100644 --- a/.github/workflows/test-integrations.yaml +++ b/.github/workflows/test-integrations.yaml @@ -267,11 +267,8 @@ jobs: # Ensure this job runs only after all jobs that produce artifacts have completed needs: [ - run-tests-slim, - run-tests-slim-spire, + run-tests-slim-topology, run-tests-directory, - run-agentic-apps, - run-tests-wfsm, ] if: ${{ always() }} runs-on: ubuntu-latest From bc9fdf85e22436db25645f8b1946d46d2bdb622b Mon Sep 17 00:00:00 2001 From: Magyari Sandor Szilard Date: Wed, 29 Oct 2025 09:40:00 +0100 Subject: [PATCH 3/3] fix: rename deploy targets Signed-off-by: Magyari Sandor Szilard --- .github/actions/deploy-components/action.yaml | 2 +- integrations/agntcy-slim/Taskfile.yml | 8 ++++---- integrations/agntcy-slim/config/peer-to-peer.yaml | 7 +++++-- integrations/agntcy-slim/config/server-config.tpl | 5 ++--- .../agntcy-slim/tests/config/main/generate_configs.go | 10 ++++++++++ .../agntcy-slim/tests/config/topology_parser.go | 6 ++++-- 6 files changed, 26 insertions(+), 12 deletions(-) diff --git a/.github/actions/deploy-components/action.yaml b/.github/actions/deploy-components/action.yaml index cc549a9d..e734a38b 100644 --- a/.github/actions/deploy-components/action.yaml +++ b/.github/actions/deploy-components/action.yaml @@ -132,7 +132,7 @@ runs: KIND_CLUSTER_NAME=${{ inputs.kind-cluster-name }} \ HELM_NAMESPACE=${{ inputs.kind-cluster-namespace }} - task -d ./${{ inputs.checkout-path }} integrations:slim:test-env:deploy:generated \ + task -d ./${{ inputs.checkout-path }} integrations:slim:test-env:deploy:clusters \ SLIM_IMAGE_TAG=${{ inputs.slim-image-tag }} \ SLIM_CHART_TAG=${{ inputs.slim-chart-tag }} \ KIND_CLUSTER_NAME=${{ inputs.kind-cluster-name }} \ diff --git a/integrations/agntcy-slim/Taskfile.yml b/integrations/agntcy-slim/Taskfile.yml index 887537f1..c909529d 100644 --- a/integrations/agntcy-slim/Taskfile.yml +++ b/integrations/agntcy-slim/Taskfile.yml @@ -83,7 +83,7 @@ tasks: --wait-for-jobs \ --timeout "15m" - test-env:generate:configs: + test-env:generate:cluster-configs: desc: Generates test environment configuration(s) for agntcy slim based on the provided test-setup descriptor cmd: | TOPOLOGY_CONFIG={{.TOPOLOGY_CONFIG}} SLIM_CONTROLLER_ENDPOINT={{ .SLIM_CONTROLLER_ENDPOINT }} go run ./tests/config/main/ @@ -110,10 +110,10 @@ tasks: - task k8s:port-forward:controller:teardown - helm delete --namespace "admin" slim-controller - test-env:deploy:generated: + test-env:deploy:clusters: desc: Deploy agntcy slim test env for each values file in config/.generated deps: - - test-env:generate:configs + - test-env:generate:cluster-configs cmd: | #!/bin/sh for file in "./config/.gen"/*.yaml ;do @@ -131,7 +131,7 @@ tasks: echo "Deployed agntcy-slim-$(basename "$file" .yaml) with config $(basename "$file")" done - test-env:cleanup:generated: + test-env:cleanup:clusters: desc: Undeploy agntcy slim test env for each values file in config/.generated cmd: | #!/bin/sh diff --git a/integrations/agntcy-slim/config/peer-to-peer.yaml b/integrations/agntcy-slim/config/peer-to-peer.yaml index cd029ce6..2d8266e8 100644 --- a/integrations/agntcy-slim/config/peer-to-peer.yaml +++ b/integrations/agntcy-slim/config/peer-to-peer.yaml @@ -17,6 +17,9 @@ topology: clusters: "cluster-a": spireMtls: true - #daemonSet: false + #deployAsDaemonSet: false + replicaCount: 2 "cluster-b": - spireMtls: true \ No newline at end of file + spireMtls: true + #deployAsDaemonSet: false + replicaCount: 2 \ No newline at end of file diff --git a/integrations/agntcy-slim/config/server-config.tpl b/integrations/agntcy-slim/config/server-config.tpl index e350efc3..390cdae3 100644 --- a/integrations/agntcy-slim/config/server-config.tpl +++ b/integrations/agntcy-slim/config/server-config.tpl @@ -4,10 +4,9 @@ spire: enabled: {{ .Spire.Enabled }} -serviceAccount: - name: - slim: + daemonset: {{ .DeployAsDaemonSet }} + replicaCount: {{ .ReplicaCount }} overrideConfig: tracing: log_level: debug diff --git a/integrations/agntcy-slim/tests/config/main/generate_configs.go b/integrations/agntcy-slim/tests/config/main/generate_configs.go index c393c97a..d27d309c 100644 --- a/integrations/agntcy-slim/tests/config/main/generate_configs.go +++ b/integrations/agntcy-slim/tests/config/main/generate_configs.go @@ -27,6 +27,8 @@ type ServerConfigData struct { SlimControllerEndpoint string `yaml:"slimControllerEndpoint"` ClusterName string `yaml:"clusterName"` ServiceName string `yaml:"serviceName"` + DeployAsDaemonSet bool `yaml:"deployAsDaemonSet"` + ReplicaCount int `yaml:"replicaCount"` } // GenerateServerConfig generates a server configuration file from the template @@ -59,6 +61,12 @@ func GenerateClusterConfigs(topology *config.Config, slimControllerEndpoint stri // Determine spire settings based on auth configuration spireEnabled := clusterConfig.SpireMtls || clusterConfig.Auth.SpireJwt + deployAsDaemonSet := clusterConfig.DeployAsDaemonSet + replicaCount := clusterConfig.ReplicaCount + if replicaCount == 0 { + replicaCount = 1 + } + // Create template data data := ServerConfigData{ Spire: SpireConfig{ @@ -68,6 +76,8 @@ func GenerateClusterConfigs(topology *config.Config, slimControllerEndpoint stri SlimControllerEndpoint: slimControllerEndpoint, ClusterName: clusterName, ServiceName: fmt.Sprintf("agntcy-%s-slim.%s.svc.cluster.local", clusterName, clusterName), + DeployAsDaemonSet: deployAsDaemonSet, + ReplicaCount: replicaCount, } // Generate server config file diff --git a/integrations/agntcy-slim/tests/config/topology_parser.go b/integrations/agntcy-slim/tests/config/topology_parser.go index 7c8a1129..7df21b88 100644 --- a/integrations/agntcy-slim/tests/config/topology_parser.go +++ b/integrations/agntcy-slim/tests/config/topology_parser.go @@ -25,8 +25,10 @@ type Client struct { // Server represents a server configuration in the topology type Server struct { - Auth Auth `yaml:"auth"` - SpireMtls bool `yaml:"spireMtls,omitempty"` + Auth Auth `yaml:"auth"` + SpireMtls bool `yaml:"spireMtls,omitempty"` + DeployAsDaemonSet bool `yaml:"deployAsDaemonSet,omitempty"` + ReplicaCount int `yaml:"replicaCount,omitempty"` } // Topology represents the topology configuration