github.com/upcmd/up@v0.8.1-0.20230108151705-ad8b797bf04f/biz/impl/scope.go (about) 1 // Ultimate Provisioner: UP cmd 2 // Copyright (c) 2019 Stephen Cheng and contributors 3 4 /* This Source Code Form is subject to the terms of the Mozilla Public 5 * License, v. 2.0. If a copy of the MPL was not distributed with this 6 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 7 8 package impl 9 10 import ( 11 "github.com/imdario/mergo" 12 ms "github.com/mitchellh/mapstructure" 13 "github.com/mohae/deepcopy" 14 "github.com/spf13/viper" 15 "github.com/upcmd/up/model/core" 16 u "github.com/upcmd/up/utils" 17 "io/ioutil" 18 ) 19 20 type Scope struct { 21 Name string 22 Ref string 23 RefDir string 24 Members []string 25 Vars core.Cache 26 Dvars Dvars 27 } 28 29 type Scopes []Scope 30 31 type ExecProfile struct { 32 Name string 33 Ref string 34 RefDir string 35 Instance string 36 Evars EnvVars 37 //optional 38 Taskname string 39 Pure bool 40 Verbose string 41 } 42 43 type ExecProfiles []ExecProfile 44 45 func DecryptAndRegister(securetag *u.SecureSetting, dvar *Dvar, contextVars *core.Cache, mergeTarget *core.Cache) { 46 s := securetag 47 48 if s == nil { 49 u.InvalidAndPanic("check secure setting", "secure setting has to be explicit in dvar secure node, or as a default setting in upconfig.yml") 50 } 51 var encryptionkey string 52 if s.KeyRef != "" { 53 data, err := ioutil.ReadFile(s.KeyRef) 54 u.LogErrorAndExit("load secure key from ref file", err, "please fix file loading problem") 55 encryptionkey = string(data) 56 } 57 58 if s.Key != "" { 59 //use vault as first priority 60 opt := GetVault().Get(s.Key) 61 if opt == nil { 62 opt = (*contextVars).Get(s.Key) 63 } 64 if opt != nil { 65 encryptionkey = opt.(string) 66 } 67 } 68 69 encrypted := dvar.Rendered 70 if encrypted != "" && encryptionkey != "" { 71 data := map[string]string{"enc_key": encryptionkey, "encrypted": encrypted} 72 decrypted := Render("{{ decryptAES .enc_key .encrypted}}", data) 73 secureName := u.Spf("%s_%s", "secure", dvar.Name) 74 (*mergeTarget).Put(secureName, decrypted) 75 } else { 76 u.InvalidAndPanic("dvar decrypt", u.Spf("please double check secure settings for [%s]\nyou might need to associate an instance id or an exec profile", dvar.Name)) 77 } 78 79 } 80 81 func Decrypt(securetag *u.SecureSetting, dvar *Dvar, contextVars *core.Cache) string { 82 s := securetag 83 var decrypted string 84 if s == nil { 85 u.InvalidAndPanic("check secure setting", "secure setting has to be explicit in dvar secure node, or as a default setting in upconfig.yml") 86 } 87 var encryptionkey string 88 if s.KeyRef != "" { 89 data, err := ioutil.ReadFile(s.KeyRef) 90 u.LogErrorAndExit("load secure key from ref file", err, "please fix file loading problem") 91 encryptionkey = string(data) 92 } 93 94 if s.Key != "" { 95 encryptionkey = (*contextVars).Get(s.Key).(string) 96 } 97 98 encrypted := dvar.Rendered 99 100 if encrypted != "" && encryptionkey != "" { 101 data := map[string]string{"enc_key": encryptionkey, "encrypted": encrypted} 102 decrypted = Render("{{ decryptAES .enc_key .encrypted}}", data) 103 } else { 104 u.InvalidAndPanic("dvar decrypt", u.Spf("please double check secure settings for [%s]\nyou might need to associate an instance id or an exec profile", dvar.Name)) 105 } 106 return decrypted 107 } 108 109 func GlobalVarsMergedWithDvars(scope *Scope) (vars *core.Cache) { 110 return VarsMergedWithDvars(scope.Name, &scope.Vars, &scope.Dvars, &(scope.Vars)) 111 } 112 113 func ScopeVarsMergedWithDvars(scope *Scope, contextMergedVars *core.Cache) *core.Cache { 114 return VarsMergedWithDvars(scope.Name, &scope.Vars, &scope.Dvars, contextMergedVars) 115 } 116 117 //given vars as base vars space to expand from, expand dvars against contextVars 118 func VarsMergedWithDvars(mark string, baseVars *core.Cache, dvars *Dvars, contextMergedVars *core.Cache) *core.Cache { 119 var mergedVars core.Cache 120 mergedVars = deepcopy.Copy(*baseVars).(core.Cache) 121 122 if dvars != nil { 123 expandedVars := dvars.Expand(mark, contextMergedVars) 124 mergo.Merge(&mergedVars, expandedVars, mergo.WithOverride) 125 } 126 127 u.Pfvvvvv("scope[%s] merged: %s", mark, u.Sppmsg(mergedVars)) 128 129 return &mergedVars 130 } 131 132 func loadRefVars(yamlroot *viper.Viper) *core.Cache { 133 scopesData := yamlroot.Get("vars") 134 vars := core.Cache{} 135 err := ms.Decode(scopesData, &vars) 136 u.Dvvvvv(vars) 137 u.LogError("load ref vars", err) 138 return &vars 139 } 140 141 func loadRefEvars(yamlroot *viper.Viper) *EnvVars { 142 evarsData := yamlroot.Get("evars") 143 vars := EnvVars{} 144 err := ms.Decode(evarsData, &vars) 145 u.Dvvvvv(vars) 146 u.LogError("load ref vars", err) 147 return &vars 148 } 149 150 //get instance vars from scope definition, eg dev 151 func (ss *Scopes) GetInstanceVars(instanceName string) *core.Cache { 152 for _, s := range *ss { 153 if s.Name == instanceName { 154 return &s.Vars 155 } 156 } 157 158 return nil 159 }