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  }