Added base for envtests

This commit is contained in:
Sylwia Brant 2021-01-20 15:46:39 +01:00
parent cb26623f5f
commit b6bf47b949
6 changed files with 337 additions and 4 deletions

View File

@ -173,7 +173,7 @@ install: ## Installs the executable
.PHONY: run .PHONY: run
run: export WATCH_NAMESPACE = $(NAMESPACE) run: export WATCH_NAMESPACE = $(NAMESPACE)
run: export OPERATOR_NAME = $(NAME) run: export OPERATOR_NAME = $(NAME)
run: fmt vet manifests install build ## Run the executable, you can use EXTRA_ARGS run: fmt vet manifests install-crds build ## Run the executable, you can use EXTRA_ARGS
@echo "+ $@" @echo "+ $@"
ifeq ($(KUBERNETES_PROVIDER),minikube) ifeq ($(KUBERNETES_PROVIDER),minikube)
kubectl config use-context $(KUBECTL_CONTEXT) kubectl config use-context $(KUBECTL_CONTEXT)
@ -422,7 +422,7 @@ generate-docs: ## Re-generate docs directory from the website directory
##################### FROM OPERATOR SDK ######################## ##################### FROM OPERATOR SDK ########################
#TODO rename #TODO rename
# Install CRDs into a cluster # Install CRDs into a cluster
install: manifests kustomize install-crds: manifests kustomize
$(KUSTOMIZE) build config/crd | kubectl apply -f - $(KUSTOMIZE) build config/crd | kubectl apply -f -
# Uninstall CRDs from a cluster # Uninstall CRDs from a cluster
@ -473,3 +473,10 @@ bundle: manifests kustomize
.PHONY: bundle-build .PHONY: bundle-build
bundle-build: bundle-build:
docker build -f bundle.Dockerfile -t $(BUNDLE_IMG) . docker build -f bundle.Dockerfile -t $(BUNDLE_IMG) .
#FIXME temporary target for running tests (test used above for go test)
ENVTEST_ASSETS_DIR=$(shell pwd)/testbin
testing: generate fmt vet manifests
mkdir -p ${ENVTEST_ASSETS_DIR}
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.7.0/hack/setup-envtest.sh
source ${ENVTEST_ASSETS_DIR}/setup-envtest.sh; fetch_envtest_tools $(ENVTEST_ASSETS_DIR); setup_envtest_env $(ENVTEST_ASSETS_DIR); go test ./... -coverprofile cover.out

170
controllers/jenkins.go Normal file
View File

@ -0,0 +1,170 @@
package controllers
import (
"github.com/jenkinsci/kubernetes-operator/api/v1alpha2"
"github.com/jenkinsci/kubernetes-operator/pkg/configuration/base/resources"
"github.com/jenkinsci/kubernetes-operator/pkg/constants"
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
)
const (
userConfigurationConfigMapName = "user-config"
userConfigurationSecretName = "user-secret"
)
type seedJobConfig struct {
v1alpha2.SeedJob
JobNames []string `json:"jobNames,omitempty"`
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
PrivateKey string `json:"privateKey,omitempty"`
}
var (
jenkinsCRName = "jenkins-example"
namespace = "default"
priorityClassName = ""
mySeedJob = seedJobConfig{
SeedJob: v1alpha2.SeedJob{
ID: "jenkins-operator",
CredentialID: "jenkins-operator",
JenkinsCredentialType: v1alpha2.NoJenkinsCredentialCredentialType,
Targets: "cicd/jobs/*.jenkins",
Description: "Jenkins Operator repository",
RepositoryBranch: "master",
RepositoryURL: "https://github.com/jenkinsci/kubernetes-operator.git",
PollSCM: "1 1 1 1 1",
UnstableOnDeprecation: true,
BuildPeriodically: "1 1 1 1 1",
FailOnMissingPlugin: true,
IgnoreMissingFiles: true,
//AdditionalClasspath: can fail with the seed job agent
GitHubPushTrigger: true,
},
}
groovyScripts = v1alpha2.GroovyScripts{
Customization: v1alpha2.Customization{
Configurations: []v1alpha2.ConfigMapRef{
{
Name: userConfigurationConfigMapName,
},
},
Secret: v1alpha2.SecretRef{
Name: userConfigurationSecretName,
},
},
}
casc = v1alpha2.ConfigurationAsCode{
Customization: v1alpha2.Customization{
Configurations: []v1alpha2.ConfigMapRef{
{
Name: userConfigurationConfigMapName,
},
},
Secret: v1alpha2.SecretRef{
Name: userConfigurationSecretName,
},
},
}
)
func createJenkinsCR(name, namespace string, seedJob *[]v1alpha2.SeedJob, groovyScripts v1alpha2.GroovyScripts, casc v1alpha2.ConfigurationAsCode, priorityClassName string) *v1alpha2.Jenkins {
var seedJobs []v1alpha2.SeedJob
if seedJob != nil {
seedJobs = append(seedJobs, *seedJob...)
}
jenkins := &v1alpha2.Jenkins{
TypeMeta: v1alpha2.JenkinsTypeMeta(),
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
Spec: v1alpha2.JenkinsSpec{
GroovyScripts: groovyScripts,
ConfigurationAsCode: casc,
Master: v1alpha2.JenkinsMaster{
Annotations: map[string]string{"test": "label"},
Containers: []v1alpha2.Container{
{
Name: resources.JenkinsMasterContainerName,
Env: []corev1.EnvVar{
{
Name: "TEST_ENV",
Value: "test_env_value",
},
},
ReadinessProbe: &corev1.Probe{
Handler: corev1.Handler{
HTTPGet: &corev1.HTTPGetAction{
Path: "/login",
Port: intstr.FromString("http"),
Scheme: corev1.URISchemeHTTP,
},
},
InitialDelaySeconds: int32(80),
TimeoutSeconds: int32(4),
FailureThreshold: int32(10),
},
LivenessProbe: &corev1.Probe{
Handler: corev1.Handler{
HTTPGet: &corev1.HTTPGetAction{
Path: "/login",
Port: intstr.FromString("http"),
Scheme: corev1.URISchemeHTTP,
},
},
InitialDelaySeconds: int32(80),
TimeoutSeconds: int32(4),
FailureThreshold: int32(10),
},
VolumeMounts: []corev1.VolumeMount{
{
Name: "plugins-cache",
MountPath: "/usr/share/jenkins/ref/plugins",
},
},
},
{
Name: "envoyproxy",
Image: "envoyproxy/envoy-alpine:v1.14.1",
},
},
Plugins: []v1alpha2.Plugin{
{Name: "audit-trail", Version: "3.7"},
{Name: "simple-theme-plugin", Version: "0.6"},
{Name: "github", Version: "1.32.0"},
{Name: "devoptics", Version: "1.1905", DownloadURL: "https://jenkins-updates.cloudbees.com/download/plugins/devoptics/1.1905/devoptics.hpi"},
},
PriorityClassName: priorityClassName,
NodeSelector: map[string]string{"kubernetes.io/os": "linux"},
Volumes: []corev1.Volume{
{
Name: "plugins-cache",
VolumeSource: corev1.VolumeSource{
EmptyDir: &corev1.EmptyDirVolumeSource{},
},
},
},
},
SeedJobs: seedJobs,
Service: v1alpha2.Service{
Type: corev1.ServiceTypeNodePort,
Port: constants.DefaultHTTPPortInt32,
},
},
}
jenkins.Spec.Roles = []rbacv1.RoleRef{
{
APIGroup: "rbac.authorization.k8s.io",
Kind: "Role",
Name: resources.GetResourceName(jenkins),
},
}
return jenkins
}

View File

@ -0,0 +1,40 @@
/*
Copyright 2021.
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 controllers
import (
"context"
"github.com/jenkinsci/kubernetes-operator/api/v1alpha2"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
// +kubebuilder:scaffold:imports
)
// These tests use Ginkgo (BDD-style Go testing framework). Refer to
// http://onsi.github.io/ginkgo/ to learn more about Ginkgo.
var _ = Describe("Jenkins controller", func() {
Describe("deploying Jenkins CR into a cluster", func() {
Context("when deploying CR to cluster", func() {
It("create Jenkins instance", func() {
ctx := context.Background()
jenkins := createJenkinsCR(jenkinsCRName, namespace, &[]v1alpha2.SeedJob{mySeedJob.SeedJob}, groovyScripts, casc, priorityClassName)
Expect(k8sClient.Create(ctx, jenkins)).Should(Succeed())
})
})
})
})

115
controllers/suite_test.go Normal file
View File

@ -0,0 +1,115 @@
/*
Copyright 2021.
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 controllers
import (
"path/filepath"
"testing"
jenkinsiov1alpha2 "github.com/jenkinsci/kubernetes-operator/api/v1alpha2"
jenkinsClient "github.com/jenkinsci/kubernetes-operator/pkg/client"
e "github.com/jenkinsci/kubernetes-operator/pkg/notifications/event"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/envtest"
"sigs.k8s.io/controller-runtime/pkg/envtest/printer"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
// +kubebuilder:scaffold:imports
)
// These tests use Ginkgo (BDD-style Go testing framework). Refer to
// http://onsi.github.io/ginkgo/ to learn more about Ginkgo.
var (
//cfg *rest.Config
k8sClient client.Client
testEnv *envtest.Environment
)
func TestAPIs(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecsWithDefaultAndCustomReporters(t,
"Controller Suite",
[]Reporter{printer.NewlineReporter{}})
}
var _ = BeforeSuite(func(done Done) {
logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)))
By("bootstrapping test environment")
testEnv = &envtest.Environment{
CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")},
}
cfg, err := testEnv.Start()
Expect(err).NotTo(HaveOccurred())
Expect(cfg).NotTo(BeNil())
err = jenkinsiov1alpha2.AddToScheme(scheme.Scheme)
Expect(err).NotTo(HaveOccurred())
// +kubebuilder:scaffold:scheme
//setup manager
k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{
Scheme: scheme.Scheme,
})
Expect(err).NotTo(HaveOccurred())
//setup controller
clientSet, err := kubernetes.NewForConfig(cfg)
Expect(err).NotTo(HaveOccurred())
notificationEvents := make(chan e.Event)
// validate jenkins API connection
jenkinsAPIConnectionSettings := jenkinsClient.JenkinsAPIConnectionSettings{}
err = (&JenkinsReconciler{
Client: k8sManager.GetClient(),
Scheme: k8sManager.GetScheme(),
JenkinsAPIConnectionSettings: jenkinsAPIConnectionSettings,
ClientSet: *clientSet,
Config: *cfg,
NotificationEvents: &notificationEvents,
KubernetesClusterDomain: "",
}).SetupWithManager(k8sManager)
Expect(err).NotTo(HaveOccurred())
go func() {
err = k8sManager.Start(ctrl.SetupSignalHandler())
Expect(err).NotTo(HaveOccurred())
}()
k8sClient = k8sManager.GetClient()
Expect(k8sClient).NotTo(BeNil())
close(done)
}, 60)
var _ = AfterSuite(func() {
By("tearing down the test environment")
err := testEnv.Stop()
Expect(err).NotTo(HaveOccurred())
})

3
go.mod
View File

@ -10,6 +10,8 @@ require (
github.com/go-logr/zapr v0.2.0 github.com/go-logr/zapr v0.2.0
github.com/golang/mock v1.4.1 github.com/golang/mock v1.4.1
github.com/mailgun/mailgun-go/v3 v3.6.4 github.com/mailgun/mailgun-go/v3 v3.6.4
github.com/onsi/ginkgo v1.14.1
github.com/onsi/gomega v1.10.2
github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/openshift/api v3.9.0+incompatible github.com/openshift/api v3.9.0+incompatible
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
@ -20,7 +22,6 @@ require (
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
k8s.io/api v0.20.2 k8s.io/api v0.20.2
k8s.io/apimachinery v0.20.2 k8s.io/apimachinery v0.20.2
k8s.io/cli-runtime v0.20.2 // indirect
k8s.io/client-go v0.20.2 k8s.io/client-go v0.20.2
k8s.io/utils v0.0.0-20201110183641-67b214c5f920 k8s.io/utils v0.0.0-20201110183641-67b214c5f920
sigs.k8s.io/controller-runtime v0.7.0 sigs.k8s.io/controller-runtime v0.7.0

View File

@ -16,7 +16,7 @@ run: generate fmt vet manifests
go run ./main.go go run ./main.go
# Install CRDs into a cluster # Install CRDs into a cluster
install: manifests kustomize install-crds: manifests kustomize
$(KUSTOMIZE) build config/crd | kubectl apply -f - $(KUSTOMIZE) build config/crd | kubectl apply -f -
# Uninstall CRDs from a cluster # Uninstall CRDs from a cluster