fix: add tls when get repository index. (#6195)

* fix: add tls when get repository index.

Signed-off-by: joyceliu <joyceliu@yunify.com>

* Update staging/src/kubesphere.io/utils/helm/repo_index.go

Signed-off-by: hongming <coder.scala@gmail.com>

* fix: add tls when get repository index.

Signed-off-by: joyceliu <joyceliu@yunify.com>

---------

Signed-off-by: joyceliu <joyceliu@yunify.com>
Signed-off-by: hongming <coder.scala@gmail.com>
Co-authored-by: joyceliu <joyceliu@yunify.com>
Co-authored-by: hongming <coder.scala@gmail.com>
This commit is contained in:
liujian
2024-09-23 15:05:14 +08:00
committed by GitHub
parent df4553131f
commit ecdffc7d73
11 changed files with 216 additions and 76 deletions

View File

@@ -456,26 +456,40 @@ func (r *InstallPlanReconciler) loadChartData(ctx context.Context) ([]byte, stri
switch chartURL.Scheme {
case registry.OCIScheme:
opts := make([]getter.Option, 0)
opts = append(opts, getter.WithInsecureSkipVerifyTLS(true))
if extensionVersion.Spec.Repository != "" {
opts = append(opts, getter.WithInsecureSkipVerifyTLS(repo.Spec.Insecure))
}
if repo.Spec.BasicAuth != nil {
opts = append(opts, getter.WithBasicAuth(repo.Spec.BasicAuth.Username, repo.Spec.BasicAuth.Password))
}
chartGetter, err = getter.NewOCIGetter(opts...)
if err != nil {
return nil, "", fmt.Errorf("failed to create chart getter: %v", err)
}
case "http", "https":
opts := make([]getter.Option, 0)
if chartURL.Scheme == "https" && extensionVersion.Spec.Repository != "" {
opts = append(opts, getter.WithInsecureSkipVerifyTLS(repo.Spec.Insecure))
}
if repo.Spec.CABundle != "" {
caFile, err := storeCAFile(repo.Spec.CABundle, repo.Name)
if err != nil {
return nil, "", fmt.Errorf("failed to store CABundle to local file: %s", err)
}
opts = append(opts, getter.WithTLSClientConfig("", "", caFile))
}
if chartURL.Scheme == "https" {
opts = append(opts, getter.WithInsecureSkipVerifyTLS(true))
opts = append(opts, getter.WithInsecureSkipVerifyTLS(repo.Spec.Insecure))
}
if repo.Spec.BasicAuth != nil {
opts = append(opts, getter.WithBasicAuth(repo.Spec.BasicAuth.Username, repo.Spec.BasicAuth.Password))
}
chartGetter, err = getter.NewHTTPGetter(opts...)
if err != nil {
return nil, "", fmt.Errorf("failed to create chart getter: %v", err)
}
default:
err = fmt.Errorf("unsupported scheme: %s", chartURL.Scheme)
}
if err != nil {
return nil, "", fmt.Errorf("failed to create chart getter: %v", err)
return nil, "", fmt.Errorf("unsupported scheme: %s", chartURL.Scheme)
}
buffer, err := chartGetter.Get(chartURL.String())

View File

@@ -11,7 +11,6 @@ import (
"encoding/base64"
"errors"
"fmt"
"io"
"mime"
"net/http"
"net/url"
@@ -19,10 +18,6 @@ import (
"strings"
"time"
kscontroller "kubesphere.io/kubesphere/pkg/controller"
clusterv1alpha1 "kubesphere.io/api/cluster/v1alpha1"
"github.com/go-logr/logr"
"helm.sh/helm/v3/pkg/chart/loader"
appsv1 "k8s.io/api/apps/v1"
@@ -35,6 +30,7 @@ import (
"k8s.io/client-go/tools/record"
"k8s.io/client-go/util/retry"
"k8s.io/klog/v2"
clusterv1alpha1 "kubesphere.io/api/cluster/v1alpha1"
corev1alpha1 "kubesphere.io/api/core/v1alpha1"
"kubesphere.io/utils/helm"
ctrl "sigs.k8s.io/controller-runtime"
@@ -43,6 +39,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"kubesphere.io/kubesphere/pkg/constants"
kscontroller "kubesphere.io/kubesphere/pkg/controller"
)
const (
@@ -52,6 +49,8 @@ const (
defaultRequeueInterval = 15 * time.Second
generateNameFormat = "repository-%s"
extensionFileName = "extension.yaml"
// caTemplate store repository.spec.caBound in local dir.
caTemplate = "{{ .TempDIR }}/repository/{{ .RepositoryName }}/ssl/ca.crt"
)
var extensionRepoConflict = fmt.Errorf("extension repo mismatch")
@@ -178,10 +177,10 @@ func (r *RepositoryReconciler) syncExtensionsFromURL(ctx context.Context, repo *
logger := klog.FromContext(ctx)
ctx, cancel := context.WithTimeout(ctx, 15*time.Second)
defer cancel()
cred := helm.RepoCredential{}
if repo.Spec.BasicAuth != nil {
cred.Username = repo.Spec.BasicAuth.Username
cred.Password = repo.Spec.BasicAuth.Password
cred, err := newHelmCred(repo)
if err != nil {
return err
}
index, err := helm.LoadRepoIndex(ctx, repoURL, cred)
if err != nil {
@@ -216,7 +215,7 @@ func (r *RepositoryReconciler) syncExtensionsFromURL(ctx context.Context, repo *
}
}
extensionVersionSpec, err := r.loadExtensionVersionSpecFrom(ctx, chartURL, repo)
extensionVersionSpec, err := r.loadExtensionVersionSpecFrom(ctx, chartURL, repo, cred)
if err != nil {
return fmt.Errorf("failed to load extension version spec: %s", err)
}
@@ -435,37 +434,19 @@ func (r *RepositoryReconciler) deployRepository(ctx context.Context, repo *corev
return nil
}
func (r *RepositoryReconciler) loadExtensionVersionSpecFrom(ctx context.Context, chartURL string, repo *corev1alpha1.Repository) (*corev1alpha1.ExtensionVersionSpec, error) {
func (r *RepositoryReconciler) loadExtensionVersionSpecFrom(ctx context.Context, chartURL string, repo *corev1alpha1.Repository, cred helm.RepoCredential) (*corev1alpha1.ExtensionVersionSpec, error) {
logger := klog.FromContext(ctx)
var result *corev1alpha1.ExtensionVersionSpec
err := retry.OnError(retry.DefaultRetry, func(err error) bool {
return true
}, func() error {
req, err := http.NewRequest(http.MethodGet, chartURL, nil)
data, err := helm.LoadData(ctx, chartURL, cred)
if err != nil {
return err
}
if repo.Spec.BasicAuth != nil {
req.SetBasicAuth(repo.Spec.BasicAuth.Username, repo.Spec.BasicAuth.Password)
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
data, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
return fmt.Errorf(string(data))
}
files, err := loader.LoadArchiveFiles(resp.Body)
files, err := loader.LoadArchiveFiles(data)
if err != nil {
return err
}

View File

@@ -7,15 +7,18 @@ package core
import (
"bytes"
"encoding/base64"
goerrors "errors"
"fmt"
"io"
"os"
"path/filepath"
"sort"
"strings"
yaml3 "gopkg.in/yaml.v3"
"text/template"
"github.com/Masterminds/semver/v3"
yaml3 "gopkg.in/yaml.v3"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/storage/driver"
rbacv1 "k8s.io/api/rbac/v1"
@@ -23,9 +26,9 @@ import (
"k8s.io/klog/v2"
clusterv1alpha1 "kubesphere.io/api/cluster/v1alpha1"
corev1alpha1 "kubesphere.io/api/core/v1alpha1"
"kubesphere.io/utils/helm"
"kubesphere.io/kubesphere/pkg/utils/hashutil"
"kubesphere.io/kubesphere/pkg/version"
)
@@ -264,3 +267,58 @@ func configChanged(sub *corev1alpha1.InstallPlan, cluster string) bool {
}
return newConfigHash != oldConfigHash
}
// newHelmCred from Repository
func newHelmCred(repo *corev1alpha1.Repository) (helm.RepoCredential, error) {
cred := helm.RepoCredential{
InsecureSkipTLSVerify: repo.Spec.Insecure,
}
if repo.Spec.CABundle != "" {
caFile, err := storeCAFile(repo.Spec.CABundle, repo.Name)
if err != nil {
return cred, err
}
cred.CAFile = caFile
}
if repo.Spec.BasicAuth != nil {
cred.Username = repo.Spec.BasicAuth.Username
cred.Password = repo.Spec.BasicAuth.Password
}
return cred, nil
}
// storeCAFile in local file from caTemplate.
func storeCAFile(caBundle string, repoName string) (string, error) {
var buff = &bytes.Buffer{}
tmpl, err := template.New("repositoryCABundle").Parse(caTemplate)
if err != nil {
return "", err
}
if err := tmpl.Execute(buff, map[string]string{
"TempDIR": os.TempDir(),
"RepositoryName": repoName,
}); err != nil {
return "", err
}
caFile := buff.String()
if _, err := os.Stat(filepath.Dir(caFile)); err != nil {
if !os.IsNotExist(err) {
return "", err
}
if err := os.MkdirAll(filepath.Dir(caFile), os.ModePerm); err != nil {
return "", err
}
}
data, err := base64.StdEncoding.DecodeString(caBundle)
if err != nil {
return "", err
}
if err := os.WriteFile(caFile, data, os.ModePerm); err != nil {
return "", err
}
return caFile, nil
}