github.com/munnerz/test-infra@v0.0.0-20190108210205-ce3d181dc989/prow/cmd/config-bootstrapper/main.go (about) 1 /* 2 Copyright 2018 The Kubernetes 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 main 18 19 import ( 20 "errors" 21 "flag" 22 "io/ioutil" 23 "os" 24 "path/filepath" 25 26 "github.com/sirupsen/logrus" 27 28 "k8s.io/test-infra/prow/config" 29 prowflagutil "k8s.io/test-infra/prow/flagutil" 30 "k8s.io/test-infra/prow/github" 31 "k8s.io/test-infra/prow/logrusutil" 32 "k8s.io/test-infra/prow/plugins" 33 "k8s.io/test-infra/prow/plugins/updateconfig" 34 ) 35 36 type options struct { 37 sourcePath string 38 39 configPath string 40 jobConfigPath string 41 pluginConfig string 42 43 dryRun bool 44 kubernetes prowflagutil.KubernetesOptions 45 } 46 47 func gatherOptions() options { 48 o := options{} 49 fs := flag.NewFlagSet(os.Args[0], flag.ExitOnError) 50 51 fs.StringVar(&o.sourcePath, "source-path", "", "Path to root of source directory to use for config updates.") 52 53 fs.StringVar(&o.configPath, "config-path", "/etc/config/config.yaml", "Path to config.yaml.") 54 fs.StringVar(&o.jobConfigPath, "job-config-path", "", "Path to prow job configs.") 55 fs.StringVar(&o.pluginConfig, "plugin-config", "/etc/plugins/plugins.yaml", "Path to plugin config file.") 56 57 fs.BoolVar(&o.dryRun, "dry-run", true, "Whether or not to make mutating API calls to GitHub.") 58 o.kubernetes.AddFlags(fs) 59 60 fs.Parse(os.Args[1:]) 61 return o 62 } 63 64 func (o *options) Validate() error { 65 if o.sourcePath == "" { 66 return errors.New("--source-path must be provided") 67 } 68 69 if err := o.kubernetes.Validate(o.dryRun); err != nil { 70 return err 71 } 72 73 return nil 74 } 75 76 func main() { 77 o := gatherOptions() 78 if err := o.Validate(); err != nil { 79 logrus.WithError(err).Fatal("Invalid options") 80 } 81 82 logrus.SetFormatter( 83 logrusutil.NewDefaultFieldsFormatter(nil, logrus.Fields{"component": "config-bootstrapper"}), 84 ) 85 86 configAgent := &config.Agent{} 87 if err := configAgent.Start(o.configPath, o.jobConfigPath); err != nil { 88 logrus.WithError(err).Fatal("Error starting config agent.") 89 } 90 91 pluginAgent := &plugins.ConfigAgent{} 92 if err := pluginAgent.Start(o.pluginConfig); err != nil { 93 logrus.WithError(err).Fatal("Error starting plugin configuration agent.") 94 } 95 96 kubeClient, err := o.kubernetes.Client(configAgent.Config().ProwJobNamespace, o.dryRun) 97 if err != nil { 98 logrus.WithError(err).Fatal("Error getting kube client.") 99 } 100 101 // act like the whole repo just got committed 102 var changes []github.PullRequestChange 103 filepath.Walk(o.sourcePath, func(path string, info os.FileInfo, err error) error { 104 if info.IsDir() { 105 return nil 106 } 107 // we know path will be below sourcePath, but we can't 108 // communicate that to the filepath module. We can ignore 109 // this error as we can be certain it won't occur 110 if relPath, err := filepath.Rel(o.sourcePath, path); err == nil { 111 changes = append(changes, github.PullRequestChange{ 112 Filename: filepath.Join(relPath, info.Name()), 113 Status: github.PullRequestFileAdded, 114 }) 115 } else { 116 logrus.WithError(err).Warn("unexpected error determining relative path to file") 117 } 118 return nil 119 }) 120 121 for cm, data := range updateconfig.FilterChanges(pluginAgent.Config().ConfigUpdater.Maps, changes, logrus.NewEntry(logrus.StandardLogger())) { 122 logger := logrus.WithFields(logrus.Fields{"configmap": map[string]string{"name": cm.Name, "namespace": cm.Namespace}}) 123 if err := updateconfig.Update(&osFileGetter{root: o.sourcePath}, kubeClient, cm.Name, cm.Namespace, data); err != nil { 124 logger.WithError(err).Error("failed to update config on cluster") 125 } 126 } 127 } 128 129 type osFileGetter struct { 130 root string 131 } 132 133 func (g *osFileGetter) GetFile(filename string) ([]byte, error) { 134 return ioutil.ReadFile(filepath.Join(g.root, filename)) 135 }