Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat(jenkins-pipeline): Create docker-config Secret From env vars #1054

Merged
merged 3 commits into from
Sep 4, 2022
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
1 change: 1 addition & 0 deletions internal/pkg/plugin/jenkinspipeline/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ func Create(options map[string]interface{}) (map[string]interface{}, error) {
// Initialize Operator with Operations
operator := &plugininstaller.Operator{
PreExecuteOperations: plugininstaller.PreExecuteOperations{
jenkins.SetHarborAuth,
jenkins.SetJobDefaultConfig,
jenkins.ValidateJobConfig,
},
Expand Down
1 change: 1 addition & 0 deletions internal/pkg/plugin/jenkinspipeline/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ func Delete(options map[string]interface{}) (bool, error) {
jenkins.ValidateJobConfig,
},
ExecuteOperations: plugininstaller.ExecuteOperations{
// TODO(daniel-hutao): delete secret: docker-config
ci.DeleteCIFiles,
jenkins.DeleteJob,
},
Expand Down
8 changes: 8 additions & 0 deletions internal/pkg/plugininstaller/jenkins/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ type JobOptions struct {
ProjectBranch string `mapstructure:"projectBranch"`
JenkinsfilePath string `mapstructure:"jenkinsfilePath" validate:"required"`

JenkinsNamespace string `mapstructure:"jenkinsNamespace"`
HarborURL string `mapstructure:"harborURL" validate:"url"`
HarborUser string `mapstructure:"harborUser"`

JenkinsEnableRestart bool `mapstructure:"jenkinsEnableRestart"`

// used in package
Expand All @@ -55,6 +59,10 @@ func newJobOptions(options plugininstaller.RawOptions) (*JobOptions, error) {
if err := mapstructure.Decode(options, &opts); err != nil {
return nil, err
}
// TODO(daniel-hutao): wait for refactoring
if opts.JenkinsNamespace == "" {
opts.JenkinsNamespace = "jenkins"
}
return &opts, nil
}

Expand Down
50 changes: 50 additions & 0 deletions internal/pkg/plugininstaller/jenkins/validate.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package jenkins

import (
"encoding/base64"
"errors"
"fmt"
"math/rand"
Expand All @@ -13,6 +14,7 @@ import (
"github.com/devstream-io/devstream/internal/pkg/plugininstaller/common"
"github.com/devstream-io/devstream/pkg/util/jenkins"
"github.com/devstream-io/devstream/pkg/util/k8s"
"github.com/devstream-io/devstream/pkg/util/log"
"github.com/devstream-io/devstream/pkg/util/validator"
)

Expand Down Expand Up @@ -126,3 +128,51 @@ func buildCIConfig(jenkinsFilePath string) *ci.CIConfig {
}
return ciConfig
}

func SetHarborAuth(options plugininstaller.RawOptions) (plugininstaller.RawOptions, error) {
opts, err := newJobOptions(options)
if err != nil {
return nil, err
}
namespace := opts.JenkinsNamespace
harborURL := opts.HarborURL
harborUser := opts.HarborUser

harborPasswd := os.Getenv("HARBOR_PASSWORD")
if harborPasswd == "" {
return nil, fmt.Errorf("the environment variable HARBOR_PASSWORD is not set")
}

return options, createDockerSecret(namespace, harborURL, harborUser, harborPasswd)
}

func createDockerSecret(namespace, url, username, password string) error {
tmpStr := fmt.Sprintf("%s:%s", username, password)
authStr := base64.StdEncoding.EncodeToString([]byte(tmpStr))
log.Debugf("Auth string: %s.", authStr)

configJsonStrTpl := `{
"auths": {
"%s": {
"auth": "%s"
}
}`
configJsonStr := fmt.Sprintf(configJsonStrTpl, url, authStr)
log.Debugf("config.json: %s.", configJsonStr)

// create secret in k8s
client, err := k8s.NewClient()
if err != nil {
return err
}

data := map[string][]byte{
"config.json": []byte(configJsonStr),
}
_, err = client.ApplySecret("docker-config", namespace, data, nil)
if err != nil {
return err
}
log.Infof("Secret %s/%s has been created.", namespace, "docker-config")
return nil
}
6 changes: 6 additions & 0 deletions internal/pkg/show/config/plugins/jenkins-pipeline.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,9 @@ tools:
jenkinsfilePath: https://raw.githubusercontent.com/YOUR_CI_FILE_LOCATION
# projectURL is the project repo location, like http://127.0.0.1:30080/root/project
projectURL: http://127.0.0.1:30080/root/test-project
# jenkins namespace in k8s cluster
jenkinsNamespace: jenkins
# harbor URL for pulling/pushing
harborURL: http://harbor.example.com:80
# harbor username
harborUser: admin
17 changes: 17 additions & 0 deletions pkg/util/k8s/secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package k8s
import (
"context"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
v1 "k8s.io/client-go/applyconfigurations/core/v1"
)

func (c *Client) GetSecret(namespace, name string) (map[string]string, error) {
Expand All @@ -18,3 +20,18 @@ func (c *Client) GetSecret(namespace, name string) (map[string]string, error) {
}
return secretMap, nil
}

func (c *Client) ApplySecret(name, namespace string, data map[string][]byte, labels map[string]string) (*corev1.Secret, error) {
secret := v1.Secret(name, namespace).
WithLabels(labels).
WithData(data).
WithImmutable(false)

applyOptions := metav1.ApplyOptions{
FieldManager: "DevStream",
}

return c.clientset.CoreV1().
Secrets(namespace).
Apply(context.Background(), secret, applyOptions)
}