Chore: remove schematic kube and helm (#6099)

* Chore: remove unused code

Signed-off-by: Somefive <yd219913@alibaba-inc.com>

* Chore: remove schematic Kube & Helm

Signed-off-by: Somefive <yd219913@alibaba-inc.com>

---------

Signed-off-by: Somefive <yd219913@alibaba-inc.com>
This commit is contained in:
Somefive
2023-06-12 10:41:02 +08:00
committed by GitHub
parent c0cbe24dc4
commit f1bae16723
86 changed files with 136 additions and 6949 deletions
@@ -84,7 +84,7 @@ func RollbackApplicationWithRevision(ctx context.Context, cli client.Client, app
// freeze the application
appKey := client.ObjectKeyFromObject(app)
controllerRequirement, err := utils.FreezeApplication(ctx, cli, app, func() {
controllerRequirement, err := FreezeApplication(ctx, cli, app, func() {
app.Spec = matchedRev.Spec.Application.Spec
oam.SetPublishVersion(app, publishVersion)
})
@@ -94,7 +94,7 @@ func RollbackApplicationWithRevision(ctx context.Context, cli client.Client, app
defer func() {
// unfreeze application
if err = utils.UnfreezeApplication(ctx, cli, app, nil, controllerRequirement); err != nil {
if err = UnfreezeApplication(ctx, cli, app, nil, controllerRequirement); err != nil {
klog.Errorf("failed to unfreeze application %s after update:%s", appKey, err.Error())
}
}()
@@ -130,3 +130,27 @@ func RollbackApplicationWithRevision(ctx context.Context, cli client.Client, app
}
return matchedRev, app, nil
}
// FreezeApplication freeze application to disable the reconciling process for it
func FreezeApplication(ctx context.Context, cli client.Client, app *v1beta1.Application, mutate func()) (string, error) {
return oam.GetControllerRequirement(app), _updateApplicationWithControllerRequirement(ctx, cli, app, mutate, "Disabled")
}
// UnfreezeApplication unfreeze application to enable the reconciling process for it
func UnfreezeApplication(ctx context.Context, cli client.Client, app *v1beta1.Application, mutate func(), originalControllerRequirement string) error {
return _updateApplicationWithControllerRequirement(ctx, cli, app, mutate, originalControllerRequirement)
}
func _updateApplicationWithControllerRequirement(ctx context.Context, cli client.Client, app *v1beta1.Application, mutate func(), controllerRequirement string) error {
appKey := client.ObjectKeyFromObject(app)
return retry.RetryOnConflict(retry.DefaultBackoff, func() error {
if err := cli.Get(ctx, appKey, app); err != nil {
return err
}
oam.SetControllerRequirement(app, controllerRequirement)
if mutate != nil {
mutate()
}
return cli.Update(ctx, app)
})
}
-14
View File
@@ -16,20 +16,6 @@ limitations under the License.
package errors
import (
"fmt"
)
// ResourceTrackerNotExistError identifies error caused by resourcetracker not exist
type ResourceTrackerNotExistError struct {
Name string
}
// Error implement error interface
func (err ResourceTrackerNotExistError) Error() string {
return fmt.Sprintf("given resource tracker %q doesn't exist", err.Name)
}
// ManagedResourceHasNoDataError identifies error caused by no data in maanged resource
type ManagedResourceHasNoDataError struct{}
-213
View File
@@ -19,32 +19,21 @@ package helm
import (
"context"
"fmt"
"io"
"log"
"os"
"strings"
v1 "k8s.io/api/core/v1"
types2 "k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/pkg/errors"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/cli"
"helm.sh/helm/v3/pkg/getter"
"helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v3/pkg/repo"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/utils/common"
cmdutil "github.com/oam-dev/kubevela/pkg/utils/util"
)
// VelaDebugLog defines an ENV to set vela helm install log to be debug
const (
VelaDebugLog = "VELA_DEBUG"
userNameSecKey = "username"
userPasswordSecKey = "password"
caFileSecKey = "caFile"
@@ -56,138 +45,6 @@ var (
settings = cli.New()
)
// Install will install helm chart
func Install(ioStreams cmdutil.IOStreams, repoName, repoURL, chartName, version, namespace, releaseName string,
vals map[string]interface{}) error {
if len(namespace) > 0 {
args, err := common.InitBaseRestConfig()
if err != nil {
return err
}
kubeClient, err := args.GetClient()
if err != nil {
return err
}
exist, err := cmdutil.DoesNamespaceExist(kubeClient, namespace)
if err != nil {
return err
}
if !exist {
if err = cmdutil.NewNamespace(kubeClient, namespace); err != nil {
return fmt.Errorf("create namespace (%s) failed for chart %s: %w", namespace, chartName, err)
}
}
}
// check release running first before add repo and install chart
if IsHelmReleaseRunning(releaseName, chartName, namespace, ioStreams) {
return nil
}
if !IsHelmRepositoryExist(repoName, repoURL) {
err := AddHelmRepository(repoName, repoURL,
"", "", "", "", "", false, ioStreams.Out)
if err != nil {
return err
}
}
chartClient, err := NewHelmInstall(version, namespace, releaseName)
if err != nil {
return err
}
chartRequested, err := GetChart(chartClient, repoName+"/"+chartName)
if err != nil {
return err
}
rel, err := chartClient.Run(chartRequested, vals)
if err != nil {
return err
}
ioStreams.Infof("Successfully installed chart (%s) with release name (%s)\n", chartName, rel.Name)
return nil
}
// Uninstall will uninstall helm chart
func Uninstall(ioStreams cmdutil.IOStreams, chartName, namespace, releaseName string) error {
if !IsHelmReleaseRunning(releaseName, chartName, namespace, ioStreams) {
return nil
}
uninstall, err := NewHelmUninstall(namespace)
if err != nil {
return err
}
_, err = uninstall.Run(releaseName)
if err != nil {
return err
}
ioStreams.Infof("Successfully removed chart (%s) with release name (%s)\n", chartName, releaseName)
return nil
}
// NewHelmInstall will create a install client for helm install
func NewHelmInstall(version, namespace, releaseName string) (*action.Install, error) {
actionConfig := new(action.Configuration)
if len(namespace) == 0 {
namespace = types.DefaultKubeVelaNS
}
if err := actionConfig.Init(
cmdutil.NewRestConfigGetter(namespace),
namespace,
os.Getenv("HELM_DRIVER"),
debug,
); err != nil {
return nil, err
}
client := action.NewInstall(actionConfig)
client.ReleaseName = releaseName
// MUST set here, client didn't use namespace from configuration
client.Namespace = namespace
if len(version) > 0 {
client.Version = version
} else {
client.Version = types.DefaultKubeVelaVersion
}
return client, nil
}
// NewHelmUninstall will create a helm uninstall client
func NewHelmUninstall(namespace string) (*action.Uninstall, error) {
actionConfig := new(action.Configuration)
if err := actionConfig.Init(
cmdutil.NewRestConfigGetter(namespace),
namespace,
os.Getenv("HELM_DRIVER"),
debug,
); err != nil {
return nil, err
}
return action.NewUninstall(actionConfig), nil
}
// IsHelmRepositoryExist will check help repo exists
func IsHelmRepositoryExist(name, url string) bool {
repos := GetHelmRepositoryList()
for _, repo := range repos {
if repo.Name == name && repo.URL == url {
return true
}
}
return false
}
// GetHelmRepositoryList get the helm repo list from default setting
func GetHelmRepositoryList() []*repo.Entry {
f, err := repo.LoadFile(settings.RepositoryConfig)
if err == nil && len(f.Repositories) > 0 {
return f.Repositories
}
return nil
}
func debug(format string, v ...interface{}) {
if settings.Debug {
format = fmt.Sprintf("[debug] %s\n", format)
@@ -195,53 +52,6 @@ func debug(format string, v ...interface{}) {
}
}
// AddHelmRepository add helm repo
func AddHelmRepository(name, url, username, password, certFile, keyFile, caFile string, insecureSkipTLSverify bool, out io.Writer) error {
var f repo.File
c := repo.Entry{
Name: name,
URL: url,
Username: username,
Password: password,
CertFile: certFile,
KeyFile: keyFile,
CAFile: caFile,
InsecureSkipTLSverify: insecureSkipTLSverify,
}
r, err := repo.NewChartRepository(&c, getter.All(settings))
if err != nil {
return err
}
if _, err := r.DownloadIndexFile(); err != nil {
return errors.Wrapf(err, "looks like %q is not a valid chart repository or cannot be reached", url)
}
f.Update(&c)
if err := f.WriteFile(settings.RepositoryConfig, 0644); err != nil {
return err
}
fmt.Fprintf(out, "%q has been added to your repositories\n", name)
return nil
}
// IsHelmReleaseRunning check helm release running
func IsHelmReleaseRunning(releaseName, chartName, ns string, streams cmdutil.IOStreams) bool {
releases, err := GetHelmRelease(ns)
if err != nil {
streams.Error("get helm release err", err)
return false
}
for _, r := range releases {
if strings.Contains(r.Chart.ChartFullPath(), chartName) && r.Name == releaseName {
return true
}
}
return false
}
// GetHelmRelease will get helm release
func GetHelmRelease(ns string) ([]*release.Release, error) {
actionConfig := new(action.Configuration)
@@ -258,29 +68,6 @@ func GetHelmRelease(ns string) ([]*release.Release, error) {
return results, nil
}
// GetChart will locate chart
func GetChart(client *action.Install, name string) (*chart.Chart, error) {
if os.Getenv(VelaDebugLog) != "" {
settings.Debug = true
}
chartPath, err := client.ChartPathOptions.LocateChart(name, settings)
if err != nil {
return nil, err
}
chartRequested, err := loader.Load(chartPath)
if err != nil {
return nil, err
}
return chartRequested, nil
}
// InstallHelmChart will install helm chart from types.Chart
func InstallHelmChart(ioStreams cmdutil.IOStreams, c types.Chart) error {
return Install(ioStreams, c.Repo, c.URL, c.Name, c.Version, c.Namespace, c.Name, c.Values)
}
// SetHTTPOption will read username and password from secret return a httpOption that contain these info.
func SetHTTPOption(ctx context.Context, k8sClient client.Client, secretRef types2.NamespacedName) (*common.HTTPOption, error) {
sec := v1.Secret{}
-6
View File
@@ -21,12 +21,6 @@ import (
"encoding/json"
)
// DumpJSON returns the JSON encoding
func DumpJSON(o interface{}) string {
j, _ := json.Marshal(o)
return string(j)
}
// StrictUnmarshal unmarshal target structure and disallow unknown fields
func StrictUnmarshal(bs []byte, dest interface{}) error {
d := json.NewDecoder(bytes.NewReader(bs))
-8
View File
@@ -185,14 +185,6 @@ func GetUserInfoFromConfig(cfg *rest.Config) *authv1.UserInfo {
return nil
}
// AutoSetSelfImpersonationInConfig set impersonate username and group to the identity in the original rest config
func AutoSetSelfImpersonationInConfig(cfg *rest.Config) {
if userInfo := GetUserInfoFromConfig(cfg); userInfo != nil {
cfg.Impersonate.UserName = userInfo.Username
cfg.Impersonate.Groups = append(cfg.Impersonate.Groups, userInfo.Groups...)
}
}
// CreateOrUpdate create or update a kubernetes object
func CreateOrUpdate(ctx context.Context, cli client.Client, obj client.Object) (controllerutil.OperationResult, error) {
bs, err := json.Marshal(obj)
-64
View File
@@ -1,64 +0,0 @@
/*
Copyright 2022 The KubeVela Authors.
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 utils
import (
"encoding/json"
"net/http"
"net/http/pprof"
"runtime"
"time"
"k8s.io/klog/v2"
)
// EnablePprof listen to the pprofAddr and export the profiling results
// If the errChan is nil, this function will panic when the listening error occurred.
func EnablePprof(pprofAddr string, errChan chan error) {
// Start pprof server if enabled
mux := http.NewServeMux()
mux.HandleFunc("/debug/pprof/", pprof.Index)
mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
mux.HandleFunc("/mem/stat", func(writer http.ResponseWriter, request *http.Request) {
var ms runtime.MemStats
runtime.ReadMemStats(&ms)
bs, _ := json.Marshal(ms)
_, _ = writer.Write(bs)
})
mux.HandleFunc("/gc", func(writer http.ResponseWriter, request *http.Request) {
runtime.GC()
})
pprofServer := http.Server{
Addr: pprofAddr,
Handler: mux,
ReadHeaderTimeout: 2 * time.Second,
}
klog.InfoS("Starting debug HTTP server", "addr", pprofServer.Addr)
if err := pprofServer.ListenAndServe(); err != nil {
klog.Error(err, "Failed to start debug HTTP server")
if errChan != nil {
errChan <- err
} else {
panic(err)
}
}
}
-41
View File
@@ -1,41 +0,0 @@
/*
Copyright 2021 The KubeVela Authors.
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 utils
import (
"net/http"
utilnet "k8s.io/apimachinery/pkg/util/net"
"k8s.io/klog/v2"
)
// TryCancelRequest tries to cancel the request by traversing round trippers
func TryCancelRequest(rt http.RoundTripper, req *http.Request) {
type canceler interface {
CancelRequest(*http.Request)
}
switch rt := rt.(type) {
case canceler:
rt.CancelRequest(req)
case utilnet.RoundTripperWrapper:
TryCancelRequest(rt.WrappedRoundTripper(), req)
default:
klog.Warningf("Unable to cancel request for %T", rt)
}
}
-26
View File
@@ -1,26 +0,0 @@
/*
Copyright 2021 The KubeVela Authors.
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 utils
import "strings"
// Sanitize the inputs by removing line endings
func Sanitize(s string) string {
s = strings.ReplaceAll(s, "\n", "")
s = strings.ReplaceAll(s, "\r", "")
return s
}
-28
View File
@@ -1,28 +0,0 @@
/*
Copyright 2021 The KubeVela Authors.
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 utils
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestSanitize(t *testing.T) {
s := "abc\ndef\rgh"
require.Equal(t, "abcdefgh", Sanitize(s))
}
+2 -31
View File
@@ -18,9 +18,8 @@ package schema
import (
"fmt"
"strings"
"github.com/oam-dev/kubevela/pkg/utils"
"github.com/kubevela/pkg/util/slices"
)
// UISchema ui schema
@@ -87,7 +86,7 @@ func (c Condition) Validate() error {
if c.Action != "enable" && c.Action != "disable" && c.Action != "" {
return fmt.Errorf("the action of the condition only supports enable, disable or leave it empty")
}
if c.Op != "" && !utils.StringsContain([]string{"==", "!=", "in"}, c.Op) {
if c.Op != "" && !slices.Contains([]string{"==", "!=", "in"}, c.Op) {
return fmt.Errorf("the op of the condition must be `==` 、`!=` and `in`")
}
return nil
@@ -125,22 +124,6 @@ type Option struct {
Value interface{} `json:"value"`
}
// FirstUpper Sets the first letter of the string to upper.
func FirstUpper(s string) string {
if s == "" {
return ""
}
return strings.ToUpper(s[:1]) + s[1:]
}
// FirstLower Sets the first letter of the string to lowercase.
func FirstLower(s string) string {
if s == "" {
return ""
}
return strings.ToLower(s[:1]) + s[1:]
}
// GetDefaultUIType Set the default mapping for API Schema Type
func GetDefaultUIType(apiType string, haveOptions bool, subType string, haveSub bool) string {
switch apiType {
@@ -170,15 +153,3 @@ func GetDefaultUIType(apiType string, haveOptions bool, subType string, haveSub
return "Input"
}
}
// RenderLabel render option label
func RenderLabel(source interface{}) string {
switch v := source.(type) {
case int:
return fmt.Sprintf("%d", v)
case string:
return FirstUpper(v)
default:
return FirstUpper(fmt.Sprintf("%v", v))
}
}
+5 -129
View File
@@ -17,128 +17,9 @@ limitations under the License.
package utils
import (
"net/url"
"path"
"reflect"
"sort"
"strconv"
"strings"
)
// StringsContain strings contain
func StringsContain(items []string, source string) bool {
for _, item := range items {
if item == source {
return true
}
}
return false
}
// ThreeWaySliceCompare will compare two string slice, with the three return values: [both in A and B], [only in A], [only in B]
func ThreeWaySliceCompare(a []string, b []string) ([]string, []string, []string) {
m := make(map[string]struct{})
for _, k := range b {
m[k] = struct{}{}
}
var AB, AO, BO []string
for _, k := range a {
_, ok := m[k]
if !ok {
AO = append(AO, k)
continue
}
AB = append(AB, k)
delete(m, k)
}
for k := range m {
BO = append(BO, k)
}
sort.Strings(AB)
sort.Strings(AO)
sort.Strings(BO)
return AB, AO, BO
}
// EqualSlice checks if two slice are equal
func EqualSlice(a, b []string) bool {
sort.Strings(a)
sort.Strings(b)
return reflect.DeepEqual(a, b)
}
// SliceIncludeSlice the slice include the b slice
func SliceIncludeSlice(a, b []string) bool {
if EqualSlice(a, b) {
return true
}
for _, item := range b {
if !StringsContain(a, item) {
return false
}
}
return true
}
// ToString convery an interface to a string type.
func ToString(i interface{}) string {
if i == nil {
return ""
}
v := reflect.ValueOf(i)
if v.Kind() == reflect.Ptr && !v.IsNil() {
v = v.Elem()
}
i = v.Interface()
switch s := i.(type) {
case string:
return s
case bool:
return strconv.FormatBool(s)
case float64:
return strconv.FormatFloat(s, 'f', -1, 64)
case float32:
return strconv.FormatFloat(float64(s), 'f', -1, 32)
case int:
return strconv.Itoa(s)
case int64:
return strconv.FormatInt(s, 10)
case int32:
return strconv.Itoa(int(s))
case int16:
return strconv.FormatInt(int64(s), 10)
case int8:
return strconv.FormatInt(int64(s), 10)
case uint:
return strconv.FormatUint(uint64(s), 10)
case uint64:
// nolint
return strconv.FormatUint(uint64(s), 10)
case uint32:
return strconv.FormatUint(uint64(s), 10)
case uint16:
return strconv.FormatUint(uint64(s), 10)
case uint8:
return strconv.FormatUint(uint64(s), 10)
case []byte:
return string(s)
case nil:
return ""
default:
return ""
}
}
// MapKey2Array convery map keys to array
func MapKey2Array(source map[string]string) []string {
var list []string
for k := range source {
list = append(list, k)
}
return list
}
// GetBoxDrawingString get line drawing string, see https://en.wikipedia.org/wiki/Box-drawing_character
// nolint:gocyclo
func GetBoxDrawingString(up bool, down bool, left bool, right bool, padLeft int, padRight int) string {
@@ -193,14 +74,9 @@ func GetBoxDrawingString(up bool, down bool, left bool, right bool, padLeft int,
return sb.String()
}
// JoinURL join baseURL and subPath to be new URL
func JoinURL(baseURL, subPath string) (string, error) {
parsedURL, err := url.Parse(baseURL)
if err != nil {
return "", err
}
parsedURL.RawPath = path.Join(parsedURL.RawPath, subPath)
parsedURL.Path = path.Join(parsedURL.Path, subPath)
URL := parsedURL.String()
return URL, nil
// Sanitize the inputs by removing line endings
func Sanitize(s string) string {
s = strings.ReplaceAll(s, "\n", "")
s = strings.ReplaceAll(s, "\r", "")
return s
}
+4 -194
View File
@@ -17,202 +17,12 @@
package utils
import (
"errors"
"net/url"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestCompareSlice(t *testing.T) {
caseA := []string{"c", "b", "a"}
caseB := []string{"c", "b", "a"}
gotab, gotao, gotbo := ThreeWaySliceCompare(caseA, caseB)
assert.Equal(t, gotab, []string{"a", "b", "c"})
assert.Equal(t, gotao, []string(nil))
assert.Equal(t, gotbo, []string(nil))
caseA = []string{"c", "b"}
caseB = []string{"c", "a"}
gotab, gotao, gotbo = ThreeWaySliceCompare(caseA, caseB)
assert.Equal(t, gotab, []string{"c"})
assert.Equal(t, gotao, []string{"b"})
assert.Equal(t, gotbo, []string{"a"})
caseA = []string{"c", "b"}
caseB = nil
gotab, gotao, gotbo = ThreeWaySliceCompare(caseA, caseB)
assert.Equal(t, gotab, []string(nil))
assert.Equal(t, gotao, []string{"b", "c"})
assert.Equal(t, gotbo, []string(nil))
caseA = nil
caseB = []string{"c", "b"}
gotab, gotao, gotbo = ThreeWaySliceCompare(caseA, caseB)
assert.Equal(t, gotab, []string(nil))
assert.Equal(t, gotao, []string(nil))
assert.Equal(t, gotbo, []string{"b", "c"})
}
func TestEqual(t *testing.T) {
caseA := []string{"c", "b", "a"}
caseB := []string{"c", "b", "a"}
assert.Equal(t, EqualSlice(caseA, caseB), true)
caseA = []string{"c", "a", "b"}
caseB = []string{"c", "b", "a"}
assert.Equal(t, EqualSlice(caseA, caseB), true)
caseA = []string{"c", "a", "b"}
caseB = []string{"b", "a", "c"}
assert.Equal(t, EqualSlice(caseA, caseB), true)
caseA = []string{"c", "a", "b"}
caseB = []string{"b", "a", "c", "d"}
assert.Equal(t, EqualSlice(caseA, caseB), false)
caseA = []string{}
caseB = []string{}
assert.Equal(t, EqualSlice(caseA, caseB), true)
caseA = []string{}
caseB = []string{"b", "a", "c"}
assert.Equal(t, EqualSlice(caseA, caseB), false)
}
func TestSliceIncludeSlice(t *testing.T) {
caseA := []string{"b", "a", "c"}
caseB := []string{}
assert.Equal(t, SliceIncludeSlice(caseA, caseB), true)
caseA = []string{"b", "a", "c"}
caseB = []string{"b"}
assert.Equal(t, SliceIncludeSlice(caseA, caseB), true)
caseA = []string{"b", "a", "c"}
caseB = []string{"b", "c"}
assert.Equal(t, SliceIncludeSlice(caseA, caseB), true)
caseA = []string{"b", "a", "c"}
caseB = []string{"b", "c", "d"}
assert.Equal(t, SliceIncludeSlice(caseA, caseB), false)
caseA = []string{"b", "a", "c"}
caseB = []string{"b", "c", "a"}
assert.Equal(t, SliceIncludeSlice(caseA, caseB), true)
}
func TestJoinURL(t *testing.T) {
testcase := []struct {
baseURL string
subPath string
expectedUrl string
err error
}{
{
baseURL: "https://www.kubevela.com",
subPath: "index.yaml",
expectedUrl: "https://www.kubevela.com/index.yaml",
err: nil,
},
{
baseURL: "http://www.kubevela.com",
subPath: "index.yaml",
expectedUrl: "http://www.kubevela.com/index.yaml",
err: nil,
},
{
baseURL: "0x7f:",
subPath: "index.yaml",
expectedUrl: "",
err: &url.Error{Op: "parse", URL: "0x7f:", Err: errors.New("first path segment in URL cannot contain colon")},
},
}
for _, tc := range testcase {
url, err := JoinURL(tc.baseURL, tc.subPath)
assert.Equal(t, tc.expectedUrl, url)
assert.Equal(t, tc.err, err)
}
}
func TestToString(t *testing.T) {
type Obj struct {
k string
}
obj := &Obj{"foo"}
boolPtr := true
caseA := []struct {
input interface{}
expect string
}{
{int(666), "666"},
{int8(6), "6"},
{int16(6), "6"},
{int32(6), "6"},
{int64(6), "6"},
{uint(6), "6"},
{uint8(6), "6"},
{uint16(6), "6"},
{uint32(6), "6"},
{uint64(6), "6"},
{float32(3.14), "3.14"},
{float64(3.14), "3.14"},
{true, "true"},
{false, "false"},
{&boolPtr, "true"},
{nil, ""},
{[]byte("one time"), "one time"},
{"one more time", "one more time"},
{obj, ""},
}
for _, test := range caseA {
v := ToString(test.input)
assert.Equal(t, test.expect, v)
}
}
func TestStringsContain(t *testing.T) {
type args struct {
items []string
source string
}
tests := []struct {
name string
args args
want bool
}{
{
name: "test empty items should not contain any string",
args: args{
items: []string{},
source: "foo",
},
want: false,
},
{
name: "test items should contain source",
args: args{
items: []string{"foo", "bar"},
source: "foo",
},
want: true,
},
{
name: "test items should not contain source",
args: args{
items: []string{"foo", "bar"},
source: "baz",
},
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equalf(t, tt.want, StringsContain(tt.args.items, tt.args.source), "StringsContain(%v, %v)", tt.args.items, tt.args.source)
})
}
func TestSanitize(t *testing.T) {
s := "abc\ndef\rgh"
require.Equal(t, "abcdefgh", Sanitize(s))
}
-9
View File
@@ -54,15 +54,6 @@ func GetVelaHomeDir() (string, error) {
return velaHome, nil
}
// GetDefaultFrontendDir return default vela frontend dir
func GetDefaultFrontendDir() (string, error) {
home, err := GetVelaHomeDir()
if err != nil {
return "", err
}
return filepath.Join(home, "frontend"), nil
}
// GetCapCenterDir return cap center dir
func GetCapCenterDir() (string, error) {
home, err := GetVelaHomeDir()
+13
View File
@@ -19,6 +19,7 @@ package utils
import (
"fmt"
"net/url"
"path"
"regexp"
)
@@ -70,3 +71,15 @@ func IsValidURL(strURL string) bool {
}
return true
}
// JoinURL join baseURL and subPath to be new URL
func JoinURL(baseURL, subPath string) (string, error) {
parsedURL, err := url.Parse(baseURL)
if err != nil {
return "", err
}
parsedURL.RawPath = path.Join(parsedURL.RawPath, subPath)
parsedURL.Path = path.Join(parsedURL.Path, subPath)
URL := parsedURL.String()
return URL, nil
}
+36
View File
@@ -17,6 +17,8 @@ limitations under the License.
package utils
import (
"fmt"
"net/url"
"testing"
"github.com/stretchr/testify/assert"
@@ -113,3 +115,37 @@ func TestIsValidURL(t *testing.T) {
})
}
}
func TestJoinURL(t *testing.T) {
testcase := []struct {
baseURL string
subPath string
expectedUrl string
err error
}{
{
baseURL: "https://www.kubevela.com",
subPath: "index.yaml",
expectedUrl: "https://www.kubevela.com/index.yaml",
err: nil,
},
{
baseURL: "http://www.kubevela.com",
subPath: "index.yaml",
expectedUrl: "http://www.kubevela.com/index.yaml",
err: nil,
},
{
baseURL: "0x7f:",
subPath: "index.yaml",
expectedUrl: "",
err: &url.Error{Op: "parse", URL: "0x7f:", Err: fmt.Errorf("first path segment in URL cannot contain colon")},
},
}
for _, tc := range testcase {
url, err := JoinURL(tc.baseURL, tc.subPath)
assert.Equal(t, tc.expectedUrl, url)
assert.Equal(t, tc.err, err)
}
}