Create type ClusterMode string and panic only in the config validation function

This commit is contained in:
TwinProduction 2020-11-11 15:10:44 -05:00
parent ea6c788fa0
commit f406206eae
4 changed files with 37 additions and 29 deletions

View File

@ -116,8 +116,8 @@ func parseAndValidateConfigBytes(yamlBytes []byte) (config *Config, err error) {
if err != nil { if err != nil {
return return
} }
// Check if the configuration file at least has services. // Check if the configuration file at least has services configured or Kubernetes auto discovery enabled
if config == nil || config.Services == nil || len(config.Services) == 0 { if config == nil || ((config.Services == nil || len(config.Services) == 0) && (config.Kubernetes == nil || !config.Kubernetes.AutoDiscover)) {
err = ErrNoServiceInConfig err = ErrNoServiceInConfig
} else { } else {
// Note that the functions below may panic, and this is on purpose to prevent Gatus from starting with // Note that the functions below may panic, and this is on purpose to prevent Gatus from starting with
@ -132,6 +132,9 @@ func parseAndValidateConfigBytes(yamlBytes []byte) (config *Config, err error) {
func validateKubernetesConfig(config *Config) { func validateKubernetesConfig(config *Config) {
if config.Kubernetes != nil && config.Kubernetes.AutoDiscover { if config.Kubernetes != nil && config.Kubernetes.AutoDiscover {
if config.Kubernetes.ServiceTemplate == nil {
panic("kubernetes.service-template cannot be nil")
}
discoveredServices, err := k8s.DiscoverServices(config.Kubernetes) discoveredServices, err := k8s.DiscoverServices(config.Kubernetes)
if err != nil { if err != nil {
panic(err) panic(err)

View File

@ -2,6 +2,7 @@ package k8s
import ( import (
"flag" "flag"
"fmt"
"os" "os"
"path/filepath" "path/filepath"
@ -11,21 +12,22 @@ import (
"k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd"
) )
func NewClient(clusterMode string) *kubernetes.Clientset { // NewClient creates a Kubernetes client for the given ClusterMode
func NewClient(clusterMode ClusterMode) (*kubernetes.Clientset, error) {
var kubeConfig *rest.Config var kubeConfig *rest.Config
var err error
switch clusterMode { switch clusterMode {
case "in": case ClusterModeIn:
kubeConfig = getInClusterConfig() kubeConfig, err = getInClusterConfig()
case "out": case ClusterModeOut:
kubeConfig = getOutClusterConfig() kubeConfig, err = getOutClusterConfig()
default: default:
panic("invalid cluster mode") return nil, fmt.Errorf("invalid cluster mode, try '%s' or '%s'", ClusterModeIn, ClusterModeOut)
} }
clientset, err := kubernetes.NewForConfig(kubeConfig)
if err != nil { if err != nil {
panic(err.Error()) return nil, fmt.Errorf("unable to get cluster config for mode '%s': %s", clusterMode, err.Error())
} }
return clientset return kubernetes.NewForConfig(kubeConfig)
} }
func homeDir() string { func homeDir() string {
@ -35,25 +37,17 @@ func homeDir() string {
return os.Getenv("USERPROFILE") // windows return os.Getenv("USERPROFILE") // windows
} }
func getOutClusterConfig() *rest.Config { func getOutClusterConfig() (*rest.Config, error) {
var kubeconfig *string var kubeConfig *string
if home := homeDir(); home != "" { if home := homeDir(); home != "" {
kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file") kubeConfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
} else { } else {
kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file") kubeConfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
} }
flag.Parse() flag.Parse()
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig) return clientcmd.BuildConfigFromFlags("", *kubeConfig)
if err != nil {
panic(err.Error())
}
return config
} }
func getInClusterConfig() *rest.Config { func getInClusterConfig() (*rest.Config, error) {
config, err := rest.InClusterConfig() return rest.InClusterConfig()
if err != nil {
panic(err.Error())
}
return config
} }

View File

@ -10,11 +10,11 @@ type Config struct {
// ServiceTemplate Template for auto discovered services // ServiceTemplate Template for auto discovered services
ServiceTemplate *core.Service `yaml:"service-template"` ServiceTemplate *core.Service `yaml:"service-template"`
// ExcludeSuffix Ignore services with this suffix // ExcludeSuffix is a slice of service suffixes that should be ignored
ExcludeSuffix []string `yaml:"exclude-suffix"` ExcludeSuffix []string `yaml:"exclude-suffix"`
// ClusterMode to authenticate with kubernetes // ClusterMode to authenticate with kubernetes
ClusterMode string `yaml:"cluster-mode"` ClusterMode ClusterMode `yaml:"cluster-mode"`
// Namespaces from which to discover services // Namespaces from which to discover services
Namespaces []*NamespaceConfig `yaml:"namespaces"` Namespaces []*NamespaceConfig `yaml:"namespaces"`
@ -31,3 +31,11 @@ type NamespaceConfig struct {
// HealthAPI URI to append to service to reach health check API // HealthAPI URI to append to service to reach health check API
HealthAPI string `yaml:"health-api"` HealthAPI string `yaml:"health-api"`
} }
// ClusterMode is the mode to use to authenticate to Kubernetes
type ClusterMode string
const (
ClusterModeIn ClusterMode = "in"
ClusterModeOut ClusterMode = "out"
)

View File

@ -9,7 +9,10 @@ import (
// DiscoverServices return discovered services // DiscoverServices return discovered services
func DiscoverServices(kubernetesConfig *Config) ([]*core.Service, error) { func DiscoverServices(kubernetesConfig *Config) ([]*core.Service, error) {
client := NewClient(kubernetesConfig.ClusterMode) client, err := NewClient(kubernetesConfig.ClusterMode)
if err != nil {
return nil, err
}
services := make([]*core.Service, 0) services := make([]*core.Service, 0)
for _, ns := range kubernetesConfig.Namespaces { for _, ns := range kubernetesConfig.Namespaces {
kubernetesServices, err := GetKubernetesServices(client, ns.Name) kubernetesServices, err := GetKubernetesServices(client, ns.Name)