Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/actions/deploy/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ cd - && kustomize build config/dev | kubectl apply -f -

# Ensuring the Atlas credentials Secret
kubectl delete secrets my-atlas-key --ignore-not-found -n "${ns}"
kubectl create secret generic my-atlas-key --from-literal="orgId=${INPUT_ATLAS_ORG_ID}" --from-literal="publicApiKey=${INPUT_ATLAS_PUBLIC_KEY}" --from-literal="privateApiKey=${INPUT_ATLAS_PRIVATE_KEY}" -n mongodb-atlas-kubernetes-system
kubectl create secret generic my-atlas-key --from-literal="orgId=${INPUT_ATLAS_ORG_ID}" --from-literal="publicApiKey=${INPUT_ATLAS_PUBLIC_KEY}" --from-literal="privateApiKey=${INPUT_ATLAS_PRIVATE_KEY}" -n "${ns}"

# Wait for the Operator to start
cmd="while ! kubectl -n ${ns} get pods -l control-plane=controller-manager -o jsonpath={.items[0].status.phase} 2>/dev/null | grep -q Running ; do printf .; sleep 1; done"
Expand Down
3 changes: 3 additions & 0 deletions .github/actions/gen-install-scripts/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ inputs:
IMAGE_URL:
description: "Operator image"
required: true
ENV:
description: "Kustomize patch name (enviroment configuration patch)"
required: true
runs:
using: 'docker'
image: 'Dockerfile'
6 changes: 3 additions & 3 deletions .github/actions/gen-install-scripts/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#!/bin/sh

target_dir="deploy"
mkdir "${target_dir}"
mkdir -p "${target_dir}"

# Generate configuration and save it to `all-in-one`
controller-gen crd:crdVersions=v1 rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases
cd config/manager && kustomize edit set image controller="${INPUT_IMAGE_URL}"
cd - && kustomize build config/default > "${target_dir}"/all-in-one.yaml
cd - && kustomize build "config/${INPUT_ENV}" > "${target_dir}/all-in-one.yaml"

cat "${target_dir}"/all-in-one.yaml
cat "${target_dir}/all-in-one.yaml"
5 changes: 1 addition & 4 deletions .github/workflows/push-image.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
# Triggered by Pull Request or Manually (from GitHub UI) events
# TODO remove after removing scripts/e2e_local.sh

name: Publish image to Registry

on:
pull_request:
push:
branches:
- main
workflow_dispatch:

jobs:
Expand Down
96 changes: 96 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ jobs:
- run: go version
- name: Run testing
run: CGO_ENABLED=0 go test -v $(go list ./pkg/...)

int-test:
name: Integration tests
runs-on: ubuntu-latest
Expand All @@ -43,3 +44,98 @@ jobs:
ATLAS_PUBLIC_KEY: ${{ secrets.ATLAS_PUBLIC_KEY }}
ATLAS_PRIVATE_KEY: ${{ secrets.ATLAS_PRIVATE_KEY }}

prepare-e2e:
name: Prepare E2E configuration and image
needs: [unit-test]
runs-on: ubuntu-latest
steps:

- name: Check out code
uses: actions/checkout@v2.3.1

- name: Prepare tag
id: prepare
uses: ./.github/actions/set-tag

- name: Push Atlas Operator to Registry
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems, that if we push the dev image here - there's no need in the "Publish image to Registry" workflow?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed push trigger from build image workflow, but I would like to leave this workflow for a while until I am sure that e2e are stable

uses: docker/build-push-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
repository: ${{ secrets.DOCKER_REPO }}
registry: ${{ secrets.DOCKER_REGISTRY }}
tags: ${{ steps.prepare.outputs.tag }}

e2e:
name: E2E tests
needs: prepare-e2e
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# k8s: ["1.17-kind", "1.19-kind", "1.17-opeshift"] # <supported platform version>-<platform>
k8s: ["v1.18.15-kind"] # <K8sGitVersion>-<Platform>
test: ["all-in-one"] # TODO refactor
steps:

- name: Check out code
uses: actions/checkout@v2.3.1

- name: Prepare tag
id: prepare
uses: ./.github/actions/set-tag

- name: Generate configuration for the tests
uses: ./.github/actions/gen-install-scripts
with:
IMAGE_URL: ${{ secrets.DOCKER_REPO }}:${{ steps.prepare.outputs.tag }}
ENV: dev

- name: Set properties
id: properties
run: |
version=$(echo ${{ matrix.k8s }} | awk -F "-" '{print $1}')
platform=$(echo ${{ matrix.k8s }} | awk -F "-" '{print $2}')
echo "::set-output name=k8s_version::$version"
echo "::set-output name=k8s_platform::$platform"

# run if platform = kind #TODO
- name: Create k8s Kind Cluster
if: ${{ steps.properties.outputs.k8s_platform == 'kind' && !env.ACT }}
uses: helm/kind-action@v1.1.0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good to know there is an action for Kind already!

with:
node_image: kindest/node:${{ steps.properties.outputs.k8s_version }}
cluster_name: ${{ matrix.k8s }}

- name: Setup Go
if: ${{ steps.properties.outputs.k8s_platform == 'kind' && !env.ACT }}
uses: actions/setup-go@v2
with:
go-version: '1.15.6'

- name: Install MongoCLI
run: |
sudo apt-get update
sudo apt-get install -y mongocli
mongocli --version

- name: Run e2e test
if: ${{ steps.properties.outputs.k8s_platform == 'kind' && !env.ACT }}
env:
MCLI_PUBLIC_API_KEY: ${{ secrets.ATLAS_PUBLIC_KEY }}
MCLI_PRIVATE_API_KEY: ${{ secrets.ATLAS_PRIVATE_KEY }}
MCLI_ORG_ID: ${{ secrets.ATLAS_ORG_ID}}
MCLI_OPS_MANAGER_URL: "https://cloud-qa.mongodb.com/"
K8S_PLATFORM: "${{ steps.properties.outputs.k8s_platform }}"
K8S_VERSION: "${{ steps.properties.outputs.k8s_version }}"
TEST_NAME: "${{ matrix.test }}"
run: |
kubectl version

go version
go get github.com/onsi/ginkgo/ginkgo && \
go get github.com/onsi/gomega/...
ginkgo ./test/e2e -x -focus "${TEST_NAME}"


# TODO if int test failed - stop e2e, add job for cleanup Atlas projects/clusters
4 changes: 4 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,9 @@ issues:
linters:
- gochecknoglobals
- wrapcheck
- path: test/e2e
linters:
- errcheck
- stylecheck
max-issues-per-linter: 0
max-same-issues: 0
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ int-test: generate manifests ## Run integration tests
test -f $(ENVTEST_ASSETS_DIR)/setup-envtest.sh || curl -sSLo $(ENVTEST_ASSETS_DIR)/setup-envtest.sh https://raw.githubusercontent.com/kubernetes-sigs/controller-runtime/v0.8.0/hack/setup-envtest.sh
source $(ENVTEST_ASSETS_DIR)/setup-envtest.sh; fetch_envtest_tools $(ENVTEST_ASSETS_DIR); setup_envtest_env $(ENVTEST_ASSETS_DIR); ginkgo -v -p -nodes=4 ./test/int -coverprofile cover.out

.PHONY: e2e
e2e: run-kind
./scripts/e2e_local.sh

.PHONY: manager
manager: generate fmt vet ## Build manager binary
go build -o bin/manager main.go
Expand Down
2 changes: 1 addition & 1 deletion config/dev/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

namespace: mongodb-atlas-kubernetes-system

resources:
- ../default
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ require (
github.com/google/go-cmp v0.5.4
github.com/mongodb-forks/digest v1.0.2
github.com/onsi/ginkgo v1.14.2
github.com/pborman/uuid v1.2.0
github.com/onsi/gomega v1.10.5
github.com/stretchr/testify v1.7.0
go.mongodb.org/atlas v0.7.1
go.uber.org/multierr v1.6.0 // indirect
go.uber.org/zap v1.16.0
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
k8s.io/api v0.18.6
k8s.io/apimachinery v0.18.6
k8s.io/client-go v0.18.6
Expand Down
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ=
github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48=
github.com/openlyinc/pointy v1.1.2 h1:LywVV2BWC5Sp5v7FoP4bUD+2Yn5k0VNeRbU5vq9jUMY=
github.com/openlyinc/pointy v1.1.2/go.mod h1:w2Sytx+0FVuMKn37xpXIAyBNhFNBIJGR/v2m7ik1WtM=
github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
Expand Down
18 changes: 18 additions & 0 deletions scripts/e2e_local.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/sh
act -j build-push

public_key=$(grep "ATLAS_PUBLIC_KEY" .actrc | cut -d "=" -f 2)
private_key=$(grep "ATLAS_PRIVATE_KEY" .actrc | cut -d "=" -f 2)
org_id=$(grep "ATLAS_ORG_ID" .actrc | cut -d "=" -f 2)
image=$(grep "DOCKER_REPO" .actrc | cut -d "=" -f 2):$(git rev-parse --abbrev-ref HEAD)-$(git rev-parse --short HEAD)

export MCLI_OPS_MANAGER_URL="https://cloud-qa.mongodb.com/"
export MCLI_PUBLIC_API_KEY="${public_key}"
export MCLI_PRIVATE_API_KEY="${private_key}"
export MCLI_ORG_ID="${org_id}"
export INPUT_IMAGE_URL="${image}"
export INPUT_ENV=dev

./.github/actions/gen-install-scripts/entrypoint.sh

ginkgo -v -x test/e2e
15 changes: 15 additions & 0 deletions test/e2e/cli/cli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package cli

import (
"os/exec"

. "github.com/onsi/ginkgo"
"github.com/onsi/gomega/gexec"
)

func Execute(command string, args ...string) *gexec.Session {
// GinkgoWriter.Write([]byte("\n " + command + " " + strings.Join(args, " "))) // TODO for the local run only
cmd := exec.Command(command, args...)
session, _ := gexec.Start(cmd, GinkgoWriter, GinkgoWriter)
return session
}
73 changes: 73 additions & 0 deletions test/e2e/cli/kube/kubectl.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package kube

import (
"fmt"
"strings"

"encoding/json"

. "github.com/onsi/gomega"
. "github.com/onsi/gomega/gbytes"

v1 "github.com/mongodb/mongodb-atlas-kubernetes/pkg/api/v1"
cli "github.com/mongodb/mongodb-atlas-kubernetes/test/e2e/cli"
)

// GenKubeVersion
func GenKubeVersion(fullVersion string) string {
version := strings.Split(fullVersion, ".")
return fmt.Sprintf("Major:\"%s\", Minor:\"%s\"", version[0], version[1])
}

// GetPodStatus status.phase
func GetPodStatus(ns string) func() string {
return func() string {
session := cli.Execute("kubectl", "get", "pods", "-l", "control-plane=controller-manager", "-o", "jsonpath={.items[0].status.phase}", "-n", ns)
return string(session.Wait("1m").Out.Contents())
}
}

// GetGeneration .status.observedGeneration
func GetGeneration(ns string) func() string {
return func() string {
session := cli.Execute("kubectl", "get", "atlascluster.atlas.mongodb.com/atlascluster-sample", "-n", ns, "-o", "jsonpath={.status.observedGeneration}")
return string(session.Wait("1m").Out.Contents())
}
}

// GetStatusCondition .status.conditions.type=Ready.status
func GetStatusCondition(ns string, atlasname string) func() string {
return func() string {
session := cli.Execute("kubectl", "get", atlasname, "-n", ns, "-o", "jsonpath={.status.conditions[?(@.type=='Ready')].status}")
return string(session.Wait("1m").Out.Contents())
}
}

// GetProjectResource
func GetProjectResource(namespace, rName string) v1.AtlasProject {
session := cli.Execute("kubectl", "get", rName, "-n", namespace, "-o", "json")
output := session.Wait("1m").Out.Contents()
var project v1.AtlasProject
ExpectWithOffset(1, json.Unmarshal(output, &project)).ShouldNot(HaveOccurred())
return project
}

// GetClusterResource
func GetClusterResource(namespace, rName string) v1.AtlasCluster {
session := cli.Execute("kubectl", "get", rName, "-n", namespace, "-o", "json")
output := session.Wait("1m").Out.Contents()
var cluster v1.AtlasCluster
ExpectWithOffset(1, json.Unmarshal(output, &cluster)).ShouldNot(HaveOccurred())
return cluster
}

func GetK8sClusterStateName(ns, rName string) func() string {
return func() string {
return GetClusterResource(ns, rName).Status.StateName
}
}

func DeleteNamespace(ns string) *Buffer {
session := cli.Execute("kubectl", "delete", "namespace", ns)
return session.Wait().Out
}
Loading