2019-01-18 01:50:10 +00:00
// Copyright 2019 the Kilo authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
2021-06-18 10:10:23 +00:00
"errors"
2019-01-18 01:50:10 +00:00
"fmt"
"os"
2021-06-15 18:53:02 +00:00
"path/filepath"
2019-01-18 01:50:10 +00:00
"strings"
2022-01-30 16:38:45 +00:00
"github.com/go-kit/kit/log"
2019-05-03 10:53:40 +00:00
"github.com/spf13/cobra"
apiextensions "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
2019-01-18 01:50:10 +00:00
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
"github.com/squat/kilo/pkg/k8s"
2019-05-03 10:53:40 +00:00
kiloclient "github.com/squat/kilo/pkg/k8s/clientset/versioned"
2019-01-18 01:50:10 +00:00
"github.com/squat/kilo/pkg/mesh"
"github.com/squat/kilo/pkg/version"
)
const (
logLevelAll = "all"
logLevelDebug = "debug"
logLevelInfo = "info"
logLevelWarn = "warn"
logLevelError = "error"
logLevelNone = "none"
)
var (
availableBackends = strings . Join ( [ ] string {
k8s . Backend ,
} , ", " )
availableGranularities = strings . Join ( [ ] string {
2019-05-07 14:34:34 +00:00
string ( mesh . LogicalGranularity ) ,
string ( mesh . FullGranularity ) ,
2021-06-18 10:10:23 +00:00
string ( mesh . AutoGranularity ) ,
2019-01-18 01:50:10 +00:00
} , ", " )
availableLogLevels = strings . Join ( [ ] string {
logLevelAll ,
logLevelDebug ,
logLevelInfo ,
logLevelWarn ,
logLevelError ,
logLevelNone ,
} , ", " )
opts struct {
backend mesh . Backend
granularity mesh . Granularity
2022-01-30 16:38:45 +00:00
port int
2019-01-18 01:50:10 +00:00
}
2020-12-11 14:44:20 +00:00
backend string
granularity string
kubeconfig string
topologyLabel string
2019-01-18 01:50:10 +00:00
)
func runRoot ( _ * cobra . Command , _ [ ] string ) error {
2022-01-30 16:38:45 +00:00
if opts . port < 1 || opts . port > 1 << 16 - 1 {
return fmt . Errorf ( "invalid port: port mus be in range [%d:%d], but got %d" , 1 , 1 << 16 - 1 , opts . port )
}
2019-01-18 01:50:10 +00:00
opts . granularity = mesh . Granularity ( granularity )
switch opts . granularity {
2019-05-07 14:34:34 +00:00
case mesh . LogicalGranularity :
case mesh . FullGranularity :
2021-06-18 10:10:23 +00:00
case mesh . AutoGranularity :
2019-01-18 01:50:10 +00:00
default :
return fmt . Errorf ( "mesh granularity %v unknown; posible values are: %s" , granularity , availableGranularities )
}
switch backend {
case k8s . Backend :
config , err := clientcmd . BuildConfigFromFlags ( "" , kubeconfig )
if err != nil {
return fmt . Errorf ( "failed to create Kubernetes config: %v" , err )
}
2019-05-03 10:53:40 +00:00
c := kubernetes . NewForConfigOrDie ( config )
kc := kiloclient . NewForConfigOrDie ( config )
ec := apiextensions . NewForConfigOrDie ( config )
2022-01-30 16:38:45 +00:00
opts . backend = k8s . New ( c , kc , ec , topologyLabel , log . NewNopLogger ( ) )
2019-01-18 01:50:10 +00:00
default :
return fmt . Errorf ( "backend %v unknown; posible values are: %s" , backend , availableBackends )
}
2019-05-03 10:53:40 +00:00
if err := opts . backend . Nodes ( ) . Init ( make ( chan struct { } ) ) ; err != nil {
return fmt . Errorf ( "failed to initialize node backend: %v" , err )
}
if err := opts . backend . Peers ( ) . Init ( make ( chan struct { } ) ) ; err != nil {
return fmt . Errorf ( "failed to initialize peer backend: %v" , err )
2019-01-18 01:50:10 +00:00
}
return nil
}
func main ( ) {
cmd := & cobra . Command {
Use : "kgctl" ,
Short : "Manage a Kilo network" ,
Long : "" ,
PersistentPreRunE : runRoot ,
Version : version . Version ,
2021-09-07 09:07:03 +00:00
SilenceErrors : true ,
2019-01-18 01:50:10 +00:00
}
cmd . PersistentFlags ( ) . StringVar ( & backend , "backend" , k8s . Backend , fmt . Sprintf ( "The backend for the mesh. Possible values: %s" , availableBackends ) )
2021-06-18 10:10:23 +00:00
cmd . PersistentFlags ( ) . StringVar ( & granularity , "mesh-granularity" , string ( mesh . AutoGranularity ) , fmt . Sprintf ( "The granularity of the network mesh to create. Possible values: %s" , availableGranularities ) )
2021-06-15 18:53:02 +00:00
defaultKubeconfig := os . Getenv ( "KUBECONFIG" )
if _ , err := os . Stat ( defaultKubeconfig ) ; os . IsNotExist ( err ) {
defaultKubeconfig = filepath . Join ( os . Getenv ( "HOME" ) , ".kube/config" )
}
cmd . PersistentFlags ( ) . StringVar ( & kubeconfig , "kubeconfig" , defaultKubeconfig , "Path to kubeconfig." )
2022-01-30 16:38:45 +00:00
cmd . PersistentFlags ( ) . IntVar ( & opts . port , "port" , mesh . DefaultKiloPort , "The WireGuard port over which the nodes communicate." )
2020-12-14 08:20:53 +00:00
cmd . PersistentFlags ( ) . StringVar ( & topologyLabel , "topology-label" , k8s . RegionLabelKey , "Kubernetes node label used to group nodes into logical locations." )
2019-01-18 01:50:10 +00:00
for _ , subCmd := range [ ] * cobra . Command {
2019-05-03 10:53:40 +00:00
graph ( ) ,
showConf ( ) ,
2019-01-18 01:50:10 +00:00
} {
cmd . AddCommand ( subCmd )
}
if err := cmd . Execute ( ) ; err != nil {
fmt . Fprintf ( os . Stderr , "%v\n" , err )
os . Exit ( 1 )
}
}
2021-06-18 10:10:23 +00:00
func optainGranularity ( gr mesh . Granularity , ns [ ] * mesh . Node ) ( mesh . Granularity , error ) {
if gr == mesh . AutoGranularity {
if len ( ns ) == 0 {
return gr , errors . New ( "could not get any nodes" )
}
ret := mesh . Granularity ( ns [ 0 ] . Granularity )
switch ret {
case mesh . LogicalGranularity :
case mesh . FullGranularity :
default :
return ret , fmt . Errorf ( "mesh granularity %v is not supported" , opts . granularity )
}
return ret , nil
}
return gr , nil
}