diff --git a/README.md b/README.md index 2e091c5..08b3a06 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ tasks: - { name: source, workspace: shared-workspace } ``` -See the [documentation](https://github.com/opendevstack/ods-pipeline-sonar/blob/main/docs/deploy.adoc) for details and available parameters. +See the [documentation](https://github.com/opendevstack/ods-pipeline-sonar/blob/main/docs/scan.adoc) for prerequisites, details and available parameters. ## About this repository diff --git a/build/docs/scan.adoc b/build/docs/scan.adoc index 54fc299..a58d836 100644 --- a/build/docs/scan.adoc +++ b/build/docs/scan.adoc @@ -36,14 +36,14 @@ data: kind: Secret apiVersion: v1 metadata: - name: 'ods-sonar-auth' + name: ods-sonar-auth type: kubernetes.io/basic-auth stringData: password: 'pwd' username: 'user' ``` -These may also be created via `kubectl`: +These may be created via `kubectl` like this: ``` kubectl create configmap ods-sonar --from-literal=url=https://sonarqube.example.com --from-literal=edition=community kubectl create secret generic ods-sonar-auth --type=kubernetes.io/basic-auth --from-literal=password=pwd --from-literal=username=user diff --git a/docs/scan.adoc b/docs/scan.adoc index 46f1493..84eb11a 100644 --- a/docs/scan.adoc +++ b/docs/scan.adoc @@ -40,14 +40,14 @@ data: kind: Secret apiVersion: v1 metadata: - name: 'ods-sonar-auth' + name: ods-sonar-auth type: kubernetes.io/basic-auth stringData: password: 'pwd' username: 'user' ``` -These may also be created via `kubectl`: +These may be created via `kubectl` like this: ``` kubectl create configmap ods-sonar --from-literal=url=https://sonarqube.example.com --from-literal=edition=community kubectl create secret generic ods-sonar-auth --type=kubernetes.io/basic-auth --from-literal=password=pwd --from-literal=username=user diff --git a/go.mod b/go.mod index 9b0f6c2..c3e39d0 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.19 require ( github.com/opendevstack/ods-pipeline v0.13.3-0.20230908140043-a85ad6d67126 github.com/tektoncd/pipeline v0.49.0 + k8s.io/api v0.25.9 k8s.io/apimachinery v0.26.5 k8s.io/client-go v0.25.9 ) @@ -74,7 +75,6 @@ require ( gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.25.9 // indirect k8s.io/klog/v2 v2.90.1 // indirect k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a // indirect k8s.io/utils v0.0.0-20230209194617-a36077c30491 // indirect diff --git a/test/e2e/main_test.go b/test/e2e/main_test.go index 6b092c6..4c432e0 100644 --- a/test/e2e/main_test.go +++ b/test/e2e/main_test.go @@ -1,13 +1,19 @@ package e2e import ( + "context" + "errors" + "fmt" "log" "os" "path/filepath" + "strings" "testing" ott "github.com/opendevstack/ods-pipeline/pkg/odstasktest" ttr "github.com/opendevstack/ods-pipeline/pkg/tektontaskrun" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var ( @@ -34,6 +40,7 @@ func testMain(m *testing.M) int { cc, ott.StartSonarQube(), ott.InstallODSPipeline(), + installSonarQubeConfigMapAndSecret(), ttr.InstallTaskFromPath( filepath.Join(rootPath, "build/tasks/scan.yaml"), nil, @@ -53,3 +60,74 @@ func runTask(opts ...ttr.TaskRunOpt) error { ttr.UsingTask(taskName), }, opts...)...) } + +// installSonarQubeConfigMapAndSecret installs the task prerequisites. +func installSonarQubeConfigMapAndSecret() ttr.NamespaceOpt { + return func(cc *ttr.ClusterConfig, nc *ttr.NamespaceConfig) error { + k8sClient, err := newKubeClient() + if err != nil { + return fmt.Errorf("create K8s client: %s", err) + } + url, err := readSonarURL() + if err != nil { + return fmt.Errorf("read SonarQube URL: %s", err) + } + _, err = k8sClient.CoreV1().ConfigMaps(nc.Name).Create(context.Background(), &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ods-sonar", + }, + Data: map[string]string{ + "url": url, + "edition": "community", + }, + }, metav1.CreateOptions{}) + if err != nil { + return fmt.Errorf("create ConfigMap ods-sonar: %s", err) + } + username, password, err := readSonarAuth() + if err != nil { + return fmt.Errorf("read SonarQube authentication: %s", err) + } + _, err = k8sClient.CoreV1().Secrets(nc.Name).Create(context.Background(), &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ods-sonar-auth", + }, + StringData: map[string]string{ + "password": password, + "username": username, + }, + }, metav1.CreateOptions{}) + if err != nil { + return fmt.Errorf("create Secret ods-sonar-auth: %s", err) + } + return nil + } +} + +// readSonarAuth reads the Sonar credentials from the central location. +// Eventually, launching the SonarQube service should be moved to this repository instead. +func readSonarAuth() (username, password string, err error) { + sonarAuth, err := getTrimmedFileContent("/tmp/ods-pipeline/kind-values/sonar-auth") + if err != nil { + return + } + username, password, found := strings.Cut(sonarAuth, ":") + if !found { + err = errors.New("did not find expected sonar auth string") + } + return +} + +// readSonarURL reads the Sonar URL from the central location. +// Eventually, launching the SonarQube service should be moved to this repository instead. +func readSonarURL() (string, error) { + return getTrimmedFileContent("/tmp/ods-pipeline/kind-values/sonar-http") +} + +func getTrimmedFileContent(filename string) (string, error) { + content, err := os.ReadFile(filename) + if err != nil { + return "", err + } + return strings.TrimSpace(string(content)), nil +}