github.com/shipa-corp/ketch@v0.6.0/cmd/ketch/configuration/configuration.go (about)

     1  package configuration
     2  
     3  import (
     4  	"log"
     5  	"os"
     6  	"path/filepath"
     7  
     8  	"github.com/BurntSushi/toml"
     9  	"k8s.io/apimachinery/pkg/runtime"
    10  	"k8s.io/cli-runtime/pkg/genericclioptions"
    11  	"k8s.io/client-go/dynamic"
    12  	"k8s.io/client-go/kubernetes"
    13  	clientgoscheme "k8s.io/client-go/kubernetes/scheme"
    14  	cmdutil "k8s.io/kubectl/pkg/cmd/util"
    15  	"sigs.k8s.io/controller-runtime/pkg/client"
    16  
    17  	ketchv1 "github.com/shipa-corp/ketch/internal/api/v1beta1"
    18  	"github.com/shipa-corp/ketch/internal/controllers"
    19  	"github.com/shipa-corp/ketch/internal/templates"
    20  )
    21  
    22  var (
    23  	scheme = runtime.NewScheme()
    24  )
    25  
    26  func init() {
    27  	_ = clientgoscheme.AddToScheme(scheme)
    28  	_ = ketchv1.AddToScheme()(scheme)
    29  }
    30  
    31  // Configuration provides methods to get initialized clients.
    32  type Configuration struct {
    33  	cli     client.Client
    34  	storage *templates.Storage
    35  }
    36  
    37  // KetchConfig contains all the values present in the config.toml
    38  type KetchConfig struct {
    39  	AdditionalBuilders []AdditionalBuilder `toml:"additional-builders,omitempty"`
    40  	DefaultBuilder     string              `toml:"default-builder,omitempty"`
    41  }
    42  
    43  // AdditionalBuilder contains the information of any user added builders
    44  type AdditionalBuilder struct {
    45  	Vendor      string `toml:"vendor" json:"vendor" yaml:"vendor"`
    46  	Image       string `toml:"image" json:"image" yaml:"image"`
    47  	Description string `toml:"description" json:"description" yaml:"description"`
    48  }
    49  
    50  // Client returns initialized controller-runtime's Client to perform CRUD operations on Kubernetes objects.
    51  func (cfg *Configuration) Client() client.Client {
    52  	if cfg.cli != nil {
    53  		return cfg.cli
    54  	}
    55  	configFlags := genericclioptions.NewConfigFlags(true)
    56  	factory := cmdutil.NewFactory(configFlags)
    57  	kubeCfg, err := factory.ToRESTConfig()
    58  	if err != nil {
    59  		log.Fatalf("failed to create kubernetes client: %v", err)
    60  	}
    61  	cfg.cli, err = client.New(kubeCfg, client.Options{Scheme: scheme})
    62  	if err != nil {
    63  		log.Fatalf("failed to create kubernetes client: %v", err)
    64  	}
    65  	return cfg.cli
    66  }
    67  
    68  // KubernetesClient returns kubernetes typed client. It's used to work with standard kubernetes types.
    69  func (cfg *Configuration) KubernetesClient() kubernetes.Interface {
    70  	configFlags := genericclioptions.NewConfigFlags(true)
    71  	factory := cmdutil.NewFactory(configFlags)
    72  	kubeCfg, err := factory.ToRESTConfig()
    73  	if err != nil {
    74  		log.Fatalf("failed to create kubernetes client: %v", err)
    75  	}
    76  	clientset, err := kubernetes.NewForConfig(kubeCfg)
    77  	if err != nil {
    78  		log.Fatalf("failed to create kubernetes client: %v", err)
    79  	}
    80  	return clientset
    81  }
    82  
    83  // Client returns initialized templates.Client to perform CRUD operations on templates.
    84  func (cfg *Configuration) Storage() templates.Client {
    85  	if cfg.storage != nil {
    86  		return cfg.storage
    87  	}
    88  	cfg.storage = templates.NewStorage(cfg.Client(), controllers.KetchNamespace)
    89  	return cfg.storage
    90  }
    91  
    92  // DynamicClient returns kubernetes dynamic client. It's used to work with CRDs for which we don't have go types like ClusterIssuer.
    93  func (cfg *Configuration) DynamicClient() dynamic.Interface {
    94  	flags := genericclioptions.NewConfigFlags(true)
    95  	factory := cmdutil.NewFactory(flags)
    96  	conf, err := factory.ToRESTConfig()
    97  	if err != nil {
    98  		log.Fatalf("failed to create kubernetes client: %v", err)
    99  	}
   100  	i, err := dynamic.NewForConfig(conf)
   101  	if err != nil {
   102  		log.Fatalf("failed to create kubernetes client: %v", err)
   103  	}
   104  	return i
   105  }
   106  
   107  // DefaultConfigPath returns the path to the config.toml file
   108  func DefaultConfigPath() (string, error) {
   109  	home, err := ketchHome()
   110  	if err != nil {
   111  		return "", err
   112  	}
   113  	return filepath.Join(home, "config.toml"), nil
   114  }
   115  
   116  func ketchHome() (string, error) {
   117  	ketchHome := os.Getenv("KETCH_HOME")
   118  	if ketchHome == "" {
   119  		home, err := os.UserHomeDir()
   120  		if err != nil {
   121  			return "", err
   122  		}
   123  		ketchHome = filepath.Join(home, ".ketch")
   124  	}
   125  	return ketchHome, nil
   126  }
   127  
   128  // Read returns a Configuration containing the unmarshalled config.toml file contents
   129  func Read(path string) KetchConfig {
   130  	var ketchConfig KetchConfig
   131  
   132  	_, err := toml.DecodeFile(path, &ketchConfig)
   133  	if err != nil && !os.IsNotExist(err) {
   134  		return KetchConfig{}
   135  	}
   136  	return ketchConfig
   137  }
   138  
   139  //Write writes the provided KetchConfig to the given path. In the event the path is not found it will be created
   140  func Write(ketchConfig KetchConfig, path string) error {
   141  	if err := os.MkdirAll(filepath.Dir(path), 0750); err != nil {
   142  		return err
   143  	}
   144  	w, err := os.Create(path)
   145  	if err != nil {
   146  		return err
   147  	}
   148  	defer w.Close()
   149  
   150  	return toml.NewEncoder(w).Encode(ketchConfig)
   151  }