github.com/oam-dev/kubevela@v1.9.11/references/common/workload.go (about) 1 /* 2 Copyright 2021 The KubeVela Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package common 18 19 import ( 20 "fmt" 21 "strconv" 22 "strings" 23 24 "github.com/oam-dev/kubevela/pkg/utils/common" 25 26 "cuelang.org/go/cue" 27 "github.com/spf13/pflag" 28 29 "github.com/oam-dev/kubevela/references/appfile" 30 "github.com/oam-dev/kubevela/references/appfile/api" 31 "github.com/oam-dev/kubevela/references/docgen" 32 ) 33 34 // InitApplication will load Application from cluster 35 func InitApplication(namespace string, c common.Args, workloadName string, appGroup string) (*api.Application, error) { 36 var appName string 37 if appGroup != "" { 38 appName = appGroup 39 } else { 40 appName = workloadName 41 } 42 // TODO(wonderflow): we should load the existing application from cluster and convert to appfile 43 // app, err := appfile.LoadApplication(env.Namespace, appName, c) 44 // compatible application not found 45 app, err := appfile.NewEmptyApplication(namespace, c) 46 if err != nil { 47 return nil, err 48 } 49 app.Name = appName 50 51 return app, nil 52 } 53 54 // BaseComplete will construct an Application from cli parameters. 55 func BaseComplete(namespace string, c common.Args, workloadName string, appName string, flagSet *pflag.FlagSet, workloadType string) (*api.Application, error) { 56 app, err := InitApplication(namespace, c, workloadName, appName) 57 if err != nil { 58 return nil, err 59 } 60 tp, workloadData := appfile.GetWorkload(app, workloadName) 61 if tp == "" { 62 if workloadType == "" { 63 return nil, fmt.Errorf("must specify workload type for application %s", workloadName) 64 } 65 // Not exist 66 tp = workloadType 67 } 68 template, err := docgen.LoadCapabilityByName(tp, namespace, c) 69 if err != nil { 70 return nil, err 71 } 72 73 for _, v := range template.Parameters { 74 name := v.Name 75 if v.Alias != "" { 76 name = v.Alias 77 } 78 // Cli can check required flag before make a request to backend, but API itself could not, so validate flags here 79 flag := flagSet.Lookup(name) 80 if name == "name" { 81 continue 82 } 83 if flag == nil || flag.Value.String() == "" { 84 if v.Required { 85 return nil, fmt.Errorf("required flag(s) \"%s\" not set", name) 86 } 87 continue 88 } 89 // nolint:exhaustive 90 switch v.Type { 91 case cue.IntKind: 92 workloadData[v.Name], err = flagSet.GetInt64(name) 93 case cue.StringKind: 94 workloadData[v.Name], err = flagSet.GetString(name) 95 case cue.BoolKind: 96 workloadData[v.Name], err = flagSet.GetBool(name) 97 case cue.NumberKind, cue.FloatKind: 98 workloadData[v.Name], err = flagSet.GetFloat64(name) 99 default: 100 // Currently we don't support get value from complex type 101 continue 102 } 103 if err != nil { 104 if strings.Contains(err.Error(), "of flag of type string") { 105 data, _ := flagSet.GetString(name) 106 // nolint:exhaustive 107 switch v.Type { 108 case cue.IntKind: 109 workloadData[v.Name], err = strconv.ParseInt(data, 10, 64) 110 case cue.BoolKind: 111 workloadData[v.Name], err = strconv.ParseBool(data) 112 case cue.NumberKind, cue.FloatKind: 113 workloadData[v.Name], err = strconv.ParseFloat(data, 64) 114 default: 115 return nil, fmt.Errorf("should not get string from type(%s) for parameter \"%s\"", v.Type.String(), name) 116 } 117 if err != nil { 118 return nil, fmt.Errorf("get flag(s) \"%s\" err %w", v.Name, err) 119 } 120 continue 121 } 122 return nil, fmt.Errorf("get flag(s) \"%s\" err %w", v.Name, err) 123 } 124 } 125 if err = appfile.SetWorkload(app, workloadName, tp, workloadData); err != nil { 126 return app, err 127 } 128 return app, nil 129 }