Skip to content

Commit

Permalink
Upgrade to operator-sdk 1.0 (#167)
Browse files Browse the repository at this point in the history
Upgrade according to https://sdk.operatorframework.io/docs/building-operators/golang/project_migration_guide/

Outstanding issues that were solved

Effectively it is completely new project structure and engine, the logic was cherry-picked and migrated step by step in multiple places
DepResolver introduced some dependency hell, we included env.go from kuberentes utils right in the codebase
Invalid memory nil pointer access was solved by adopting of depresolver to new style of GslbReconciler initialization
Adapt to new reconciliation related method signatures
Adapt to new logging style
Upstream/k8gb Makefile merge
Unit test fixes - controller runtime fake client changed its behaviour in treating object versions
Terratest fixes
Github actions changes
Resolves #166

All tests are passing.
  • Loading branch information
ytsarev authored Oct 5, 2020
1 parent bad735c commit d0af222
Show file tree
Hide file tree
Showing 89 changed files with 2,239 additions and 1,430 deletions.
8 changes: 2 additions & 6 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,12 @@ jobs:
- uses: actions/checkout@v1
- name: Operator image build and push
env:
OPERATOR_SDK_VERSION: v0.16.0
DOCKER_USER: ${{ secrets.DOCKER_USER }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
run: |
wget https://github.com/operator-framework/operator-sdk/releases/download/${OPERATOR_SDK_VERSION}/operator-sdk-${OPERATOR_SDK_VERSION}-x86_64-linux-gnu -O ./operator-sdk
chmod +x ./operator-sdk
export PATH=.:$PATH
docker login -u "${DOCKER_USER}" -p "${DOCKER_PASSWORD}"
make build
make push
make docker-build
make docker-push
- uses: dave-mcconnell/helm-gh-pages-microservices@master
with:
access-token: ${{ secrets.CR_TOKEN }}
Expand Down
4 changes: 0 additions & 4 deletions .github/workflows/terratest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ jobs:
NODE_ROLE: control-plane
TEST_CURRENT_COMMIT: yes
run: |
OPERATOR_SDK_VERSION=v0.16.0
wget https://github.com/operator-framework/operator-sdk/releases/download/${OPERATOR_SDK_VERSION}/operator-sdk-${OPERATOR_SDK_VERSION}-x86_64-linux-gnu -O ./operator-sdk
chmod +x ./operator-sdk
export PATH=.:$PATH
export VERSION=$(make version)
./deploy/full.sh
kubectl get pods -A
Expand Down
25 changes: 25 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,28 @@

# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
bin

# Test binary, build with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Kubernetes Generated files - skip generated files, except for vendored files

!vendor/**/zz_generated.*

# editor and IDE paraphernalia
.idea
*.swp
*.swo
*~

# Temporary Build Files
build/_output
build/_test
Expand Down
27 changes: 27 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Build the manager binary
FROM golang:1.13 as builder

WORKDIR /workspace
# Copy the Go Modules manifests
COPY go.mod go.mod
COPY go.sum go.sum
# cache deps before building and copying source so that we don't need to re-download as much
# and so that source changes don't invalidate our downloaded layer
RUN go mod download

# Copy the go source
COPY main.go main.go
COPY api/ api/
COPY controllers/ controllers/

# Build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -a -o manager main.go

# Use distroless as minimal base image to package the manager binary
# Refer to https://github.com/GoogleContainerTools/distroless for more details
FROM gcr.io/distroless/static:nonroot
WORKDIR /
COPY --from=builder /workspace/manager .
USER nonroot:nonroot

ENTRYPOINT ["/manager"]
153 changes: 127 additions & 26 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,128 @@
REPO ?= absaoss/k8gb
# Current Operator version
VERSION ?= $$(helm show chart chart/k8gb/|awk '/appVersion:/ {print $$2}')
K8GB_IMAGE_TAG ?= v$(VERSION)
# Default bundle image tag
BUNDLE_IMG ?= controller-bundle:$(VERSION)
# Options for 'bundle-build'
ifneq ($(origin CHANNELS), undefined)
BUNDLE_CHANNELS := --channels=$(CHANNELS)
endif
ifneq ($(origin DEFAULT_CHANNEL), undefined)
BUNDLE_DEFAULT_CHANNEL := --default-channel=$(DEFAULT_CHANNEL)
endif
BUNDLE_METADATA_OPTS ?= $(BUNDLE_CHANNELS) $(BUNDLE_DEFAULT_CHANNEL)

# Image URL to use all building/pushing image targets
IMG ?= $(REPO):$(K8GB_IMAGE_TAG)
# Produce CRDs that work back to Kubernetes 1.11 (no version conversion)
CRD_OPTIONS ?= "crd:trivialVersions=true"

# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN))
GOBIN=$(shell go env GOPATH)/bin
else
GOBIN=$(shell go env GOBIN)
endif

all: manager

# Run tests
test: generate fmt vet manifests
go test ./... -coverprofile cover.out

# Build manager binary
manager: generate fmt vet
go build -o bin/manager main.go

# Run against the configured Kubernetes cluster in ~/.kube/config
run: generate fmt vet manifests
go run ./main.go

# Install CRDs into a cluster
install: manifests kustomize
$(KUSTOMIZE) build config/crd | kubectl apply -f -

# Uninstall CRDs from a cluster
uninstall: manifests kustomize
$(KUSTOMIZE) build config/crd | kubectl delete -f -

# Deploy controller in the configured Kubernetes cluster in ~/.kube/config
deploy: manifests kustomize
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
$(KUSTOMIZE) build config/default | kubectl apply -f -

# Generate manifests e.g. CRD, RBAC etc.
manifests: controller-gen
$(CONTROLLER_GEN) $(CRD_OPTIONS) rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases

# Run go fmt against code
fmt:
go fmt ./...

# Run go vet against code
vet:
go vet ./...

# Generate code
generate: controller-gen
$(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..."

# Build the docker image
docker-build: test
docker build . -t ${IMG}

# Push the docker image
docker-push:
docker push ${IMG}

# find or download controller-gen
# download controller-gen if necessary
controller-gen:
ifeq (, $(shell which controller-gen))
@{ \
set -e ;\
CONTROLLER_GEN_TMP_DIR=$$(mktemp -d) ;\
cd $$CONTROLLER_GEN_TMP_DIR ;\
go mod init tmp ;\
go get sigs.k8s.io/controller-tools/cmd/controller-gen@v0.3.0 ;\
rm -rf $$CONTROLLER_GEN_TMP_DIR ;\
}
CONTROLLER_GEN=$(GOBIN)/controller-gen
else
CONTROLLER_GEN=$(shell which controller-gen)
endif

kustomize:
ifeq (, $(shell which kustomize))
@{ \
set -e ;\
KUSTOMIZE_GEN_TMP_DIR=$$(mktemp -d) ;\
cd $$KUSTOMIZE_GEN_TMP_DIR ;\
go mod init tmp ;\
go get sigs.k8s.io/kustomize/kustomize/v3@v3.5.4 ;\
rm -rf $$KUSTOMIZE_GEN_TMP_DIR ;\
}
KUSTOMIZE=$(GOBIN)/kustomize
else
KUSTOMIZE=$(shell which kustomize)
endif

# Generate bundle manifests and metadata, then validate generated files.
.PHONY: bundle
bundle: manifests
operator-sdk generate kustomize manifests -q
cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG)
$(KUSTOMIZE) build config/manifests | operator-sdk generate bundle -q --overwrite --version $(VERSION) $(BUNDLE_METADATA_OPTS)
operator-sdk bundle validate ./bundle

# Build the bundle image.
.PHONY: bundle-build
bundle-build:
docker build -f bundle.Dockerfile -t $(BUNDLE_IMG) .

## Special k8gb make part

VALUES_YAML ?= chart/k8gb/values.yaml
HELM_ARGS ?=
ETCD_DEBUG_IMAGE ?= quay.io/coreos/etcd:v3.2.25
Expand All @@ -11,12 +134,6 @@ K8GB_IMAGE_TAG ?= v$(VERSION)
K8GB_COREDNS_IP ?= kubectl get svc k8gb-coredns -n k8gb -o custom-columns='IP:spec.clusterIP' --no-headers
PODINFO_IMAGE_REPO ?= stefanprodan/podinfo

.PHONY: up-local
up-local: create-test-ns
kubectl apply -f ./deploy/crds/k8gb.absa.oss_gslbs_crd.yaml
kubectl apply -f ./deploy/crds/k8gb.absa.oss_v1beta1_gslb_cr.yaml
operator-sdk run --local --namespace=test-gslb

.PHONY: debug-local
debug-local: create-test-ns
kubectl apply -f ./deploy/crds/k8gb.absa.oss_gslbs_crd.yaml
Expand All @@ -25,22 +142,14 @@ debug-local: create-test-ns

.PHONY: lint
lint:
staticcheck ./pkg/... ./cmd/...
errcheck ./pkg/... ./cmd/...
golint '-set_exit_status=1' pkg/controller/... cmd/manager/...

.PHONY: test
test:
go test -v ./...
staticcheck ./...
errcheck ./...
golint '-set_exit_status=1' ./...

.PHONY: terratest
terratest:
cd terratest/test/ && go mod download && go test -v

.PHONY: e2e-test
e2e-test: deploy-gslb-operator
operator-sdk test local ./pkg/test --no-setup --namespace k8gb

.PHONY: dns-tools
dns-tools:
kubectl -n k8gb get svc k8gb-coredns
Expand Down Expand Up @@ -101,7 +210,7 @@ create-test-ns:

.PHONY: deploy-local-ingress
deploy-local-ingress: create-k8gb-ns
helm repo add stable https://kubernetes-charts.storage.googleapis.com
helm repo add --force-update stable https://kubernetes-charts.storage.googleapis.com
helm repo update
helm -n k8gb upgrade -i nginx-ingress stable/nginx-ingress --version 1.41.1 -f deploy/ingress/nginx-ingress-values.yaml

Expand Down Expand Up @@ -141,14 +250,6 @@ clean-test-apps:
helm -n test-gslb uninstall backend
helm -n test-gslb uninstall frontend

.PHONY: build
build:
operator-sdk build $(K8GB_IMAGE_REPO):$(K8GB_IMAGE_TAG)

.PHONY: push
push:
docker push $(K8GB_IMAGE_REPO):$(K8GB_IMAGE_TAG)

.PHONY: debug-test-etcd
debug-test-etcd:
kubectl run --rm -i --tty --env="ETCDCTL_API=3" --env="ETCDCTL_ENDPOINTS=http://etcd-cluster-client:2379" --namespace k8gb etcd-test --image "$(ETCD_DEBUG_IMAGE)" --restart=Never -- /bin/sh
Expand Down
11 changes: 11 additions & 0 deletions PROJECT
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
domain: absa.oss
layout: go.kubebuilder.io/v2
projectName: k8gb
repo: github.com/AbsaOSS/k8gb
resources:
- group: k8gb
kind: Gslb
version: v1beta1
version: 3-alpha
plugins:
go.sdk.operatorframework.io/v2-alpha: {}
36 changes: 36 additions & 0 deletions api/v1beta1/groupversion_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package v1beta1 contains API Schema definitions for the k8gb v1beta1 API group
// +kubebuilder:object:generate=true
// +groupName=k8gb.absa.oss
package v1beta1

import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/scheme"
)

var (
// GroupVersion is group version used to register these objects
GroupVersion = schema.GroupVersion{Group: "k8gb.absa.oss", Version: "v1beta1"}

// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}

// AddToScheme adds the types in this group-version to the given scheme.
AddToScheme = SchemeBuilder.AddToScheme
)
32 changes: 22 additions & 10 deletions pkg/apis/k8gb/v1beta1/gslb_types.go → api/v1beta1/gslb_types.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package v1beta1

import (
Expand All @@ -23,29 +39,25 @@ type Strategy struct {
// +k8s:openapi-gen=true
type GslbSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "operator-sdk generate k8s" to regenerate code after modifying this file
// Add custom validation using kubebuilder tags: https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html
// Important: Run "make" to regenerate code after modifying this file

Ingress v1beta1.IngressSpec `json:"ingress"`
Strategy Strategy `json:"strategy"`
}

// GslbStatus defines the observed state of Gslb
// +k8s:openapi-gen=true
type GslbStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "operator-sdk generate k8s" to regenerate code after modifying this file
// Add custom validation using kubebuilder tags: https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html
// Important: Run "make" to regenerate code after modifying this file
ServiceHealth map[string]string `json:"serviceHealth"`
HealthyRecords map[string][]string `json:"healthyRecords"`
GeoTag string `json:"geoTag"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status

// Gslb is the Schema for the gslbs API
// +k8s:openapi-gen=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:path=gslbs,scope=Namespaced
type Gslb struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Expand All @@ -54,7 +66,7 @@ type Gslb struct {
Status GslbStatus `json:"status,omitempty"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +kubebuilder:object:root=true

// GslbList contains a list of Gslb
type GslbList struct {
Expand Down
Loading

0 comments on commit d0af222

Please sign in to comment.