github.com/billybanfield/evergreen@v0.0.0-20170525200750-eeee692790f7/plugin/builtin/expansions/expansions_plugin.go (about) 1 package expansions 2 3 import ( 4 "fmt" 5 "net/http" 6 "path/filepath" 7 8 "github.com/evergreen-ci/evergreen/model" 9 "github.com/evergreen-ci/evergreen/plugin" 10 "github.com/mitchellh/mapstructure" 11 "github.com/mongodb/grip/slogger" 12 "github.com/pkg/errors" 13 ) 14 15 func init() { 16 plugin.Publish(&ExpansionsPlugin{}) 17 } 18 19 const ( 20 ExpansionsPluginName = "expansions" 21 UpdateVarsCmdName = "update" 22 ) 23 24 // ExpansionsPlugin handles updating expansions in a task at runtime. 25 type ExpansionsPlugin struct{} 26 27 // Name fulfills the Plugin interface. 28 func (self *ExpansionsPlugin) Name() string { 29 return ExpansionsPluginName 30 } 31 32 // GetRoutes registers the API handler for fetching expansion variables 33 // from the API server. 34 func (self *ExpansionsPlugin) GetAPIHandler() http.Handler { 35 r := http.NewServeMux() 36 r.HandleFunc(fmt.Sprintf("/%v", FetchVarsRoute), FetchVarsHandler) // GET 37 r.HandleFunc("/", http.NotFound) 38 return r 39 } 40 41 func (self *ExpansionsPlugin) Configure(map[string]interface{}) error { 42 return nil 43 } 44 45 // NewCommand fulfills the Plugin interface. 46 func (self *ExpansionsPlugin) NewCommand(cmdName string) (plugin.Command, error) { 47 if cmdName == UpdateVarsCmdName { 48 return &UpdateCommand{}, nil 49 } else if cmdName == FetchVarsCmdname { 50 return &FetchVarsCommand{}, nil 51 } 52 return nil, &plugin.ErrUnknownCommand{cmdName} 53 } 54 55 // UpdateCommand reads in a set of new expansions and updates the 56 // task's expansions at runtime. UpdateCommand can take a list 57 // of update expansion pairs and/or a file of expansion pairs 58 type UpdateCommand struct { 59 // Key-value pairs for updating the task's parameters with 60 Updates []PutCommandParams `mapstructure:"updates"` 61 62 // Filename for a yaml file containing expansion updates 63 // in the form of 64 // "expansion_key: expansions_value" 65 YamlFile string `mapstructure:"file"` 66 } 67 68 // PutCommandParams are pairings of expansion names 69 // and the value they expand to 70 type PutCommandParams struct { 71 // The name of the expansion 72 Key string 73 74 // The expanded value 75 Value string 76 77 // Can optionally concat a string to the end of the current value 78 Concat string 79 } 80 81 func (self *UpdateCommand) Name() string { 82 return UpdateVarsCmdName 83 } 84 85 func (self *UpdateCommand) Plugin() string { 86 return ExpansionsPluginName 87 } 88 89 // ParseParams validates the input to the UpdateCommand, returning and error 90 // if something is incorrect. Fulfills Command interface. 91 func (self *UpdateCommand) ParseParams(params map[string]interface{}) error { 92 err := mapstructure.Decode(params, self) 93 if err != nil { 94 return err 95 } 96 97 for _, item := range self.Updates { 98 if item.Key == "" { 99 return errors.Errorf("error parsing '%v' params: key must not be "+ 100 "a blank string", self.Name()) 101 } 102 } 103 104 return nil 105 } 106 107 func (self *UpdateCommand) ExecuteUpdates(conf *model.TaskConfig) error { 108 for _, update := range self.Updates { 109 if update.Concat == "" { 110 newValue, err := conf.Expansions.ExpandString(update.Value) 111 112 if err != nil { 113 return err 114 } 115 conf.Expansions.Put(update.Key, newValue) 116 } else { 117 newValue, err := conf.Expansions.ExpandString(update.Concat) 118 if err != nil { 119 return err 120 } 121 122 oldValue := conf.Expansions.Get(update.Key) 123 conf.Expansions.Put(update.Key, oldValue+newValue) 124 } 125 } 126 127 return nil 128 } 129 130 // Execute updates the expansions. Fulfills Command interface. 131 func (self *UpdateCommand) Execute(pluginLogger plugin.Logger, 132 pluginCom plugin.PluginCommunicator, conf *model.TaskConfig, stop chan bool) error { 133 134 err := self.ExecuteUpdates(conf) 135 if err != nil { 136 return err 137 } 138 139 if self.YamlFile != "" { 140 self.YamlFile, err = conf.Expansions.ExpandString(self.YamlFile) 141 if err != nil { 142 return err 143 } 144 145 pluginLogger.LogTask(slogger.INFO, "Updating expansions with keys from file: %v", self.YamlFile) 146 filename := filepath.Join(conf.WorkDir, self.YamlFile) 147 err := conf.Expansions.UpdateFromYaml(filename) 148 if err != nil { 149 return err 150 } 151 } 152 return nil 153 154 }