diff --git a/.github/release.yml b/.github/release.yml deleted file mode 100644 index 060ed6d..0000000 --- a/.github/release.yml +++ /dev/null @@ -1,62 +0,0 @@ -name: Release agents with goreleaser -on: - push: - tags: - - v*.*.* - -jobs: - discovery: - runs-on: ubuntu-latest - name: Release discovery - defaults: - run: - working-directory: . - steps: - - uses: actions/checkout@v3 - - name: Unshallow Fetch - run: git fetch --prune --unshallow - - uses: actions/setup-go@v3 - with: - go-version: 1.21 - - name: Export SDK Version # exports the SDK_VERSION to be used by the goreleaser - run: echo "SDK_VERSION=$(make sdk-version)" >> $GITHUB_ENV - - name: Discovery Release - uses: goreleaser/goreleaser-action@v4.2.0 - with: - args: release -f .goreleaser-da.yml - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - traceability: - runs-on: ubuntu-latest - name: Release traceability - defaults: - run: - working-directory: . - steps: - - uses: actions/checkout@v3 - - name: Unshallow Fetch - run: git fetch --prune --unshallow - - uses: actions/setup-go@v3 - with: - go-version: 1.21 - - name: Export SDK Version # exports the SDK_VERSION to be used by the goreleaser - run: echo "SDK_VERSION=$(make sdk-version)" >> $GITHUB_ENV - - name: Traceability Release - uses: goreleaser/goreleaser-action@v4.2.0 - with: - args: release -f .goreleaser-ta.yml - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - notifyTeamsChannel: - needs: [discovery, traceability] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - name: Notify Teams channel - env: - TEAMS_WEBHOOK_URL: ${{ secrets.TEAMS_WEBHOOK_URL }} - TAG: ${{ github.ref_name }} - run: ./release.sh diff --git a/.github/workflows/build-discovery-agent-docker.yml b/.github/workflows/build-discovery-agent-docker.yml index 2964728..f513fe7 100644 --- a/.github/workflows/build-discovery-agent-docker.yml +++ b/.github/workflows/build-discovery-agent-docker.yml @@ -21,6 +21,13 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Set output + id: vars + run: | + echo "date=$(date +'%Y%m%d%H%M%S')" >> $GITHUB_OUTPUT + echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT + echo "sdkversion=$(grep github.com/Axway/agent-sdk go.mod | awk '{print $2}')" >> $GITHUB_OUTPUT + echo "commit=$(git rev-parse --short ${{ github.sha }})" >> $GITHUB_OUTPUT - name: Extract metadata (tags, labels) for Docker id: meta uses: docker/metadata-action@v4 @@ -33,5 +40,11 @@ jobs: context: . file: build/discovery/Dockerfile push: true + build-args: | + time=${{ steps.vars.outputs.date }} + CGO_ENABLED=0 + version=${{ steps.vars.outputs.tag }} + sdk_version=${{ steps.vars.outputs.sdkversion }} + commit_id=${{ steps.vars.outputs.commit }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/build-traceability-agent-docker.yml b/.github/workflows/build-traceability-agent-docker.yml index c1864bd..8bba1c5 100644 --- a/.github/workflows/build-traceability-agent-docker.yml +++ b/.github/workflows/build-traceability-agent-docker.yml @@ -21,6 +21,13 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Set output + id: vars + run: | + echo "date=$(date +'%Y%m%d%H%M%S')" >> $GITHUB_OUTPUT + echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT + echo "sdkversion=$(grep github.com/Axway/agent-sdk go.mod | awk '{print $2}')" >> $GITHUB_OUTPUT + echo "commit=$(git rev-parse --short ${{ github.sha }})" >> $GITHUB_OUTPUT - name: Extract metadata (tags, labels) for Docker id: meta uses: docker/metadata-action@v4 @@ -33,5 +40,11 @@ jobs: context: . file: build/traceability/Dockerfile push: true + build-args: | + time=${{ steps.vars.outputs.date }} + CGO_ENABLED=0 + version=${{ steps.vars.outputs.tag }} + sdk_version=${{ steps.vars.outputs.sdkversion }} + commit_id=${{ steps.vars.outputs.commit }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} diff --git a/.gitignore b/.gitignore index 1c755b5..7de5e89 100644 --- a/.gitignore +++ b/.gitignore @@ -21,7 +21,11 @@ bin/ .run/ *.log -kong_discovery_agent.yml -kong_traceability_agent.yml +/kong_discovery_agent.yml +/kong_traceability_agent.yml specs/ + +secret.yaml +overrides.yaml +configmap.yaml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ebe0413..3716586 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -115,6 +115,18 @@ whitesource:on-schedule: - echo "Checking out ${GIT_TAG_PREFIX}${LATEST_TAG}" - git checkout ${GIT_TAG_PREFIX}${LATEST_TAG} +blackduck:on-schedule: + extends: .blackduck + rules: + - !reference [.mirror-schedule-csr-rules, rules] + before_script: + - git config --global http.sslVerify false + - git config --global url."ssh://git@git.ecd.axway.org".insteadOf "https://git.ecd.axway.org"'' + - git fetch + - *get-latest-tag + - echo "Checking out ${GIT_TAG_PREFIX}${LATEST_TAG}" + - git checkout ${GIT_TAG_PREFIX}${LATEST_TAG} + # overridden from csrjobs.yml because mirror repos like this one don't get merge events fortify: rules: @@ -133,8 +145,6 @@ whitesource: blackduck: rules: - !reference [.mirror-branch-csr-rules, rules] - before_script: - - export GOWORK=off run-csr: rules: diff --git a/.goreleaser-da.yml b/.goreleaser-da.yml deleted file mode 100644 index 66e5b63..0000000 --- a/.goreleaser-da.yml +++ /dev/null @@ -1,60 +0,0 @@ -# Documentation at http://goreleaser.com -before: - hooks: - - go mod download - - go mod tidy - -builds: - - id: kong_discovery_agent - binary: kong_discovery_agent - main: ./cmd/discovery/main.go - flags: - - -tags=static_all - - -a - ldflags: - - -X 'github.com/Axway/agent-sdk/pkg/cmd.BuildTime={{ .Date }}' - - -X 'github.com/Axway/agent-sdk/pkg/cmd.BuildVersion={{ .Version }}' - - -X 'github.com/Axway/agent-sdk/pkg/cmd.BuildCommitSha={{ .Commit }}' - - -X 'github.com/Axway/agent-sdk/pkg/cmd.BuildAgentName=KongDiscoveryAgent' - - -X 'github.com/Axway/agent-sdk/pkg/cmd.BuildAgentDescription=Kong Discovery Agent' - - -X 'github.com/Axway/agent-sdk/pkg/cmd.SDKBuildVersion={{ .Env.SDK_VERSION }}' - env: - - CGO_ENABLED=0 - goos: - - linux - - windows - - darwin - ignore: - - goos: windows - goarch: arm64 - -archives: - - id: discovery_agent_archives - name_template: >- - kong_discovery_agent_{{ .Version }}_{{ .Os }}_ - {{- if eq .Arch "darwin" }}Darwin - {{- else if eq .Arch "linux" }}Linux - {{- else if eq .Arch "windows" }}Windows - {{- else if eq .Arch "386" }}i386 - {{- else if eq .Arch "amd64" }}x86_64 - {{- else }}{{ .Arch }}{{ end }} - wrap_in_directory: discovery_agent - files: - - README_discovery.md - - README_subscription.md - - src: build/kong_discovery_agent.yml - dst: . - strip_parent: true - -checksum: - name_template: "discovery_checksums.txt" - -snapshot: - name_template: "{{ .Tag }}-next" - -changelog: - sort: asc - filters: - exclude: - - '^docs:' - - '^test:' diff --git a/.goreleaser-ta.yml b/.goreleaser-ta.yml deleted file mode 100644 index d733a86..0000000 --- a/.goreleaser-ta.yml +++ /dev/null @@ -1,59 +0,0 @@ -# Documentation at http://goreleaser.com -before: - hooks: - - go mod download - - go mod tidy - -builds: - - id: kong_traceability_agent - binary: kong_traceability_agent - main: ./cmd/traceability/main.go - flags: - - -tags=static_all - - -a - ldflags: - - -X 'github.com/Axway/agent-sdk/pkg/cmd.BuildTime={{ .Date }}' - - -X 'github.com/Axway/agent-sdk/pkg/cmd.BuildVersion={{ .Version }}' - - -X 'github.com/Axway/agent-sdk/pkg/cmd.BuildCommitSha={{ .Commit }}' - - -X 'github.com/Axway/agent-sdk/pkg/cmd.BuildAgentName=KongTraceabilityAgent' - - -X 'github.com/Axway/agent-sdk/pkg/cmd.BuildAgentDescription=Kong Traceability Agent' - - -X 'github.com/Axway/agent-sdk/pkg/cmd.SDKBuildVersion={{ .Env.SDK_VERSION }}' - env: - - CGO_ENABLED=0 - goos: - - linux - - windows - - darwin - ignore: - - goos: windows - goarch: arm64 - -archives: - - id: traceability_agent_archives - name_template: >- - kong_traceability_agent_{{ .Version }}_{{ .Os }}_ - {{- if eq .Arch "darwin" }}Darwin - {{- else if eq .Arch "linux" }}Linux - {{- else if eq .Arch "windows" }}Windows - {{- else if eq .Arch "386" }}i386 - {{- else if eq .Arch "amd64" }}x86_64 - {{- else }}{{ .Arch }}{{ end }} - wrap_in_directory: traceability_agent - files: - - README_traceability.md - - src: build/kong_traceability_agent.yml - dst: . - strip_parent: true - -checksum: - name_template: "traceability_checksums.txt" - -snapshot: - name_template: "{{ .Tag }}-next" - -changelog: - sort: asc - filters: - exclude: - - '^docs:' - - '^test:' diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 57fc715..0000000 --- a/Dockerfile +++ /dev/null @@ -1,38 +0,0 @@ -FROM beano.swf-artifactory.lab.phx.axway.int/beano-alpine-base:latest as builder - -RUN mkdir -p /go/src/git.ecd.axway.org/apigov/kong_traceability_agent - -WORKDIR /go/src/git.ecd.axway.org/apigov/kong_traceability_agent - -COPY . . - -RUN make build - -RUN ls -l bin/ - -# Create non-root user -RUN addgroup -g 2500 axway && adduser -u 2500 -D -G axway axway -RUN chown -R axway:axway /go/src/git.ecd.axway.org/apigov/kong_traceability_agent/bin/kong_traceability_agent -USER axway - -# alpine 3.12.0 -FROM docker.io/alpine@sha256:a15790640a6690aa1730c38cf0a440e2aa44aaca9b0e8931a9f2b0d7cc90fd65 - -COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt -COPY --from=builder /etc/passwd /etc/passwd -COPY --from=builder /go/src/git.ecd.axway.org/apigov/kong_traceability_agent/kong_traceability_agent.yml /kong_traceability_agent.yml -COPY --from=builder /go/src/git.ecd.axway.org/apigov/kong_traceability_agent/bin/kong_traceability_agent /kong_traceability_agent -COPY --from=builder /go/src/git.ecd.axway.org/apigov/kong_traceability_agent/private_key.pem private_key.pem -COPY --from=builder /go/src/git.ecd.axway.org/apigov/kong_traceability_agent/public_key.pem public_key.pem - -RUN mkdir /keys /data && \ - chown -R axway /data /keys /kong_traceability_agent.yml && \ - chmod go-w /kong_traceability_agent.yml - -RUN find / -perm /6000 -type f -exec chmod a-s {} \; || true - -USER axway - -VOLUME ["/keys"] - -ENTRYPOINT ["/kong_traceability_agent"] \ No newline at end of file diff --git a/README.md b/README.md index 8ddd31f..df4de44 100644 --- a/README.md +++ b/README.md @@ -1,81 +1,368 @@ # Getting started -To download the package dependencies run `make download` +The Kong agents are used to discover, provision access to, and track usages of Kong Gateway routes. -## Create an environment in Central +- [Getting started](#getting-started) + - [Setup](#setup) + - [Amplify setup](#amplify-setup) + - [Platform - organization ID](#platform---organization-id) + - [Platform - service account](#platform---service-account) + - [Central - environment](#central---environment) + - [Kong setup](#kong-setup) + - [Kong admin API secured by Kong Gateway](#kong-admin-api-secured-by-kong-gateway) + - [Specification discovery methods](#specification-discovery-methods) + - [Local specification path](#local-specification-path) + - [URL specification paths](#url-specification-paths) + - [Kong agents deployment](#kong-agents-deployment) + - [Additional information](#additional-information) + - [Docker](#docker) + - [Environment variable files](#environment-variable-files) + - [Deployment](#deployment) + - [Helm](#helm) + - [Download](#download) + - [Create secrets](#create-secrets) + - [Create volume, local specification files only](#create-volume-local-specification-files-only) + - [Create overrides](#create-overrides) + - [Deploy local helm chart](#deploy-local-helm-chart) + - [Discovery process](#discovery-process) + - [Provisioning process](#provisioning-process) + - [Marketplace application](#marketplace-application) + - [Access request](#access-request) + - [Credential](#credential) + - [Environment variables](#environment-variables) -Log into Amplify Central https://apicentral.axway.com -Navigate to the Topology page -Click the "Environment" button in the top right. -Select "Other" for the gateway type. -Provide a name and a title, such as "kong-gateway" and then hit "Save" in the top right. +## Setup -## Create a DOSA Account +The following sections will guide you on how to setup Amplify Platform and Central then connect your Kong agents. + +### Amplify setup + +This section will walk you through creating an service account in Amplify Platform and an environment on Amplify Central. It will also help you find all of the required values needed to start your Kong agents. + +#### Platform - organization ID + +- Log into your [Amplify Platform](https://platform.axway.com) account +- Navigate to your [Organizations](https://platform.axway.com/org) page +- Note your *Organization ID* + +#### Platform - service account + +- Log into your [Amplify Platform](https://platform.axway.com) account +- Navigate to your [Organizations Service Accounts](https://platform.axway.com/org/client) page +- Click the *+ Service Account* button +- Set the following + - Name: *Kong Agents*, for example + - Description: optional + - Tags: optional + - Method: *Client Certificate* + - Credentials: *Platform-generated key pair* + - Org Roles: *Administrator* and *Central Admin* + - Teams: Do not set any +- Download the Private Key and note its location +- Note the *Client ID* of the new service account +- Copy the *Public Key* contents and save, in the same place as the private key, naming it *public_key.pem* +- Move both of the key files to a single directory and save the path, ex: `/home/user/keys` + +You now have the service account information needed for you Kong Agent installation. + +#### Central - environment + +- Log into Amplify Central for your Region + - [US](https://apicentral.axway.com) + - [EU](https://central.eu-fr.axway.com) + - [APAC](https://central.ap-sg.axway.com/) +- On the left navigation bar select *Topology* and then *Environments* +- Click the *+ Environment* button +- Set the following + - Environment Name: *Kong Gateway*, for example + - Environment Type: *Custom/SDK* + - Custom Type: *Kong* + - Production: set the appropriate value + - Governance: *Customer Managed* + - Description: optional + - Profile Image/Icon: optiona + - Click *Next >* +- Finish up the wizard setting values as desired, on the last page click *Save* +- Note the *Logical Name* for your new environment + +### Kong setup + +#### Kong admin API secured by Kong Gateway + +See [Kong - Securing the Admin API](https://docs.konghq.com/gateway/latest/production/running-kong/secure-admin-api/) + +After following the procedures above the Kong Admin API can be secured using any authentication method that Kong provides. In this section you will learn the authentication types that the Kong agents support. As well as how to retrieve the values needed for the Kong agents. + +Once the Kong admin API is secured a gateway service for it must be added to Kong and then a route configured to access the gateway service. After adding those configurations the following authentication may be added to the route. Then create a consumer, in Kong, for the agent and add credentials for that consumer. Note these credentials for later. + +- Basic authentication +- API Key authentication +- OAuth2 authentication + +#### Specification discovery methods + +In order to publish a specification file that properly represents the gateway service configured in Kong, discovery agent supports two types of specification discovery methods. The first is a local directory, to the Kong agent, that specification files are saved in. The other is a list of URL paths that the Kong agent will query to attempt to find the specification file/ + +##### Local specification path + +The local specification discovery method is configured by providing a value for the `KONG_SPEC_LOCALPATH` variable. When set the Kong agent will look for a tag, on the gateway service, that is prefixed by `spec_local_`. When that tag is set the value, after stripping the prefix, is used to find the specification file in directory configured by `KONG_SPEC_LOCALPATH`. When this configuration value is set no other specification discovery methods will be used. + +Ex. + +Files on disk + +```shell +> ls -l /path/to/specfiles +petstore.json +my-service.yaml +``` + +Configuration for agent + +```shell +KONG_SPEC_LOCALPATH=/path/to/specfiles +``` + +Configuration on my-service gateway service + +```json +{ +... +"tags": [ + "tag1", + "tag2", + "spec_local_my-service.yaml", + "tag3" +] +... +} +``` + +##### URL specification paths + +The URL specification paths discovery method is configured by value(s) for the `KONG_SPEC_URLPATHS` variable, comma separated. When values are set here, and a local path is not set, The Kong agent will query each of these paths against the gateway service in order to find a specification file. Once a specification file is found none of the other configured URL paths will be queried as that specification file will be used in the creation of the API Service on Central. + +Ex. + +Configuration for agent + +```shell +KONG_SPEC_URLPATHS=/openapi.json,/swagger.json +``` + +## Kong agents deployment + +The Kong agents are delivered as containers, kong_discovery_agent and kong_traceability_agent. These containers can be deployed directly to a container server, such as Docker, or using the provided helm chart. In this section you will lean how to deploy the agents directly as containers or within a kubernetes cluster using the helm chart. + +### Additional information + +Before beginning to deploy the agents following information will need to be gathered in addition to the details that were noted in setup. + +- The full URL to connect to the Kong admin API, `KONG_ADMIN_URL` +- The host the agent will use when setting the endpoint of a discovered API, (`KONG_PROXY_HOST`) + - The HTTP `KONG_PROXY_PORTS_HTTP` and HTTPs `KONG_PROXY_PORTS_HTTPS` ports the agent will use with the endpoint above +- The URL paths, hosted by the gateway service, to query for spec files, `KONG_SPEC_URLPATHS` + +### Docker + +#### Environment variable files + +In this section we will use the information gathered within the setup and additional information sections above and create two environment variable files for each agent to use. This is the minimum configuration assuming defaults for all other available settings. Note the setting below expect the use of the API Key authentication method for the [Kong admin api](#kong-admin-api-secured-by-kong-gateway). + +Discovery Agent + +```shell +KONG_ADMIN_URL=https://kong.url.com:8444 +KONG_ADMIN_AUTH_APIKEY_HEADER="apikey" +KONG_ADMIN_AUTH_APIKEY_VALUE=123456789abcdefghijkl098765432109 +KONG_PROXY_HOST=kong.proxy.endpoint.com +KONG_PROXY_PORTS_HTTP=8000 +KONG_PROXY_PORTS_HTTPS=8443 +KONG_SPEC_LOCALPATH=/specs + +CENTRAL_ORGANIZATIONID=123456789 +CENTRAL_AUTH_CLIENTID=kong-agents_123456789-abcd-efgh-ijkl-098765432109 +CENTRAL_ENVIRONMENT=kong +CENTRAL_GRPC_ENABLED=true + +AGENTFEATURES_MARKETPLACEPROVISIONING=true +``` + +Traceability Agent -Create a public and private key pair locally on your computer. ```shell -openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048 -openssl rsa -in private_key.pem -pubout -out public_key.pem +KONG_ADMIN_URL=https://kong.url.com:8444 +KONG_ADMIN_AUTH_APIKEY_HEADER="apikey" +KONG_ADMIN_AUTH_APIKEY_VALUE=123456789abcdefghijkl098765432109 + +CENTRAL_ORGANIZATIONID=123456789 +CENTRAL_AUTH_CLIENTID=kong-agents_123456789-abcd-efgh-ijkl-098765432109 +CENTRAL_ENVIRONMENT=kong +CENTRAL_GRPC_ENABLED=true + +AGENTFEATURES_MARKETPLACEPROVISIONING=true ``` -In Central, click the "Access" tab on the sidebar, which is the second to last tab. -Click on "Service Accounts". -Click the button in the top right that says "+ Service Account". -Name the account and provide the public key. -## Find your Organization ID +#### Deployment + +In the following docker commands... -After making the environment click on your name in the top right. Select "Organization" from the dropdown. -You will see a field called "Organization ID". This will be needed to connect the agents to your org. +- `/home/user/keys` in the commands below refers to the directory where the key files were created during the last step in [Platform - service account](#platform---service-account) +- `/home/user/discovery/data:/data` and `/home/user/traceability/data:/data` are volumes that are used to store cached information to be saved outside of the container in order to persist restarts +- `/home/user/specs:/specs` is a volume mount for the spec files, the path in the `KONG_SPEC_LOCALPATH` variable is `/specs` and the path outside fo the container is `/home/user/specs`. +- `discovery-agents.env` and `traceability-agents.env` are files with the various environment variable settings that are available to each agent -## Create a Kong user +Kong Discovery agent -Log into the kong manager. You will need to have a trial enterprise account. Ex: https://manager-radixlink2fbc76.kong-cloud.com/login -Click the Teams tab in the top navigation -Click the RBAC Users tab -Click the "Add New User" button -Provide a name for the user, and a value to use as a token, ex: 1234. -Click the Add/Edit Roles and add the "super-admin" role. +```shell +docker run -d -v /home/user/keys:/keys -v /home/user/specs:/specs -v /home/user/discovery/data:/data --env-file discovery-agents.env ghcr.io/axway/kong_discovery_agent:latest +``` + +Kong Traceability agent + +```shell +docker run -d -v /home/user/keys:/keys -v /home/user/traceability/data:/data --env-file traceability-agents.env ghcr.io/axway/kong_traceability_agent:latest +``` + +### Helm + +#### Download + +At the current time the Kong agents helm chart is not hosted on a helm chart repository. To deploy using this helm chart you will first want to download the helm directory from your desired release tag, removing the v, 0.0.1 in the sample below. + +```shell +tag=0.0.1 # tag v0.0.1 with 'v' removed +curl -L https://github.com/Axway/agents-kong/archive/refs/tags/v${tag}.tar.gz --output kong-agents.tar.gz # download release archive +tar xvf kong-agents.tar.gz --strip-components=2 agents-kong-${tag}/helm/kong-agents # extract the helm chart in the current directory +rm kong-agents.tar.gz # remove the archive +``` -## Fill out the environment variables +#### Create secrets -Copy the content of `default_kong_discovery_agent.yml` to a new file named `kong_discovery_agent.yml` -Copy the content of `default_kong_traceability_agent.yml` to a new file named `kong_traceability_agent.yml` +Platform service account key secret -In each of the two config files for the agents provide the following variables for your config. -Provide the `environment`, `organizationID`, `platformURL`, `team`, `url`, `clientID`, `privateKey`, `publicKey` (provide the full file path to the keys). +kong-agent-keys.yaml -In the `kong_discovery_agent.yml` file provide the details of the kong user. `adminEndpoint`, `proxyEndpoint`, `proxyEndpointProtocols`, `user`, `token` +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: kong-agent-keys +type: Opaque +stringData: + private_key: | + -----BEGIN PRIVATE KEY----- + private + key + data + -----END PRIVATE KEY----- + public_key: | + -----BEGIN PUBLIC KEY----- + public + key + data + -----END PUBLIC KEY----- +``` + +#### Create volume, local specification files only + +A volume of with the local specification files is required, given that is the desired [specification discovery method](#specification-discovery-methods). This volume could be of any kubernetes resource type which can be mounted in the Kong agent container. Below is a sample of a ConfigMap that is used for the local specification files. See [Kubernetes Volumes](https://kubernetes.io/docs/concepts/storage/volumes/). + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: my-spec-files +data: + petstore.json: | + ...spec file contents... +``` + +Once a resource with the files is created, which ever resource type is chosen, the overrides file will need to be updated with that resource information for mounting as a volume. + +```yaml +kong: + ... + spec: + localPath: + configMap: # type of the resource, provided in the deployment as a volume. + name: my-spec-files # name of the resource created +``` + +#### Create overrides + +overrides.yaml + +```yaml +kong: + admin: + url: https://kong.url.com:8444 + proxy: + host: kong.proxy.endpoint.com + ports: + http: 8000 + https: 8443 + spec: + localPath: + configMap: + name: my-spec-files +env: + CENTRAL_ORGANIZATIONID: 123456789 + CENTRAL_AUTH_CLIENTID: kong-agents_123456789-abcd-efgh-ijkl-098765432109 + CENTRAL_ENVIRONMENT: kong + CENTRAL_GRPC_ENABLED: true + AGENTFEATURES_MARKETPLACEPROVISIONING: true +``` + +#### Deploy local helm chart + +Assuming you are already in the desired kubernetes context and namespace, execute the following commands. + +Create the secret containing the Central key files used for authentication. + +```shell +kubectl apply -f kong-agent-keys.yaml +``` + +Install the helm chart using the created overrides file. + +```shell +helm install kong-agents ./kong-agents -f overrides.yaml +``` -In the `kong_traceability_agent.yml` overrides can be provided if desired under `http_log_plugin_config` for the path and port for http endpoint that listens for request logs from Kong's HTTP Log plugin +## Discovery process -# Kong Discovery Agent +On startup the Kong discovery agent first validates that it is able to connect to all required services. Once connected to Kong the agent begins looking at the Plugins configured, as the ACL plugin is required for handling Amplify Central provisioning events. Then the agent will determine, from the plugins, which credential types the Kong Gateway has configured and create the Central representation of those types. -The discovery agent has two modes to discover specs. Specs can be discovered from either the Kong Developer Portal by setting `specDevPortalEnabled` to `true`, or they can be discovered from a local directory. -To discover specs from a local directory provide a file path for the agent to look find specs in by setting the `specHomePath` field. +After that initial startup process the discovery agent begins running its main discovery loop. In this loop the agent first gets a list of all Gateway Services. With each service the agent looks for all configured routes. The agent then looks to gather the specification file, see [Specification discovery methods](#specification-discovery-methods), if found the process continues. Using the route the agent checks for plugins to determine the types of credentials to associate with it. After gathering all of this information the agent creates a new API service with the specification file and linking the appropriate credentials. The endpoints associated to the API service are constructed using the **KONG_PROXY_HOST**, **KONG_PROXY_PORTS_HTTP**, and **KONG_PROXY_PORTS_HTTPS** settings. -## Build and run the binary +## Provisioning process -To build the discovery agent run `make build-disc` +As described in the [Discovery process](#discovery-process) section the Kong agent creates all supported credential types on Central at startup. Once API services are published they can be made into Assets and Products via Central itself. The Products can then be published to the Marketplace for consumption. In order to receive access to the service a user must first request access to it and the Kong agent provisioning process will execute based off of that request. -To run the discovery agent run `make run-disc` +### Marketplace application -# Kong Traceability Agent +A Marketplace application is created by a Marketplace user. When a resource within the Kong environment is added to that application Central will create a ManagedApplication resource that the agent will execute off of. This ManagedApplication resource event is captured by the Kong agent and the agent creates a Kong consumer. In addition to the creation of the Consumer the agent adds an ACL Group ID to the Consumer, to be used by the Access Request. -Kong Traceability agent does these tasks: -* Runs an HTTP Server exposing an endpoint that serves as the target for Kong's [HTTP Log Plugin](https://docs.konghq.com/hub/kong-inc/http-log/) -* Processes the request logs as they are sent by the HTTP Log plugin and builds transaction summary and transaction leg event in the format expected by Central's API Observer -* Uses libbeat to publish the events to Condor +### Access request -## Prerequisites -Kong Traceability agent requires **global deployment** of the below plugin on your Kong instance in order to generate transaction summary and transaction leg event for all Kong's proxies -* [HTTP Log Plugin](https://docs.konghq.com/hub/kong-inc/http-log/) used to get the request logs associated with Kong proxy invocation +When a Marketplace user requests access to a resource, within the Kong environment, Central will create an AccessRequest resource in the same Kong environment. The agent receives this event and makes several changes within Kong. First the agent will add, or update, an ACL configuration on the Route being requested. This ACL will allow the Group ID created during the handling of the [Marketplace application](#marketplace-application) access to the route. Additionally, if a quota for this route has been set in Central in the product being handled the agent will add a Rate limiting plugin to reflect the quota that was set in Central for that product. Note: Quotas in Central can have a Weekly amount, this is not supported by Kong and the agent will reject the Access Request. -## Build and run the binary +### Credential -To build the traceability agent run `make build-trace` +Finally, when a Marketplace user requests a credential, within the Kong environment, Central will create a Credential resource in the same Kong environment. The agent receives this event and creates the proper credential type for the Consumer that the [Marketplace application](#marketplace-application) handling created. After successfully creating this credential the necessary details are returned back to the Central to be viewed and used by the Marketplace user. -To run the traceability agent run `make run-trace` +## Environment variables -# Development +All Kong specific environment variables available are listed below -In development you can run an agent by running `go run ./cmd/discovery/main.go` or `go run ./cmd/traceability/main.go`. You do not need to build the binary for agents on every change. \ No newline at end of file +| Name | Description | +| --------------------------------- | ------------------------------------------------------------------------------------- | +| **KONG_ADMIN_URL** | The Kong admin API URL that the agent will query against | +| **KONG_ADMIN_AUTH_APIKEY_HEADER** | The API Key header name the agent will use when authenticating | +| **KONG_ADMIN_AUTH_APIKEY_VALUE** | The API Key value the agent will use when authenticating | +| **KONG_PROXY_HOST** | The proxy endpoint that the agent will use in API Services for discovered Kong routes | +| **KONG_PROXY_PORTS_HTTP** | The HTTP port number that the agent will set for discovered APIS | +| **KONG_PROXY_PORTS_HTTPS** | The HTTPs port number that the agent will set for discovered APIS | +| **KONG_SPEC_LOCALPATH** | The local path that the agent will look in for API definitions | +| **KONG_SPEC_URLPATHS** | The URL paths that the agent will query on the gateway service for API definitions | diff --git a/build/discovery/kong_discovery_agent.yml b/build/discovery/kong_discovery_agent.yml deleted file mode 100644 index 015e080..0000000 --- a/build/discovery/kong_discovery_agent.yml +++ /dev/null @@ -1,31 +0,0 @@ -# this is a sample config file. Copy the content of this file to a new file named kong_discovery_agent.yml -central: - environment: - mode: publishToEnvironmentAndCatalog - organizationID: "" - platformURL: https://platform.axway.com - pollInterval: 20s - team: "Default Team" - url: https://apicentral.axway.com - auth: - clientID: - privateKey: - publicKey: - realm: Broker - timeout: 20s - url: https://login.axway.com/auth - -log: - level: debug - format: json - output: stdout - path: logs - -kong: - adminEndpoint: - token: 1234 - proxyEndpoint: - proxyEndpointProtocols: - http: 80 - https: 443 - specDownloadPaths: [] diff --git a/build/traceability/kong_traceability_agent.yml b/build/traceability/kong_traceability_agent.yml index 5659287..0285244 100644 --- a/build/traceability/kong_traceability_agent.yml +++ b/build/traceability/kong_traceability_agent.yml @@ -1,51 +1,115 @@ -# this is a sample config file. Copy the content of this file to a new file named kong_traceability_agent.yml kong_traceability_agent: + # Settings for connecting to Kong + kong: + admin: + url: ${KONG_ADMIN_URL} + auth: + apikey: + header: ${KONG_ADMIN_AUTH_APIKEY_HEADER} + value: ${KONG_ADMIN_AUTH_APIKEY_VALUE} + http_log_plugin_config: + path: ${KONG_LOGS_HTTP_SERVER_PATH} + port: ${KONG_LOGS_HTTP_SERVER_PORT} + # Settings for connecting to Amplify Central central: - environment: - mode: publishToEnvironment - organizationID: "" - platformURL: https://platform.axway.com - pollInterval: 20s - team: "Default Team" - url: https://apicentral.axway.com + url: ${CENTRAL_URL:https://apicentral.axway.com} + organizationID: ${CENTRAL_ORGANIZATIONID:""} + team: ${CENTRAL_TEAM:""} + deployment: ${CENTRAL_DEPLOYMENT:prod} + environment: ${CENTRAL_ENVIRONMENT:""} + environmentID: ${CENTRAL_ENVIRONMENTID} # only required when CENTRAL_USAGEREPORTING_OFFLINE=true + agentName: ${CENTRAL_AGENTNAME:""} + platformURL: ${CENTRAL_PLATFORMURL:https://platform.axway.com} + reportActivityFrequency: ${CENTRAL_REPORTACTIVITYFREQUENCY:5m} + versionChecker: ${CENTRAL_VERSIONCHECKER:true} + usageReporting: + publish: ${CENTRAL_USAGEREPORTING_PUBLISH} + publishMetric: ${CENTRAL_USAGEREPORTING_PUBLISHMETRIC} + interval: ${CENTRAL_USAGEREPORTING_INTERVAL} + usageSchedule: ${CENTRAL_USAGEREPORTING_USAGESCHEDULE} + offline: ${CENTRAL_USAGEREPORTING_OFFLINE} + offlineSchedule: ${CENTRAL_USAGEREPORTING_OFFLINESCHEDULE} auth: - clientID: - privateKey: - publicKey: - realm: Broker - timeout: 20s - url: https://login.axway.com/auth - -http_log_plugin_config: - # Path used by Kong's HTTP Log plugin to send request logs - path: ${LOGS_HTTP_SERVER_PATH} - # Port that listens for request logs sent by Kong's HTTP Log plugin - port: ${LOGS_HTTP_SERVER_PORT} + url: ${CENTRAL_AUTH_URL:https://login.axway.com/auth} + realm: ${CENTRAL_AUTH_REALM:Broker} + clientId: ${CENTRAL_AUTH_CLIENTID:""} + privateKey: ${CENTRAL_AUTH_PRIVATEKEY:./private_key.pem} + publicKey: ${CENTRAL_AUTH_PUBLICKEY:./public_key.pem} + keyPassword: ${CENTRAL_AUTH_KEYPASSWORD:""} + timeout: 10s + ssl: + minVersion: ${CENTRAL_SSL_MINVERSION:""} + maxVersion: ${CENTRAL_SSL_MAXVERSION:""} + nextProtos: ${CENTRAL_SSL_NEXTPROTOS:[]} + cipherSuites: ${CENTRAL_SSL_CIPHERSUITES:[]} + insecureSkipVerify: ${CENTRAL_SSL_INSECURESKIPVERIFY:false} + grpc: + enabled: ${CENTRAL_GRPC_ENABLED} + host: ${CENTRAL_GRPC_HOST} + port: ${CENTRAL_GRPC_PORT} + proxyUrl: ${CENTRAL_PROXYURL:""} + clientTimeout: ${CENTRAL_CLIENTTIMEOUT:60s} # Condor Ingestion service output.traceability: - compression_level: ${TRACEABILITY_COMPRESSIONLEVEL:3} enabled: true - hosts: - - ${TRACEABILITY_HOST:"ingestion-lumberjack.datasearch.axway.com:453"} + hosts: ${TRACEABILITY_HOST:ingestion.datasearch.axway.com:5044} protocol: ${TRACEABILITY_PROTOCOL:"tcp"} + compression_level: ${TRACEABILITY_COMPRESSIONLEVEL:3} + bulk_max_size: ${TRACEABILITY_BULKMAXSIZE:100} + client_timeout: ${TRACEABILITY_CLIENTTIMEOUT:60s} + pipelining: ${TRACEABILITY_PIPELINING:0} + worker: ${TRACEABILITY_WORKER:1} + loadbalance: ${TRACEABILITY_LOADBALANCE:true} + slow_start: ${TRACEABILITY_SLOWSTART:true} ssl: - enabled: true + enabled: ${TRACEABILITY_ENABLE_SSL:true} verification_mode: none cipher_suites: - "ECDHE-ECDSA-AES-128-GCM-SHA256" - "ECDHE-ECDSA-AES-256-GCM-SHA384" + - "ECDHE-ECDSA-AES-128-CBC-SHA256" - "ECDHE-ECDSA-CHACHA20-POLY1305" - "ECDHE-RSA-AES-128-CBC-SHA256" - "ECDHE-RSA-AES-128-GCM-SHA256" - "ECDHE-RSA-AES-256-GCM-SHA384" - - "ECDHE-RSA-CHACHA20-POLY1205" - worker: 1 - pipelining: 0 proxy_url: ${TRACEABILITY_PROXYURL:""} + redaction: + path: + show: ${TRACEABILITY_REDACTION_PATH_SHOW:[]} + queryArgument: + show: ${TRACEABILITY_REDACTION_QUERYARGUMENT_SHOW:[]} + sanitize: ${TRACEABILITY_REDACTION_QUERYARGUMENT_SANITIZE:[]} + requestHeader: + show: ${TRACEABILITY_REDACTION_REQUESTHEADER_SHOW:[]} + sanitize: ${TRACEABILITY_REDACTION_REQUESTHEADER_SANITIZE:[]} + responseHeader: + show: ${TRACEABILITY_REDACTION_RESPONSEHEADER_SHOW:[]} + sanitize: ${TRACEABILITY_REDACTION_RESPONSEHEADER_SANITIZE:[]} + jmsProperties: + show: ${TRACEABILITY_REDACTION_JMSPROPERTIES_SHOW:[]} + sanitize: ${TRACEABILITY_REDACTION_JMSPROPERTIES_SANITIZE:[]} + maskingCharacters: ${TRACEABILITY_REDACTION_MASKING_CHARACTERS:"\u007B*\u007D"} # unicode for {*} + sampling: + percentage: ${TRACEABILITY_SAMPLING_PERCENTAGE:10} + per_api: ${TRACEABILITY_SAMPLING_PER_API:true} + per_subscription: ${TRACEABILITY_SAMPLING_PER_SUBSCRIPTION:true} + reportAllErrors: ${TRACEABILITY_SAMPLING_REPORTALLERRORS:true} + apiExceptionsList: ${TRACEABILITY_EXCEPTION_LIST:[]} + +queue: + mem: + events: ${QUEUE_MEM_EVENTS:2048} + flush: + min_events: ${QUEUE_MEM_FLUSH_MINEVENTS:100} + timeout: ${QUEUE_MEM_FLUSH_TIMEOUT:1s} logging: metrics: enabled: false - to_stderr: true - level: ${LOG_LEVEL:"info"} + files: + permissions: 0600 + name: ${LOG_FILE_NAME:traceability_agent.log} + path: ${LOG_FILE_PATH:logs} + keepfiles: ${LOG_FILE_KEEPFILES:7} + rotateeverybytes: ${LOG_FILE_ROTATEEVERYBYTES:10485760} \ No newline at end of file diff --git a/cmd/discovery/main.go b/cmd/discovery/main.go deleted file mode 100644 index 475fb6f..0000000 --- a/cmd/discovery/main.go +++ /dev/null @@ -1,16 +0,0 @@ -package main - -import ( - "fmt" - "os" - - "github.com/Axway/agents-kong/pkg/cmd/discovery" -) - -func main() { - - if err := discovery.DiscoveryCmd.Execute(); err != nil { - fmt.Println(err) - os.Exit(1) - } -} diff --git a/cmd/traceability/main.go b/cmd/traceability/main.go deleted file mode 100644 index c957c5f..0000000 --- a/cmd/traceability/main.go +++ /dev/null @@ -1,16 +0,0 @@ -package main - -import ( - "fmt" - "os" - - _ "github.com/Axway/agent-sdk/pkg/traceability" - "github.com/Axway/agents-kong/pkg/cmd/traceability" -) - -func main() { - if err := traceability.TraceCmd.Execute(); err != nil { - fmt.Println(err) - os.Exit(1) - } -} diff --git a/default_kong_discovery_agent.yml b/default_kong_discovery_agent.yml deleted file mode 100644 index a7bcde1..0000000 --- a/default_kong_discovery_agent.yml +++ /dev/null @@ -1,32 +0,0 @@ -# this is a sample config file. Copy the content of this file to a new file named kong_discovery_agent.yml -central: - environment: - mode: publishToEnvironmentAndCatalog - organizationID: "" - platformURL: https://platform.axway.com - pollInterval: 20s - team: "Default Team" - url: https://apicentral.axway.com - auth: - clientID: - privateKey: - publicKey: - realm: Broker - timeout: 20s - url: https://login.axway.com/auth - -log: - level: debug - format: json - output: stdout - path: logs - -kong: - adminEndpoint: - token: 1234 - proxyEndpoint: - proxyEndpointProtocols: - http: 80 - https: 443 - specDownloadPaths: [] - specLocalPath: diff --git a/default_kong_traceability_agent.yml b/default_kong_traceability_agent.yml deleted file mode 100644 index 5659287..0000000 --- a/default_kong_traceability_agent.yml +++ /dev/null @@ -1,51 +0,0 @@ -# this is a sample config file. Copy the content of this file to a new file named kong_traceability_agent.yml -kong_traceability_agent: - central: - environment: - mode: publishToEnvironment - organizationID: "" - platformURL: https://platform.axway.com - pollInterval: 20s - team: "Default Team" - url: https://apicentral.axway.com - auth: - clientID: - privateKey: - publicKey: - realm: Broker - timeout: 20s - url: https://login.axway.com/auth - -http_log_plugin_config: - # Path used by Kong's HTTP Log plugin to send request logs - path: ${LOGS_HTTP_SERVER_PATH} - # Port that listens for request logs sent by Kong's HTTP Log plugin - port: ${LOGS_HTTP_SERVER_PORT} - -# Condor Ingestion service -output.traceability: - compression_level: ${TRACEABILITY_COMPRESSIONLEVEL:3} - enabled: true - hosts: - - ${TRACEABILITY_HOST:"ingestion-lumberjack.datasearch.axway.com:453"} - protocol: ${TRACEABILITY_PROTOCOL:"tcp"} - ssl: - enabled: true - verification_mode: none - cipher_suites: - - "ECDHE-ECDSA-AES-128-GCM-SHA256" - - "ECDHE-ECDSA-AES-256-GCM-SHA384" - - "ECDHE-ECDSA-CHACHA20-POLY1305" - - "ECDHE-RSA-AES-128-CBC-SHA256" - - "ECDHE-RSA-AES-128-GCM-SHA256" - - "ECDHE-RSA-AES-256-GCM-SHA384" - - "ECDHE-RSA-CHACHA20-POLY1205" - worker: 1 - pipelining: 0 - proxy_url: ${TRACEABILITY_PROXYURL:""} - -logging: - metrics: - enabled: false - to_stderr: true - level: ${LOG_LEVEL:"info"} diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 9f18ed1..0000000 --- a/docker-compose.yml +++ /dev/null @@ -1,72 +0,0 @@ -version: '3.7' - -services: - kong-db: - image: postgres:11 - environment: - POSTGRES_USER: kong - POSTGRES_DB: kong - POSTGRES_PASSWORD: kongpass - networks: - - kong-net - ports: - - "5432:5432" - kong-migration: -# image: kong:3.3.1 - image: kong:2.8.3 - command: kong migrations bootstrap - environment: - KONG_ADMIN_ACCESS_LOG: /dev/stdout - KONG_ADMIN_ERROR_LOG: /dev/stderr - KONG_ADMIN_LISTEN: '0.0.0.0:8001' - # KONG_DATABASE: "off" - KONG_DATABASE: postgres - KONG_PG_HOST: kong-db - KONG_PG_PASSWORD: kongpass - KONG_PASSWORD: test - # KONG_DECLARATIVE_CONFIG: /usr/local/kong/declarative/kong.yml - KONG_PROXY_ACCESS_LOG: /dev/stdout - KONG_PROXY_ERROR_LOG: /dev/stderr - networks: - - kong-net - depends_on: - - kong-db - kong: - image: kong:2.8.3 - environment: - KONG_ADMIN_ACCESS_LOG: /dev/stdout - KONG_ADMIN_ERROR_LOG: /dev/stderr - KONG_ADMIN_LISTEN: '0.0.0.0:8001' -# KONG_DATABASE: "off" - KONG_DATABASE: postgres - KONG_PG_HOST: kong-db - KONG_PG_PASSWORD: kongpass - KONG_PASSWORD: test -# KONG_DECLARATIVE_CONFIG: /usr/local/kong/declarative/kong.yml - KONG_PROXY_ACCESS_LOG: /dev/stdout - KONG_PROXY_ERROR_LOG: /dev/stderr -# volumes: -# - ./kong/:/usr/local/kong/declarative - networks: - - kong-net - ports: - - "8000:8000/tcp" - - "127.0.0.1:8001:8001/tcp" - - "8443:8443/tcp" - - "127.0.0.1:8444:8444/tcp" - healthcheck: - test: ["CMD", "kong", "health"] - interval: 10s - timeout: 10s - retries: 10 - restart: on-failure - deploy: - restart_policy: - condition: on-failure - depends_on: - - kong-db - - kong-migration - -networks: - kong-net: - external: false \ No newline at end of file diff --git a/go.mod b/go.mod index b1b09c7..5c66279 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/elastic/beats/v7 v7.17.5 github.com/google/uuid v1.3.1 github.com/kong/go-kong v0.47.0 + github.com/mitchellh/mapstructure v1.5.0 github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.8.4 github.com/tidwall/gjson v1.16.0 @@ -101,7 +102,6 @@ require ( github.com/mattn/go-isatty v0.0.14 // indirect github.com/miekg/dns v1.1.25 // indirect github.com/mitchellh/hashstructure v1.1.0 // indirect - github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect diff --git a/helm/kong-agents/templates/_helpers.tpl b/helm/kong-agents/templates/_helpers.tpl index 64d9fba..9c0638d 100644 --- a/helm/kong-agents/templates/_helpers.tpl +++ b/helm/kong-agents/templates/_helpers.tpl @@ -65,5 +65,5 @@ Create the name of the service account to use Create the name of the service account to use */}} {{- define "kong-agents.specDownloadPathsString" -}} -{{- join "," .Values.kong.specDownloadPaths }} +{{- join "," .Values.kong.spec.urlPaths }} {{- end -}} \ No newline at end of file diff --git a/helm/kong-agents/templates/discovery-deployment.yaml b/helm/kong-agents/templates/discovery-deployment.yaml index 2a93359..e55c05b 100644 --- a/helm/kong-agents/templates/discovery-deployment.yaml +++ b/helm/kong-agents/templates/discovery-deployment.yaml @@ -66,38 +66,63 @@ spec: {{- end }} {{- end }} env: + - name: KONG_ADMIN_URL + value: "{{ .Values.kong.admin.url }}" + - name: KONG_PROXY_HOST + value: "{{ .Values.kong.proxy.host }}" + - name: KONG_PROXY_PORTS_HTTP + value: "{{ .Values.kong.proxy.ports.http }}" + - name: KONG_PROXY_PORTS_HTTPS + value: "{{ .Values.kong.proxy.ports.https }}" + {{- if (include "kong-agents.specDownloadPathsString" .) }} + - name: KONG_SPEC_URLPATHS + value: {{ include "kong-agents.specDownloadPathsString" . }} + {{- end }} + {{- if .Values.kong.spec.localPath }} + - name: KONG_SPEC_LOCALPATH + value: /specs + {{- end }} + {{- if .Values.kong.admin.auth.apikey.value }} + - name: KONG_ADMIN_AUTH_APIKEY_VALUE + valueFrom: + secretKeyRef: + name: kong-admin-auth-apikey + key: value + - name: KONG_ADMIN_AUTH_APIKEY_HEADER + valueFrom: + secretKeyRef: + name: kong-admin-auth-apikey + key: header + {{- end }} {{- with .Values.env }} {{- range $key, $value := . }} {{- if and (not (eq (toString $value) "")) (not (eq (toString $key) "")) - (not (eq (toString $key) "KONG_ADMINENDPOINT")) - (not (eq (toString $key) "KONG_PROXYENDPOINT")) - (not (eq (toString $key) "KONG_PROXYENDPOINTPROTOCOLS_HTTP")) - (not (eq (toString $key) "KONG_PROXYENDPOINTPROTOCOLS_HTTPS")) - (not (eq (toString $key) "KONG_SPECDOWNLOADPATHS")) - (not (eq (toString $key) "KONG_TOKEN")) }} + (not (has (toString $key) (list "KONG_ADMIN_URL" + "KONG_ADMIN_AUTH_APIKEY_HEADER" + "KONG_ADMIN_AUTH_APIKEY_VALUE" + "KONG_PROXY_HOST" + "KONG_PROXY_PORTS_HTTP" + "KONG_PROXY_PORTS_HTTPS" + "KONG_SPEC_LOCALPATH" + "KONG_SPEC_URLPATHS"))) + }} - name: {{ $key }} value: {{ $value | quote }} {{- end }} {{- end }} {{- end }} - - name: KONG_ADMINENDPOINT - value: "{{ .Values.kong.adminEndpoint }}" - {{- if eq .Values.kong.token "" }} - - name: KONG_TOKEN - value: "{{ .Values.kong.token }}" - {{- end }} - - name: KONG_PROXYENDPOINT - value: "{{ .Values.kong.proxyEndpoint }}" - - name: KONG_PROXYENDPOINTPROTOCOLS_HTTP - value: "{{ .Values.kong.proxyEndpointProtocols.http }}" - - name: KONG_PROXYENDPOINTPROTOCOLS_HTTPS - value: "{{ .Values.kong.proxyEndpointProtocols.https }}" - - name: KONG_SPECDOWNLOADPATHS - value: {{ include "kong-agents.specDownloadPathsString" . }} + - name: CENTRAL_AUTH_PRIVATEKEY + value: "/keys/private_key.pem" + - name: CENTRAL_AUTH_PUBLICKEY + value: "/keys/public_key.pem" volumeMounts: - name: "kong-agent-keys" mountPath: "/keys" + {{- if .Values.kong.spec.localPath }} + - name: "kong-agent-specs" + mountPath: "/specs" + {{- end }} resources: {{- toYaml .Values.resources | nindent 12 }} volumes: @@ -109,6 +134,12 @@ spec: path: private_key.pem - key: public_key path: public_key.pem + {{- if .Values.kong.spec.localPath }} + {{- with .Values.kong.spec.localPath }} + - name: kong-agent-specs + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} diff --git a/helm/kong-agents/templates/kong-admin-auth-apikey.yaml b/helm/kong-agents/templates/kong-admin-auth-apikey.yaml new file mode 100644 index 0000000..b1cefb9 --- /dev/null +++ b/helm/kong-agents/templates/kong-admin-auth-apikey.yaml @@ -0,0 +1,10 @@ +{{- if .Values.kong.admin.auth.apikey.value }} +apiVersion: v1 +kind: Secret +metadata: + name: kong-admin-auth-apikey +type: Opaque +stringData: + header: "{{ .Values.kong.admin.auth.apikey.header }}" + value: "{{ .Values.kong.admin.auth.apikey.value }}" +{{- end }} \ No newline at end of file diff --git a/helm/kong-agents/templates/traceability-deployment.yaml b/helm/kong-agents/templates/traceability-deployment.yaml index 77ebe1e..c1a85d0 100644 --- a/helm/kong-agents/templates/traceability-deployment.yaml +++ b/helm/kong-agents/templates/traceability-deployment.yaml @@ -1,3 +1,4 @@ +{{- if .Values.kong.enable.traceability }} apiVersion: apps/v1 kind: Deployment metadata: @@ -66,27 +67,38 @@ spec: {{- end }} {{- end }} env: + - name: KONG_ADMIN_URL + value: "{{ .Values.kong.admin.url }}" + {{- if .Values.kong.admin.auth.apikey.value }} + - name: KONG_ADMIN_AUTH_APIKEY_VALUE + valueFrom: + secretKeyRef: + name: kong-admin-auth-apikey + key: value + - name: KONG_ADMIN_AUTH_APIKEY_HEADER + valueFrom: + secretKeyRef: + name: kong-admin-auth-apikey + key: header + {{- end }} {{- with .Values.env }} {{- range $key, $value := . }} {{- if and (not (eq (toString $value) "")) (not (eq (toString $key) "")) - (not (eq (toString $key) "KONG_ADMINENDPOINT")) - (not (eq (toString $key) "KONG_PROXYENDPOINT")) - (not (eq (toString $key) "KONG_PROXYENDPOINTPROTOCOLS_HTTP")) - (not (eq (toString $key) "KONG_PROXYENDPOINTPROTOCOLS_HTTPS")) - (not (eq (toString $key) "KONG_SPECDOWNLOADPATHS")) - (not (eq (toString $key) "KONG_TOKEN")) }} + (not (has (toString $key) (list "KONG_ADMIN_URL" + "KONG_ADMIN_AUTH_APIKEY_HEADER" + "KONG_ADMIN_AUTH_APIKEY_VALUE" + "KONG_PROXY_HOST" + "KONG_PROXY_PORTS_HTTP" + "KONG_PROXY_PORTS_HTTPS" + "KONG_SPEC_LOCALPATH" + "KONG_SPEC_URLPATHS"))) + }} - name: {{ $key }} value: {{ $value | quote }} {{- end }} {{- end }} {{- end }} - - name: KONG_ADMINENDPOINT - value: "{{ .Values.kong.adminEndpoint }}" - {{- if eq .Values.kong.token "" }} - - name: KONG_TOKEN - value: "{{ .Values.kong.token }}" - {{- end }} volumeMounts: - name: "kong-agent-keys" mountPath: "/keys" @@ -113,3 +125,4 @@ spec: tolerations: {{- toYaml . | nindent 8 }} {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/kong-agents/values.yaml b/helm/kong-agents/values.yaml index c786454..0fb0630 100644 --- a/helm/kong-agents/values.yaml +++ b/helm/kong-agents/values.yaml @@ -21,13 +21,22 @@ fullnameOverride: "" statusPort: 8989 kong: - adminEndpoint: - token: - proxyEndpoint: - proxyEndpointProtocols: - http: 8000 - https: 8443 - specDownloadPaths: [] + enable: + traceability: false + admin: + url: + auth: + apikey: + header: + value: + proxy: + host: + ports: + http: 8000 + https: 8443 + spec: + urlPaths: [] + localPath: # Add any environment variable overrides here env: {} diff --git a/pkg/cmd/discovery/cmd.go b/pkg/cmd/discovery/cmd.go index 7d245aa..f6659b9 100644 --- a/pkg/cmd/discovery/cmd.go +++ b/pkg/cmd/discovery/cmd.go @@ -14,13 +14,14 @@ var DiscoveryCmd corecmd.AgentRootCmd var agentConfig config.AgentConfig const ( - cfgKongToken = "kong.token" - cfgKongAdminEp = "kong.adminEndpoint" - cfgKongProxyEp = "kong.proxyEndpoint" - cfgKongProxyEpHttp = "kong.proxyEndpointProtocols.http" - cfgKongProxyEpHttps = "kong.proxyEndpointProtocols.https" - cfgKongSpecDownloadPaths = "kong.specDownloadPaths" - cfgKongSpecLocalPath = "kong.specLocalPath" + cfgKongAdminURL = "kong.admin.url" + cfgKongAdminAPIKey = "kong.admin.auth.apikey.value" + cfgKongAdminAPIKeyHeader = "kong.admin.auth.apikey.header" + cfgKongProxyHost = "kong.proxy.host" + cfgKongProxyPortHttp = "kong.proxy.port.http" + cfgKongProxyPortHttps = "kong.proxy.port.https" + cfgKongSpecURLPaths = "kong.spec.urlPaths" + cfgKongSpecLocalPath = "kong.spec.localPath" ) func init() { @@ -36,12 +37,13 @@ func init() { // Get the root command properties and bind the config property in YAML definition rootProps := DiscoveryCmd.GetProperties() - rootProps.AddStringProperty(cfgKongToken, "", "Token to authenticate with Kong Gateway") - rootProps.AddStringProperty(cfgKongAdminEp, "", "The Kong admin endpoint") - rootProps.AddStringProperty(cfgKongProxyEp, "", "The Kong proxy endpoint") - rootProps.AddIntProperty(cfgKongProxyEpHttp, 80, "The Kong proxy http port") - rootProps.AddIntProperty(cfgKongProxyEpHttps, 443, "The Kong proxy https port") - rootProps.AddStringSliceProperty(cfgKongSpecDownloadPaths, []string{}, "URL paths where the agent will look in for spec files") + rootProps.AddStringProperty(cfgKongAdminURL, "", "The Kong admin endpoint") + rootProps.AddStringProperty(cfgKongAdminAPIKey, "", "API Key value to authenticate with Kong Gateway") + rootProps.AddStringProperty(cfgKongAdminAPIKeyHeader, "", "API Key header to authenticate with Kong Gateway") + rootProps.AddStringProperty(cfgKongProxyHost, "", "The Kong proxy endpoint") + rootProps.AddIntProperty(cfgKongProxyPortHttp, 80, "The Kong proxy http port") + rootProps.AddIntProperty(cfgKongProxyPortHttps, 443, "The Kong proxy https port") + rootProps.AddStringSliceProperty(cfgKongSpecURLPaths, []string{}, "URL paths that the agent will look in for spec files") rootProps.AddStringProperty(cfgKongSpecLocalPath, "", "Local paths where the agent will look for spec files") } @@ -80,13 +82,26 @@ func initConfig(centralConfig corecfg.CentralConfig) (interface{}, error) { // Parse the config from bound properties and setup gateway config gatewayConfig := &config.KongGatewayConfig{ - Token: rootProps.StringPropertyValue(cfgKongToken), - AdminEndpoint: rootProps.StringPropertyValue(cfgKongAdminEp), - ProxyEndpoint: rootProps.StringPropertyValue(cfgKongProxyEp), - ProxyHttpPort: rootProps.IntPropertyValue(cfgKongProxyEpHttp), - ProxyHttpsPort: rootProps.IntPropertyValue(cfgKongProxyEpHttps), - SpecDownloadPaths: rootProps.StringSlicePropertyValue(cfgKongSpecDownloadPaths), - SpecLocalPath: rootProps.StringPropertyValue(cfgKongSpecLocalPath), + Admin: config.KongAdminConfig{ + URL: rootProps.StringPropertyValue(cfgKongAdminURL), + Auth: config.KongAdminAuthConfig{ + APIKey: config.KongAdminAuthAPIKeyConfig{ + Value: rootProps.StringPropertyValue(cfgKongAdminAPIKey), + Header: rootProps.StringPropertyValue(cfgKongAdminAPIKeyHeader), + }, + }, + }, + Proxy: config.KongProxyConfig{ + Host: rootProps.StringPropertyValue(cfgKongProxyHost), + Port: config.KongProxyPortConfig{ + HTTP: rootProps.IntPropertyValue(cfgKongProxyPortHttp), + HTTPS: rootProps.IntPropertyValue(cfgKongProxyPortHttps), + }, + }, + Spec: config.KongSpecConfig{ + URLPaths: rootProps.StringSlicePropertyValue(cfgKongSpecURLPaths), + LocalPath: rootProps.StringPropertyValue(cfgKongSpecLocalPath), + }, } agentConfig = config.AgentConfig{ diff --git a/pkg/common/common.go b/pkg/common/common.go index d77d47d..ec209e7 100644 --- a/pkg/common/common.go +++ b/pkg/common/common.go @@ -12,8 +12,7 @@ const ( AclGroup = "amplify.group" Marketplace = "marketplace" // CorsField - - CorsField = "cors" - ProvisionKey = "provision_key" + CorsField = "cors" // RedirectURLsField - RedirectURLsField = "redirectURLs" diff --git a/pkg/config/discovery/config.go b/pkg/config/discovery/config.go index 0225aa0..d07944d 100644 --- a/pkg/config/discovery/config.go +++ b/pkg/config/discovery/config.go @@ -4,7 +4,6 @@ import ( "fmt" corecfg "github.com/Axway/agent-sdk/pkg/config" - "github.com/Axway/agent-sdk/pkg/util/log" ) // AgentConfig - represents the config for agent @@ -13,31 +12,53 @@ type AgentConfig struct { KongGatewayCfg *KongGatewayConfig `config:"kong"` } +type KongAdminConfig struct { + URL string `config:"url"` + Auth KongAdminAuthConfig `config:"auth"` +} + +type KongAdminAuthConfig struct { + APIKey KongAdminAuthAPIKeyConfig `config:"apikey"` +} + +type KongAdminAuthAPIKeyConfig struct { + Header string `config:"header"` + Value string `config:"value"` +} + +type KongProxyConfig struct { + Host string `config:"host"` + Port KongProxyPortConfig `config:"port"` +} + +type KongProxyPortConfig struct { + HTTP int `config:"http"` + HTTPS int `config:"https"` +} + +type KongSpecConfig struct { + URLPaths []string `config:"urlPaths"` + LocalPath string `config:"localPaths"` +} + // KongGatewayConfig - represents the config for gateway type KongGatewayConfig struct { corecfg.IConfigValidator - AdminEndpoint string `config:"adminEndpoint"` - Token string `config:"token"` - ProxyEndpoint string `config:"proxyEndpoint"` - ProxyHttpPort int `config:"proxyHttpPort"` - ProxyHttpsPort int `config:"proxyHttpsPort"` - SpecDownloadPaths []string `config:"specDownloadPaths"` - SpecLocalPath string `config:"specLocalPath"` + Admin KongAdminConfig `config:"admin"` + Proxy KongProxyConfig `config:"proxy"` + Spec KongSpecConfig `config:"spec"` } // ValidateCfg - Validates the gateway config func (c *KongGatewayConfig) ValidateCfg() (err error) { - if c.AdminEndpoint == "" { - return fmt.Errorf("error: adminEndpoint is required") - } - if c.ProxyEndpoint == "" { - return fmt.Errorf("error: proxyEndpoint is required") + if c.Admin.URL == "" { + return fmt.Errorf("error: admin url is required") } - if c.ProxyHttpPort == 0 && c.ProxyHttpsPort == 0 { - return fmt.Errorf("error: proxyEndpointProtocols requires at least one value of either http or https") + if c.Proxy.Host == "" { + return fmt.Errorf("error: proxy host is required") } - if c.Token == "" { - log.Warn("no token set for authenticating with the kong admin endpoint") + if c.Proxy.Port.HTTP == 0 && c.Proxy.Port.HTTPS == 0 { + return fmt.Errorf("error: at least one proxy port value of either http or https is required") } return } diff --git a/pkg/gateway/centralclient.go b/pkg/gateway/centralclient.go deleted file mode 100644 index ec68625..0000000 --- a/pkg/gateway/centralclient.go +++ /dev/null @@ -1,28 +0,0 @@ -package gateway - -import ( - corecfg "github.com/Axway/agent-sdk/pkg/config" -) - -type CentralAPIClient interface { - ExecuteAPI(method, endpoint string, queryParam map[string]string, buffer []byte) ([]byte, error) -} - -type CentralClient struct { - client CentralAPIClient - envName string - apiServerHost string -} - -func NewCentralClient(client CentralAPIClient, config corecfg.CentralConfig) CentralClient { - return CentralClient{ - client: client, - envName: config.GetEnvironmentName(), - apiServerHost: config.GetAPIServerURL(), - } -} - -func (cc *CentralClient) execute(method, endpoint string, queryParam map[string]string, buffer []byte) ([]byte, error) { - host := cc.apiServerHost + cc.envName + endpoint - return cc.client.ExecuteAPI(method, host, queryParam, buffer) -} diff --git a/pkg/gateway/client.go b/pkg/gateway/client.go index b1e8c05..d8cee07 100644 --- a/pkg/gateway/client.go +++ b/pkg/gateway/client.go @@ -23,8 +23,8 @@ import ( ) const ( - ardCtx = "contextArd" - crdCtx = "contextCrd" + ardCtx log.ContextField = "accessRequestDefinition" + crdCtx log.ContextField = "credentialRequestDefinition" ) func NewClient(agentConfig config.AgentConfig) (*Client, error) { @@ -34,7 +34,6 @@ func NewClient(agentConfig config.AgentConfig) (*Client, error) { if err != nil { return nil, err } - apicClient := NewCentralClient(agent.GetCentralClient(), agentConfig.CentralCfg) daCache := cache.New() logger := log.NewFieldLogger().WithField("component", "agent") @@ -55,7 +54,6 @@ func NewClient(agentConfig config.AgentConfig) (*Client, error) { centralCfg: agentConfig.CentralCfg, kongGatewayCfg: kongGatewayConfig, kongClient: kongClient, - apicClient: apicClient, cache: daCache, mode: common.Marketplace, }, nil @@ -64,7 +62,7 @@ func NewClient(agentConfig config.AgentConfig) (*Client, error) { // Returns no error in case an ACL plugin which is enabled is found func hasACLEnabledInPlugins(plugins []*klib.Plugin) error { for _, plugin := range plugins { - if *plugin.Name == "acl" && *plugin.Enabled == true { + if *plugin.Name == "acl" && *plugin.Enabled { return nil } } @@ -150,9 +148,9 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se log := gc.logger.WithField("service-name", *service.Name) log.Infof("processing service") - proxyEndpoint := gc.kongGatewayCfg.ProxyEndpoint - httpPort := gc.kongGatewayCfg.ProxyHttpPort - httpsPort := gc.kongGatewayCfg.ProxyHttpsPort + proxyHost := gc.kongGatewayCfg.Proxy.Host + httpPort := gc.kongGatewayCfg.Proxy.Port.HTTP + httpsPort := gc.kongGatewayCfg.Proxy.Port.HTTPS routes, err := gc.kongClient.ListRoutesForService(ctx, *service.ID) if err != nil { @@ -188,7 +186,8 @@ func (gc *Client) processSingleKongService(ctx context.Context, service *klib.Se oasSpec := Openapi{ spec: string(kongServiceSpec), } - endpoints := gc.processKongRoute(proxyEndpoint, oasSpec.BasePath(), route, httpPort, httpsPort) + + endpoints := gc.processKongRoute(proxyHost, oasSpec.BasePath(), route, httpPort, httpsPort) serviceBody, err := gc.processKongAPI(ctx, *route.ID, service, oasSpec, endpoints, apiPlugins) if err != nil { return err @@ -225,7 +224,7 @@ func (gc *Client) processKongRoute(defaultHost string, basePath string, route *k } routingBasePath := *path - if *route.StripPath == true { + if *route.StripPath { routingBasePath = routingBasePath + basePath } endpoint := apic.EndpointDefinition{ @@ -353,25 +352,8 @@ func isPublished(api *KongAPI, c cache.Cache) (bool, string) { return true, checksum } -func getFirstAuthPluginArdAndCrd(plugins map[string]*klib.Plugin) (string, string) { - for key := range plugins { - switch key { - case "key-auth": - return provisioning.APIKeyARD, provisioning.APIKeyCRD - case "jwt": - return "jwt", "jwt" - case "basic-auth": - return provisioning.BasicAuthARD, provisioning.BasicAuthCRD - case "oauth2": - return "oauth2", "oauth2" - } - - } - return "", "" -} - func isValidAuthTypeAndEnabled(p *klib.Plugin) bool { - if *p.Enabled != true { + if !*p.Enabled { return false } for _, availableAuthName := range []string{"basic-auth", "oauth2", "key-auth"} { diff --git a/pkg/gateway/client_test.go b/pkg/gateway/client_test.go index 5cfe460..f7c44f1 100644 --- a/pkg/gateway/client_test.go +++ b/pkg/gateway/client_test.go @@ -9,8 +9,12 @@ import ( func TestKongClient(t *testing.T) { gatewayConfig := &config.KongGatewayConfig{ - AdminEndpoint: "http://localhost", - ProxyEndpoint: "http://localhost", + Admin: config.KongAdminConfig{ + URL: "http://localhost", + }, + Proxy: config.KongProxyConfig{ + Host: "localhost", + }, } _ = config.AgentConfig{ CentralCfg: corecfg.NewCentralConfig(corecfg.DiscoveryAgent), diff --git a/pkg/gateway/definitions.go b/pkg/gateway/definitions.go index 5366f2a..2b3acb2 100644 --- a/pkg/gateway/definitions.go +++ b/pkg/gateway/definitions.go @@ -5,10 +5,9 @@ import ( "github.com/Axway/agent-sdk/pkg/cache" corecfg "github.com/Axway/agent-sdk/pkg/config" "github.com/Axway/agent-sdk/pkg/util/log" - "github.com/Axway/agents-kong/pkg/kong" config "github.com/Axway/agents-kong/pkg/config/discovery" - kutil "github.com/Axway/agents-kong/pkg/kong" + "github.com/Axway/agents-kong/pkg/kong" ) type Client struct { @@ -16,8 +15,7 @@ type Client struct { centralCfg corecfg.CentralConfig kongGatewayCfg *config.KongGatewayConfig kongClient kong.KongAPIClient - apicClient CentralClient - plugins kutil.Plugins + plugins kong.Plugins cache cache.Cache mode string } @@ -36,19 +34,8 @@ type KongAPI struct { imageContentType string crds []string apiUpdateSeverity string - serviceAttributes map[string]string agentDetails map[string]string - subscriptionName string tags []string stage string - state string - status string ard string } - -type CachedService struct { - kongServiceId string - kongServiceName string - hash string - centralName string -} diff --git a/pkg/kong/kongclient.go b/pkg/kong/kongclient.go index 1632697..e331023 100644 --- a/pkg/kong/kongclient.go +++ b/pkg/kong/kongclient.go @@ -46,7 +46,6 @@ type KongAPIClient interface { type KongClient struct { *klib.Client - ctx context.Context logger log.FieldLogger baseClient DoRequest kongAdminEndpoint string @@ -56,20 +55,20 @@ type KongClient struct { } func NewKongClient(baseClient *http.Client, kongConfig *config.KongGatewayConfig) (*KongClient, error) { - if kongConfig.Token != "" { + if kongConfig.Admin.Auth.APIKey.Value != "" { defaultTransport := http.DefaultTransport.(*http.Transport) http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} baseClient.Transport = defaultTransport headers := make(http.Header) - headers.Set("Kong-Admin-Token", kongConfig.Token) + headers.Set(kongConfig.Admin.Auth.APIKey.Header, kongConfig.Admin.Auth.APIKey.Value) client := klib.HTTPClientWithHeaders(baseClient, headers) baseClient = client } logger := log.NewFieldLogger().WithComponent("client").WithPackage("kong") - baseKongClient, err := klib.NewClient(&kongConfig.AdminEndpoint, baseClient) + baseKongClient, err := klib.NewClient(&kongConfig.Admin.URL, baseClient) if err != nil { logger.WithError(err).Error("failed to create kong client") return nil, err @@ -78,10 +77,10 @@ func NewKongClient(baseClient *http.Client, kongConfig *config.KongGatewayConfig Client: baseKongClient, logger: log.NewFieldLogger().WithComponent("KongClient").WithPackage("kong"), baseClient: baseClient, - kongAdminEndpoint: kongConfig.AdminEndpoint, - specURLPaths: kongConfig.SpecDownloadPaths, - specLocalPath: kongConfig.SpecLocalPath, - clientTimeout: 10 * time.Second, + kongAdminEndpoint: kongConfig.Admin.URL, + specURLPaths: kongConfig.Spec.URLPaths, + specLocalPath: kongConfig.Spec.LocalPath, + clientTimeout: 60 * time.Second, }, nil } diff --git a/pkg/kong/provisioning.go b/pkg/kong/provisioning.go index c72ccda..a8397b8 100644 --- a/pkg/kong/provisioning.go +++ b/pkg/kong/provisioning.go @@ -311,7 +311,7 @@ func (k KongClient) updateOrDeleteACL(ctx context.Context, aclPlugin *klib.Plugi // enable the plugin in case it is disabled aclPlugin.Enabled = klib.Bool(true) - aclPlugin, err := k.Plugins.UpdateForRoute(ctx, &routeID, aclPlugin) + _, err := k.Plugins.UpdateForRoute(ctx, &routeID, aclPlugin) if err != nil { return err } diff --git a/pkg/kong/provisioning_test.go b/pkg/kong/provisioning_test.go index a6ab25a..fcccc07 100644 --- a/pkg/kong/provisioning_test.go +++ b/pkg/kong/provisioning_test.go @@ -27,7 +27,6 @@ type response struct { } type mockCredentialRequest struct { - id string credType string appName string details string @@ -88,7 +87,9 @@ func createClient(responses map[string]response) KongAPIClient { } })) cfg := &config.KongGatewayConfig{ - AdminEndpoint: s.URL, + Admin: config.KongAdminConfig{ + URL: s.URL, + }, } client, _ := NewKongClient(&http.Client{}, cfg) return client diff --git a/pkg/subscription/access/access.go b/pkg/subscription/access/access.go index 7394da8..2ae9f0a 100644 --- a/pkg/subscription/access/access.go +++ b/pkg/subscription/access/access.go @@ -75,7 +75,7 @@ func (a AccessProvisioner) Provision() (provisioning.RequestStatus, provisioning return rs.SetMessage("route ID not found").Failed(), nil } - if a.quota.GetInterval().String() == provisioning.Weekly.String() { + if a.quota != nil && a.quota.GetInterval().String() == provisioning.Weekly.String() { a.logger.Debug("weekly quota interval is not supported") return rs.SetMessage("weekly quota is not supported by kong").Failed(), nil } @@ -86,6 +86,11 @@ func (a AccessProvisioner) Provision() (provisioning.RequestStatus, provisioning return rs.SetMessage("could not provide access to consumer in kong").Failed(), nil } + if a.quota == nil { + a.logger.Info("provisioned access") + return rs.Success(), nil + } + quotaInterval := a.quota.GetIntervalString() quotaLimit := int(a.quota.GetLimit()) err = a.client.AddQuota(a.ctx, a.routeID, a.appID, quotaInterval, quotaLimit) diff --git a/pkg/subscription/credential/builder.go b/pkg/subscription/credential/builder.go index d54164f..4fd1253 100644 --- a/pkg/subscription/credential/builder.go +++ b/pkg/subscription/credential/builder.go @@ -19,7 +19,6 @@ type kongCredentialBuilder struct { clientSecret *string clientType *string redirectURIs []*string - credMetadata map[string]interface{} } type credentialMetaData struct { diff --git a/pkg/subscription/credential/credential.go b/pkg/subscription/credential/credential.go index 69efbbe..781bd6f 100644 --- a/pkg/subscription/credential/credential.go +++ b/pkg/subscription/credential/credential.go @@ -4,27 +4,17 @@ import ( "context" "github.com/Axway/agent-sdk/pkg/apic/provisioning" - prov "github.com/Axway/agent-sdk/pkg/apic/provisioning" "github.com/Axway/agent-sdk/pkg/util/log" "github.com/Axway/agents-kong/pkg/common" - _ "github.com/kong/go-kong/kong" + "github.com/google/uuid" klib "github.com/kong/go-kong/kong" ) -const ( - reqApiKey = "apiKey" - reqUsername = "username" - reqClientID = "clientId" - reqClientSecret = "clientSecret" -) - type credentialProvisioner struct { - ctx context.Context - client credentialClient - appID string - managedAppName string - logger log.FieldLogger - request credRequest + ctx context.Context + client credentialClient + logger log.FieldLogger + request credRequest } type credentialClient interface { @@ -56,7 +46,7 @@ func NewCredentialProvisioner(ctx context.Context, client credentialClient, req return a } -func (p credentialProvisioner) Deprovision() prov.RequestStatus { +func (p credentialProvisioner) Deprovision() provisioning.RequestStatus { consumerID := p.request.GetApplicationDetailsValue(common.AttrAppID) rs := provisioning.NewRequestStatusBuilder() ctx := context.Background() @@ -93,7 +83,7 @@ func (p credentialProvisioner) Deprovision() prov.RequestStatus { return rs.SetMessage("Failed to identify credential type").Failed() } -func (p credentialProvisioner) Provision() (prov.RequestStatus, prov.Credential) { +func (p credentialProvisioner) Provision() (provisioning.RequestStatus, provisioning.Credential) { consumerID := p.request.GetApplicationDetailsValue(common.AttrAppID) agentTag := "amplify-agent" consumerTags := []*string{&agentTag} @@ -119,8 +109,10 @@ func (p credentialProvisioner) Provision() (prov.RequestStatus, prov.Credential) } case provisioning.BasicAuthARD: { - basicAuth := kongBuilder.WithUsername(""). - WithPassword(""). + user := uuid.NewString() + pass := uuid.NewString() + basicAuth := kongBuilder.WithUsername(user). + WithPassword(pass). ToBasicAuth() resp, err := p.client.CreateHttpBasic(ctx, consumerID, basicAuth) if err != nil { @@ -129,7 +121,7 @@ func (p credentialProvisioner) Provision() (prov.RequestStatus, prov.Credential) rs.AddProperty(common.AttrAppID, *resp.Consumer.ID) rs.AddProperty(common.AttrCredentialID, *resp.ID) rs.AddProperty(common.AttrCredUpdater, *resp.Username) - return rs.Success(), provisioning.NewCredentialBuilder().SetHTTPBasic(*resp.Username, *resp.Password) + return rs.Success(), provisioning.NewCredentialBuilder().SetHTTPBasic(user, pass) } case provisioning.OAuthSecretCRD: { @@ -150,7 +142,7 @@ func (p credentialProvisioner) Provision() (prov.RequestStatus, prov.Credential) return rs.Failed(), nil } -func (p credentialProvisioner) Update() (prov.RequestStatus, prov.Credential) { +func (p credentialProvisioner) Update() (provisioning.RequestStatus, provisioning.Credential) { consumerID := p.request.GetApplicationDetailsValue(common.AttrAppID) agentTag := "amplify-agent" consumerTags := []*string{&agentTag} diff --git a/pkg/subscription/credential/credential_test.go b/pkg/subscription/credential/credential_test.go index 6b17811..747b49f 100644 --- a/pkg/subscription/credential/credential_test.go +++ b/pkg/subscription/credential/credential_test.go @@ -11,11 +11,7 @@ import ( const testName log.ContextField = "testName" -type mockCredentialClient struct { - consumer *klib.Consumer - err bool - kongErr bool -} +type mockCredentialClient struct{} func (mockCredentialClient) DeleteOauth2(ctx context.Context, consumerID, clientID string) error { return nil @@ -41,10 +37,7 @@ func (mockCredentialClient) CreateAuthKey(ctx context.Context, consumerID string return &klib.KeyAuth{}, nil } -type mockCredentialRequest struct { - name string - id string -} +type mockCredentialRequest struct{} func (m *mockCredentialRequest) GetApplicationDetailsValue(key string) string { return "" diff --git a/pkg/subscription/register.go b/pkg/subscription/register.go index c65d11a..c081f06 100644 --- a/pkg/subscription/register.go +++ b/pkg/subscription/register.go @@ -10,7 +10,6 @@ import ( const Oauth2Name = provisioning.OAuthSecretCRD const HttpBasicName = provisioning.BasicAuthARD const ApiKeyName = provisioning.APIKeyARD -const propertyName = "kong-api-key" func getCredTypes() []string { return []string{"confidential", "public"} @@ -19,7 +18,6 @@ func getCredTypes() []string { func registerOauth2() { oAuthRedirects := getAuthRedirectSchemaPropertyBuilder() corsProp := getCorsSchemaPropertyBuilder() - provisionKey := getProvisionKeyPropertyBuilder() oAuthTypeProp := provisioning.NewSchemaPropertyBuilder(). SetName(common.ApplicationTypeField). SetRequired(). @@ -29,7 +27,7 @@ func registerOauth2() { _, err := agent.NewAccessRequestBuilder().SetName(Oauth2Name).Register() if err != nil { - logrus.Errorf("Error registering Oauth2 Access Request %v", err) + logrus.Errorf("Error registering Oauth2 Access Request %v", err) } _, err = agent.NewOAuthCredentialRequestBuilder( @@ -41,14 +39,7 @@ func registerOauth2() { agent.WithCRDIsSuspendable(), ).Register() if err != nil { - logrus.Errorf("Error registering Oauth2 credential Request %v", err) - } - - _, err = agent.NewOAuthCredentialRequestBuilder(agent.WithCRDRequestSchemaProperty(corsProp), - agent.WithCRDProvisionSchemaProperty(provisionKey)).SetName(Oauth2Name).IsRenewable().Register() - if err != nil { - logrus.Errorf("Error registering Oauth2 credential Request %v", err) - + logrus.Errorf("Error registering Oauth2 credential Request %v", err) } } @@ -67,16 +58,11 @@ func registerBasicAuth() { func registerKeyAuth() { //"The api key. Leave empty for autogeneration" corsProp := getCorsSchemaPropertyBuilder() - apiKeyProp := provisioning.NewSchemaPropertyBuilder(). - SetName(ApiKeyName). - SetLabel(propertyName). - SetDescription("The api key. Leave empty for auto generation"). - IsString() _, err := agent.NewAPIKeyAccessRequestBuilder().SetName(ApiKeyName).Register() if err != nil { logrus.Error("Error registering API key Access Request") } - _, err = agent.NewAPIKeyCredentialRequestBuilder(agent.WithCRDProvisionSchemaProperty(apiKeyProp), agent.WithCRDRequestSchemaProperty(corsProp)).IsRenewable().Register() + _, err = agent.NewAPIKeyCredentialRequestBuilder(agent.WithCRDRequestSchemaProperty(corsProp)).IsRenewable().Register() if err != nil { logrus.Error("Error registering API Credential Access Request") } @@ -103,11 +89,3 @@ func getCorsSchemaPropertyBuilder() provisioning.PropertyBuilder { SetName("Origins"). IsString()) } - -func getProvisionKeyPropertyBuilder() provisioning.PropertyBuilder { - return provisioning.NewSchemaPropertyBuilder(). - SetName(common.ProvisionKey). - SetLabel("Provision key"). - SetRequired(). - IsString() -}