github.com/munnerz/test-infra@v0.0.0-20190108210205-ce3d181dc989/def/configmap/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  // configmap will write a configmap to --output from --data=name=/path/to/source
    18  package main
    19  
    20  import (
    21  	"bytes"
    22  	"flag"
    23  	"fmt"
    24  	"io/ioutil"
    25  	"log"
    26  	"os"
    27  	"strings"
    28  
    29  	"k8s.io/api/core/v1"
    30  	"sigs.k8s.io/yaml"
    31  )
    32  
    33  type options struct {
    34  	data      multiKeyValue
    35  	labels    multiKeyValue
    36  	name      string
    37  	namespace string
    38  	output    string
    39  }
    40  
    41  // multiKeyValue allows --key=value --key=value2
    42  type multiKeyValue map[string]string
    43  
    44  func (mkv *multiKeyValue) String() string {
    45  	var b bytes.Buffer
    46  	if mkv == nil {
    47  		return ""
    48  	}
    49  	for k, v := range *mkv {
    50  		if b.Len() > 0 {
    51  			b.WriteString(",")
    52  		}
    53  		fmt.Fprintf(&b, "%s=%s", k, v)
    54  	}
    55  	return b.String()
    56  }
    57  
    58  func (mkv *multiKeyValue) Set(v string) error {
    59  	p := strings.SplitN(v, "=", 2)
    60  	if len(p) != 2 {
    61  		return fmt.Errorf("%s does not match label=value", v)
    62  	}
    63  	if mkv == nil {
    64  		mkv = &multiKeyValue{
    65  			p[0]: p[1],
    66  		}
    67  	} else {
    68  		(*mkv)[p[0]] = p[1]
    69  	}
    70  	return nil
    71  }
    72  
    73  func flags() *options {
    74  	opt := options{
    75  		data:   multiKeyValue{},
    76  		labels: multiKeyValue{},
    77  	}
    78  	flag.StringVar(&opt.output, "output", "", "Write configmap here instead of stdout")
    79  	flag.StringVar(&opt.name, "name", "", "Name of resource")
    80  	flag.StringVar(&opt.namespace, "namespace", "", "Namespace for resource")
    81  	flag.Var(&opt.labels, "label", "Add a key=value label (repeat flag)")
    82  	flag.Var(&opt.data, "data", "Add a key=/path/to/file configmap source (repeat flag)")
    83  	flag.Parse()
    84  	return &opt
    85  }
    86  
    87  func buildConfigMap(name, namespace string, labels map[string]string, data map[string]string) (*v1.ConfigMap, error) {
    88  
    89  	var cm v1.ConfigMap
    90  	cm.TypeMeta.Kind = "ConfigMap"
    91  	cm.TypeMeta.APIVersion = "v1"
    92  	cm.ObjectMeta.Name = name
    93  	cm.ObjectMeta.Namespace = namespace
    94  	cm.ObjectMeta.Labels = labels
    95  	if len(data) > 0 {
    96  		cm.Data = map[string]string{}
    97  		for key, value := range data {
    98  			buf, err := ioutil.ReadFile(value)
    99  			if err != nil {
   100  				wd, _ := os.Getwd()
   101  				return nil, fmt.Errorf("could not read %s/%s: %v", wd, value, err)
   102  			}
   103  			cm.Data[key] = string(buf)
   104  		}
   105  	}
   106  	return &cm, nil
   107  }
   108  
   109  func main() {
   110  	opt := flags()
   111  	if opt.name == "" {
   112  		log.Fatal("Non-empty --name required")
   113  	}
   114  	cm, err := buildConfigMap(opt.name, opt.namespace, opt.labels, opt.data)
   115  	if err != nil {
   116  		log.Fatalf("Failed to create %s: %v", opt.name, err)
   117  	}
   118  	buf, err := yaml.Marshal(cm)
   119  	if err != nil {
   120  		log.Fatalf("Failed to serialize %s: %v", opt.name, err)
   121  	}
   122  	if opt.output == "" {
   123  		fmt.Print(string(buf))
   124  		return
   125  	}
   126  	err = ioutil.WriteFile(opt.output, buf, 0644)
   127  	if err != nil {
   128  		log.Fatalf("Failed to write %s: %v", opt.output, err)
   129  	}
   130  }