Skip to content

Commit 5fede30

Browse files
Merge pull request #1061 from renyunkang/ca
support self-signed certificates & skip tls authentication
2 parents 912f453 + f3e0e95 commit 5fede30

3 files changed

Lines changed: 83 additions & 19 deletions

File tree

pkg/constants/constants.go

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,17 @@ limitations under the License.
1717
package constants
1818

1919
const (
20-
CreatorAnnotationKey = "kubesphere.io/creator"
21-
WorkspaceLabelKey = "kubesphere.io/workspace"
22-
DisplayNameAnnotationKey = "kubesphere.io/alias-name"
23-
InsecureSkipTLSAnnotationKey = "devops.kubesphere.io/insecure-skip-tls"
24-
GitAuthorNameAnnotationKey = "devops.kubesphere.io/git-author-name"
25-
GitAuthorEmailAnnotationKey = "devops.kubesphere.io/git-author-email"
26-
DevOpsProjectLabelKey = "kubesphere.io/devopsproject"
20+
CreatorAnnotationKey = "kubesphere.io/creator"
21+
WorkspaceLabelKey = "kubesphere.io/workspace"
22+
DisplayNameAnnotationKey = "kubesphere.io/alias-name"
23+
InsecureSkipTLSAnnotationKey = "devops.kubesphere.io/insecure-skip-tls"
24+
TLSCertsNameAnnotationKey = "devops.kubesphere.io/tls-certs"
25+
TLSCertsNameSpaceAnnotationKey = "devops.kubesphere.io/tls-certs-namespace"
26+
GitAuthorNameAnnotationKey = "devops.kubesphere.io/git-author-name"
27+
GitAuthorEmailAnnotationKey = "devops.kubesphere.io/git-author-email"
28+
DevOpsProjectLabelKey = "kubesphere.io/devopsproject"
2729

30+
TLSCertKey = "ca.crt"
2831
AuthenticationTag = "Authentication"
2932
DevOpsCredentialTag = "DevOps Credential"
3033
DevOpsPipelineTag = "DevOps Pipeline"
@@ -38,7 +41,9 @@ const (
3841
DevOpsClusterTemplateTag = "DevOps ClusterTemplate"
3942
GitOpsTag = "GitOps"
4043

41-
DevOpsManagedKey = "devops.kubesphere.io/managed"
44+
DevOpsManagedKey = "devops.kubesphere.io/managed"
45+
DevOpsSystemNamespace = "kubesphere-devops-system"
46+
DevOpsWorkerNamespace = "kubesphere-devops-worker"
4247
)
4348

4449
var (

pkg/kapis/devops/v1alpha3/gitops/factory.go

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package gitops
22

33
import (
44
"context"
5-
"errors"
65
"fmt"
76
"os"
87
"path/filepath"
@@ -47,6 +46,32 @@ func (g *gitRepoFactory) parseSkipTLSFromRepo(ctx context.Context, repo *v1alpha
4746
return yes
4847
}
4948

49+
func (g *gitRepoFactory) parseTLSCertsFromRepo(ctx context.Context, repo *v1alpha3.GitRepository) ([]byte, error) {
50+
tlsCertsName := repo.Annotations[constants.TLSCertsNameAnnotationKey]
51+
if tlsCertsName == "" {
52+
return nil, nil
53+
}
54+
55+
tlsCertsNamespace := repo.Annotations[constants.TLSCertsNameSpaceAnnotationKey]
56+
if tlsCertsNamespace == "" {
57+
tlsCertsNamespace = constants.DevOpsWorkerNamespace
58+
}
59+
60+
caSecret := &v1.ConfigMap{}
61+
if err := g.k8sClient.Get(ctx, types.NamespacedName{
62+
Name: tlsCertsName,
63+
Namespace: tlsCertsNamespace,
64+
}, caSecret); err != nil {
65+
return nil, err
66+
}
67+
68+
if caSecret.Data[constants.TLSCertKey] == "" {
69+
return nil, fmt.Errorf("invalid secret data: %s", constants.TLSCertKey)
70+
}
71+
72+
return []byte(caSecret.Data[constants.TLSCertKey]), nil
73+
}
74+
5075
func (g *gitRepoFactory) parseAuthorFromSecret(ctx context.Context, secret *v1.Secret) *object.Signature {
5176
var authorName, authorEmail string
5277
if secret != nil {
@@ -97,6 +122,10 @@ func (g *gitRepoFactory) NewRepoService(ctx context.Context, user user.Info, rep
97122
}
98123

99124
insecureSkipTLS := g.parseSkipTLSFromRepo(ctx, gitRepo)
125+
ca, err := g.parseTLSCertsFromRepo(ctx, gitRepo)
126+
if err != nil {
127+
return nil, err
128+
}
100129
author := g.parseAuthorFromSecret(ctx, secret)
101130
repoDir := g.getRepoDirForUser(ctx, repoName.Namespace, gitRepo.Spec.URL)
102131

@@ -111,12 +140,15 @@ func (g *gitRepoFactory) NewRepoService(ctx context.Context, user user.Info, rep
111140
if err != nil {
112141
return nil, err
113142
}
114-
} else if errors.Is(err, os.ErrNotExist) {
115-
repo, err = git.PlainClone(repoDir, false, &git.CloneOptions{
116-
Auth: auth,
117-
URL: gitRepo.Spec.URL,
118-
Progress: os.Stdout,
119-
})
143+
} else if os.IsNotExist(err) {
144+
opt := &git.CloneOptions{
145+
Auth: auth,
146+
URL: gitRepo.Spec.URL,
147+
Progress: os.Stdout,
148+
InsecureSkipTLS: insecureSkipTLS,
149+
CABundle: ca,
150+
}
151+
repo, err = git.PlainClone(repoDir, false, opt)
120152
if err != nil {
121153
return nil, err
122154
}
@@ -133,8 +165,9 @@ func (g *gitRepoFactory) NewRepoService(ctx context.Context, user user.Info, rep
133165
user: user,
134166
repo: repo,
135167
auth: auth,
136-
insecureSkipTLS: insecureSkipTLS,
137168
newFilePerm: g.config.NewFilePerm,
169+
insecureSkipTLS: insecureSkipTLS,
170+
caBundle: ca,
138171
}
139172
repoService := NewGitRepoService(gitRepoOpts)
140173

pkg/kapis/devops/v1alpha3/scm/scmhandler.go

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@ import (
2828
"github.com/go-git/go-git/v5/storage/memory"
2929
goscm "github.com/jenkins-x/go-scm/scm"
3030
"github.com/kubesphere/ks-devops/pkg/client/git"
31+
"github.com/kubesphere/ks-devops/pkg/constants"
3132
"github.com/kubesphere/ks-devops/pkg/kapis"
3233
"github.com/kubesphere/ks-devops/pkg/kapis/common"
3334
v1 "k8s.io/api/core/v1"
35+
"k8s.io/apimachinery/pkg/api/errors"
3436
"sigs.k8s.io/controller-runtime/pkg/client"
3537
)
3638

@@ -50,6 +52,9 @@ func newHandler(k8sClient client.Client) *handler {
5052
func (h *handler) verify(request *restful.Request, response *restful.Response) {
5153
scm := request.PathParameter("scm")
5254
secretName := request.QueryParameter("secret")
55+
insecureSkipTLS := request.QueryParameter("insecureSkipTLS") == "true"
56+
caName := request.QueryParameter("caName")
57+
caNamespace := request.QueryParameter("caNamespace")
5358
secretNamespace := request.QueryParameter("secretNamespace")
5459
server := common.GetQueryParameter(request, queryParameterServer)
5560

@@ -62,7 +67,8 @@ func (h *handler) verify(request *restful.Request, response *restful.Response) {
6267
response.WriteHeaderAndEntity(http.StatusBadRequest, err)
6368
return
6469
}
65-
code, err = h.checkRepoAccess(server, secretName, secretNamespace)
70+
71+
code, err = h.checkRepoAccess(server, secretName, secretNamespace, insecureSkipTLS, caName, caNamespace)
6672

6773
default:
6874
_, code, err = h.getOrganizations(scm, server, secretName, secretNamespace, 1, 1, false)
@@ -74,14 +80,34 @@ func (h *handler) verify(request *restful.Request, response *restful.Response) {
7480
_ = response.WriteAsJson(verifyResult)
7581
}
7682

77-
func (h *handler) checkRepoAccess(repourl, secretName, secretNamespace string) (int, error) {
83+
func (h *handler) checkRepoAccess(repourl, secretName, secretNamespace string, insecureSkipTLS bool, caName, caNamespace string) (int, error) {
7884
storage := memory.NewStorage()
7985
remote := gogit.NewRemote(storage, &config.RemoteConfig{
8086
Name: "origin",
8187
URLs: []string{repourl},
8288
})
8389

84-
listOption := &gogit.ListOptions{}
90+
listOption := &gogit.ListOptions{InsecureSkipTLS: insecureSkipTLS}
91+
if caName != "" {
92+
if caNamespace == "" {
93+
caNamespace = constants.DevOpsWorkerNamespace
94+
}
95+
96+
cacm := &v1.ConfigMap{}
97+
if err := h.Get(context.Background(), client.ObjectKey{Namespace: caNamespace, Name: caName}, cacm); err != nil {
98+
if errors.IsNotFound(err) {
99+
return http.StatusNotFound, err
100+
}
101+
return http.StatusInternalServerError, err
102+
}
103+
104+
certData, exists := cacm.Data[constants.TLSCertKey]
105+
if !exists {
106+
return http.StatusNotFound, fmt.Errorf("ca.crt not found in configmap %s", caName)
107+
}
108+
listOption.CABundle = []byte(certData)
109+
}
110+
85111
if secretName != "" && secretNamespace != "" {
86112
factory := git.NewClientFactory("git", &v1.SecretReference{
87113
Namespace: secretNamespace, Name: secretName,

0 commit comments

Comments
 (0)