github.com/theishshah/operator-sdk@v0.6.0/pkg/scaffold/olm-catalog/config.go (about)

     1  // Copyright 2018 The Operator-SDK Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package catalog
    16  
    17  import (
    18  	"fmt"
    19  	"io/ioutil"
    20  	"os"
    21  	"path/filepath"
    22  
    23  	"github.com/operator-framework/operator-sdk/pkg/scaffold"
    24  
    25  	"github.com/ghodss/yaml"
    26  )
    27  
    28  // CSVConfig is a configuration file for CSV composition. Its fields contain
    29  // file path information.
    30  type CSVConfig struct {
    31  	// The operator manifest file path. Defaults to deploy/operator.yaml.
    32  	OperatorPath string `json:"operator-path,omitempty"`
    33  	// The RBAC role manifest file path. Defaults to deploy/role.yaml.
    34  	RolePath string `json:"role-path,omitempty"`
    35  	// A list of CRD and CR manifest file paths. Defaults to deploy/crds.
    36  	CRDCRPaths []string `json:"crd-cr-paths,omitempty"`
    37  }
    38  
    39  // TODO: discuss case of no config file at default path: write new file or not.
    40  func GetCSVConfig(cfgFile string) (*CSVConfig, error) {
    41  	cfg := &CSVConfig{}
    42  	if _, err := os.Stat(cfgFile); err == nil {
    43  		cfgData, err := ioutil.ReadFile(cfgFile)
    44  		if err != nil {
    45  			return nil, err
    46  		}
    47  		if err = yaml.Unmarshal(cfgData, cfg); err != nil {
    48  			return nil, err
    49  		}
    50  	} else if !os.IsNotExist(err) {
    51  		return nil, err
    52  	}
    53  
    54  	if err := cfg.setFields(); err != nil {
    55  		return nil, err
    56  	}
    57  	return cfg, nil
    58  }
    59  
    60  const yamlExt = ".yaml"
    61  
    62  func (c *CSVConfig) setFields() error {
    63  	if c.OperatorPath == "" {
    64  		info, err := (&scaffold.Operator{}).GetInput()
    65  		if err != nil {
    66  			return err
    67  		}
    68  		c.OperatorPath = info.Path
    69  	}
    70  
    71  	if c.RolePath == "" {
    72  		info, err := (&scaffold.Role{}).GetInput()
    73  		if err != nil {
    74  			return err
    75  		}
    76  		c.RolePath = info.Path
    77  	}
    78  
    79  	if len(c.CRDCRPaths) == 0 {
    80  		paths, err := getManifestPathsFromDir(scaffold.CRDsDir)
    81  		if err != nil {
    82  			return err
    83  		}
    84  		c.CRDCRPaths = paths
    85  	} else {
    86  		// Allow user to specify a list of dirs to search. Avoid duplicate files.
    87  		paths, seen := make([]string, 0), make(map[string]struct{})
    88  		for _, path := range c.CRDCRPaths {
    89  			info, err := os.Stat(path)
    90  			if err != nil {
    91  				return err
    92  			}
    93  			if info.IsDir() {
    94  				tmpPaths, err := getManifestPathsFromDir(path)
    95  				if err != nil {
    96  					return err
    97  				}
    98  				for _, p := range tmpPaths {
    99  					if _, ok := seen[p]; !ok {
   100  						paths = append(paths, p)
   101  						seen[p] = struct{}{}
   102  					}
   103  				}
   104  			} else if filepath.Ext(path) == yamlExt {
   105  				if _, ok := seen[path]; !ok {
   106  					paths = append(paths, path)
   107  					seen[path] = struct{}{}
   108  				}
   109  			}
   110  		}
   111  		c.CRDCRPaths = paths
   112  	}
   113  
   114  	return nil
   115  }
   116  
   117  func getManifestPathsFromDir(dir string) (paths []string, err error) {
   118  	err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
   119  		if err != nil {
   120  			return err
   121  		}
   122  		if info == nil {
   123  			return fmt.Errorf("file info for %s was nil", path)
   124  		}
   125  		if !info.IsDir() && filepath.Ext(path) == yamlExt {
   126  			paths = append(paths, path)
   127  		}
   128  		return nil
   129  	})
   130  	if err != nil {
   131  		return nil, err
   132  	}
   133  	return paths, nil
   134  }