mirror of
https://github.com/cloudnativelabs/kube-router.git
synced 2025-11-20 20:41:06 +01:00
* Makefile: Add lint using golangci-lint
* build/travis-test.sh: Run lint step
* metrics_controller: Lint
pkg/metrics/metrics_controller.go:150:2: `mu` is unused (structcheck)
mu sync.Mutex
^
pkg/metrics/metrics_controller.go:151:2: `nodeIP` is unused (structcheck)
nodeIP net.IP
^
* network_service_graceful: Lint
pkg/controllers/proxy/network_service_graceful.go:21:6: `gracefulQueueItem` is unused (deadcode)
type gracefulQueueItem struct {
^
pkg/controllers/proxy/network_service_graceful.go:22:2: `added` is unused (structcheck)
added time.Time
^
pkg/controllers/proxy/network_service_graceful.go:23:2: `service` is unused (structcheck)
service *ipvs.Service
^
* network_services_controller_test: Lint
pkg/controllers/proxy/network_services_controller_test.go:80:6: func `logf` is unused (unused)
* ecmp_vip: Lint
pkg/controllers/routing/ecmp_vip.go:208:4: S1023: redundant `return` statement (gosimple)
return
^
* bgp_peers: Lint
pkg/controllers/routing/bgp_peers.go:331:4: S1023: redundant `return` statement (gosimple)
return
^
* bgp_policies: Lint
pkg/controllers/routing/bgp_policies.go:80:3: S1011: should replace loop with `externalBgpPeers = append(externalBgpPeers, nrc.nodePeerRouters...)` (gosimple)
for _, peer := range nrc.nodePeerRouters {
^
pkg/controllers/routing/bgp_policies.go:23:20: ineffectual assignment to `err` (ineffassign)
podCidrPrefixSet, err := table.NewPrefixSet(config.PrefixSet{
^
pkg/controllers/routing/bgp_policies.go:42:22: ineffectual assignment to `err` (ineffassign)
clusterIPPrefixSet, err := table.NewPrefixSet(config.PrefixSet{
^
pkg/controllers/routing/bgp_policies.go:33:30: Error return value of `nrc.bgpServer.AddDefinedSet` is not checked (errcheck)
nrc.bgpServer.AddDefinedSet(podCidrPrefixSet)
^
pkg/controllers/routing/bgp_policies.go:48:30: Error return value of `nrc.bgpServer.AddDefinedSet` is not checked (errcheck)
nrc.bgpServer.AddDefinedSet(clusterIPPrefixSet)
^
pkg/controllers/routing/bgp_policies.go:69:31: Error return value of `nrc.bgpServer.AddDefinedSet` is not checked (errcheck)
nrc.bgpServer.AddDefinedSet(iBGPPeerNS)
^
pkg/controllers/routing/bgp_policies.go:108:31: Error return value of `nrc.bgpServer.AddDefinedSet` is not checked (errcheck)
nrc.bgpServer.AddDefinedSet(ns)
^
pkg/controllers/routing/bgp_policies.go:120:30: Error return value of `nrc.bgpServer.AddDefinedSet` is not checked (errcheck)
nrc.bgpServer.AddDefinedSet(ns)
^
^
* network_policy_controller: Lint
pkg/controllers/netpol/network_policy_controller.go:35:2: `networkPolicyAnnotation` is unused (deadcode)
networkPolicyAnnotation = "net.beta.kubernetes.io/network-policy"
^
pkg/controllers/netpol/network_policy_controller.go:1047:4: SA9003: empty branch (staticcheck)
if err != nil {
^
pkg/controllers/netpol/network_policy_controller.go:969:10: SA4006: this value of `err` is never used (staticcheck)
chains, err := iptablesCmdHandler.ListChains("filter")
^
pkg/controllers/netpol/network_policy_controller.go:1568:4: SA4006: this value of `err` is never used (staticcheck)
err = iptablesCmdHandler.Delete("filter", "FORWARD", strconv.Itoa(i-realRuleNo))
^
pkg/controllers/netpol/network_policy_controller.go:1584:4: SA4006: this value of `err` is never used (staticcheck)
err = iptablesCmdHandler.Delete("filter", "OUTPUT", strconv.Itoa(i-realRuleNo))
^
* network_services_controller: Lint
pkg/controllers/proxy/network_services_controller.go:66:2: `h` is unused (deadcode)
h *ipvs.Handle
^
pkg/controllers/proxy/network_services_controller.go:879:23: SA1019: client.NewEnvClient is deprecated: use NewClientWithOpts(FromEnv) (staticcheck)
dockerClient, err := client.NewEnvClient()
^
pkg/controllers/proxy/network_services_controller.go:944:5: unreachable: unreachable code (govet)
glog.V(3).Infof("Waiting for tunnel interface %s to come up in the pod, retrying", KUBE_TUNNEL_IF)
^
pkg/controllers/proxy/network_services_controller.go:1289:5: S1002: should omit comparison to bool constant, can be simplified to `!hasHairpinChain` (gosimple)
if hasHairpinChain != true {
^
pkg/controllers/proxy/network_services_controller.go:1237:43: S1019: should use make(map[string][]string) instead (gosimple)
rulesNeeded := make(map[string][]string, 0)
^
pkg/controllers/proxy/network_services_controller.go:1111:4: S1023: redundant break statement (gosimple)
break
^
pkg/controllers/proxy/network_services_controller.go:1114:4: S1023: redundant break statement (gosimple)
break
^
pkg/controllers/proxy/network_services_controller.go:1117:4: S1023: redundant break statement (gosimple)
break
^
pkg/controllers/proxy/network_services_controller.go:445:21: Error return value of `nsc.publishMetrics` is not checked (errcheck)
nsc.publishMetrics(nsc.serviceMap)
^
pkg/controllers/proxy/network_services_controller.go:1609:9: Error return value of `h.Write` is not checked (errcheck)
h.Write([]byte(ip + "-" + protocol + "-" + port))
^
pkg/controllers/proxy/network_services_controller.go:912:13: Error return value of `netns.Set` is not checked (errcheck)
netns.Set(hostNetworkNamespaceHandle)
^
pkg/controllers/proxy/network_services_controller.go:926:13: Error return value of `netns.Set` is not checked (errcheck)
netns.Set(hostNetworkNamespaceHandle)
^
pkg/controllers/proxy/network_services_controller.go:950:13: Error return value of `netns.Set` is not checked (errcheck)
netns.Set(hostNetworkNamespaceHandle)
^
pkg/controllers/proxy/network_services_controller.go:641:9: SA4006: this value of `err` is never used (staticcheck)
addrs, err := getAllLocalIPs()
^
* network_routes_controller: Lint
pkg/controllers/routing/network_routes_controller.go:340:2: S1000: should use for range instead of for { select {} } (gosimple)
for {
^
pkg/controllers/routing/network_routes_controller.go:757:22: Error return value of `nrc.bgpServer.Stop` is not checked (errcheck)
nrc.bgpServer.Stop()
^
pkg/controllers/routing/network_routes_controller.go:770:22: Error return value of `nrc.bgpServer.Stop` is not checked (errcheck)
nrc.bgpServer.Stop()
^
pkg/controllers/routing/network_routes_controller.go:782:23: Error return value of `nrc.bgpServer.Stop` is not checked (errcheck)
nrc.bgpServer.Stop()
^
pkg/controllers/routing/network_routes_controller.go:717:12: Error return value of `g.Serve` is not checked (errcheck)
go g.Serve()
* ipset: Lint
pkg/utils/ipset.go:243:23: Error return value of `entry.Set.Parent.Save` is not checked (errcheck)
entry.Set.Parent.Save()
^
* pkg/cmd/kube-router: Lint
pkg/cmd/kube-router.go:214:26: SA1006: printf-style function with dynamic format string and no further arguments should use print-style function instead (staticcheck)
fmt.Fprintf(os.Stderr, output)
^
pkg/cmd/kube-router.go:184:15: SA1017: the channel used with signal.Notify should be buffered (staticcheck)
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
^
pkg/cmd/kube-router.go:94:17: Error return value of `hc.RunServer` is not checked (errcheck)
go hc.RunServer(stopCh, &wg)
^
pkg/cmd/kube-router.go:112:16: Error return value of `hc.RunCheck` is not checked (errcheck)
go hc.RunCheck(healthChan, stopCh, &wg)
^
pkg/cmd/kube-router.go:121:12: Error return value of `mc.Run` is not checked (errcheck)
go mc.Run(healthChan, stopCh, &wg)
^
* cmd/kube-router/kube-router: Lint
cmd/kube-router/kube-router.go:31:24: Error return value of `flag.CommandLine.Parse` is not checked (errcheck)
flag.CommandLine.Parse([]string{})
^
cmd/kube-router/kube-router.go:33:10: Error return value of `flag.Set` is not checked (errcheck)
flag.Set("logtostderr", "true")
^
cmd/kube-router/kube-router.go:34:10: Error return value of `flag.Set` is not checked (errcheck)
flag.Set("v", config.VLevel)
^
cmd/kube-router/kube-router.go:62:27: SA1006: printf-style function with dynamic format string and no further arguments should use print-style function instead (staticcheck)
fmt.Fprintf(os.Stdout, http.ListenAndServe("0.0.0.0:6060", nil).Error())
^
* kube-router_test: Lint
cmd/kube-router/kube-router_test.go:21:10: Error return value of `io.Copy` is not checked (errcheck)
io.Copy(stderrBuf, stderrR)
^
cmd/kube-router/kube-router_test.go:40:17: Error return value of `docBuf.ReadFrom` is not checked (errcheck)
docBuf.ReadFrom(docF)
^
* service_endpoints_sync: Lint
pkg/controllers/proxy/service_endpoints_sync.go:460:2: ineffectual assignment to `ipvsSvcs` (ineffassign)
ipvsSvcs, err := nsc.ln.ipvsGetServices()
^
pkg/controllers/proxy/service_endpoints_sync.go:311:5: SA4006: this value of `err` is never used (staticcheck)
err = nsc.ln.ipAddrDel(dummyVipInterface, externalIP)
^
* node: Lint
pkg/utils/node.go:19:16: SA1019: clientset.Core is deprecated: please explicitly pick a version if possible. (staticcheck)
node, err := clientset.Core().Nodes().Get(nodeName, metav1.GetOptions{})
^
pkg/utils/node.go:27:15: SA1019: clientset.Core is deprecated: please explicitly pick a version if possible. (staticcheck)
node, err := clientset.Core().Nodes().Get(hostName, metav1.GetOptions{})
^
pkg/utils/node.go:34:15: SA1019: clientset.Core is deprecated: please explicitly pick a version if possible. (staticcheck)
node, err = clientset.Core().Nodes().Get(hostnameOverride, metav1.GetOptions{})
^
* aws: Lint
pkg/controllers/routing/aws.go:31:8: SA4006: this value of `err` is never used (staticcheck)
URL, err := url.Parse(providerID)
^
* health_controller: Lint
pkg/healthcheck/health_controller.go:54:10: Error return value of `w.Write` is not checked (errcheck)
w.Write([]byte("OK\n"))
^
pkg/healthcheck/health_controller.go:68:10: Error return value of `w.Write` is not checked (errcheck)
w.Write([]byte("Unhealthy"))
^
pkg/healthcheck/health_controller.go:159:2: S1000: should use a simple channel send/receive instead of `select` with a single case (gosimple)
select {
^
* network_routes_controller_test: Lint
pkg/controllers/routing/network_routes_controller_test.go:1113:37: Error return value of `testcase.nrc.bgpServer.Stop` is not checked (errcheck)
defer testcase.nrc.bgpServer.Stop()
^
pkg/controllers/routing/network_routes_controller_test.go:1314:37: Error return value of `testcase.nrc.bgpServer.Stop` is not checked (errcheck)
defer testcase.nrc.bgpServer.Stop()
^
pkg/controllers/routing/network_routes_controller_test.go:2327:37: Error return value of `testcase.nrc.bgpServer.Stop` is not checked (errcheck)
defer testcase.nrc.bgpServer.Stop()
^
* .golangci.yml: Increase timeout
Default is 1m, increase to 5m otherwise travis might fail
* Makefile: Update golangci-lint to 1.27.0
* kube-router_test.go: defer waitgroup
Co-authored-by: Aaron U'Ren <aauren@users.noreply.github.com>
* network_routes_controller: Incorporate review
* bgp_policies: Incorporate review
* network_routes_controller: Incorporate review
* bgp_policies: Log error instead
* network_services_controller: Incorporate review
Co-authored-by: Aaron U'Ren <aauren@users.noreply.github.com>
219 lines
6.4 KiB
Go
219 lines
6.4 KiB
Go
package cmd
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"os/signal"
|
|
"runtime"
|
|
"sync"
|
|
"syscall"
|
|
|
|
"github.com/cloudnativelabs/kube-router/pkg/controllers/netpol"
|
|
"github.com/cloudnativelabs/kube-router/pkg/controllers/proxy"
|
|
"github.com/cloudnativelabs/kube-router/pkg/controllers/routing"
|
|
"github.com/cloudnativelabs/kube-router/pkg/healthcheck"
|
|
"github.com/cloudnativelabs/kube-router/pkg/metrics"
|
|
"github.com/cloudnativelabs/kube-router/pkg/options"
|
|
"github.com/golang/glog"
|
|
|
|
"k8s.io/client-go/informers"
|
|
"k8s.io/client-go/kubernetes"
|
|
"k8s.io/client-go/rest"
|
|
"k8s.io/client-go/tools/clientcmd"
|
|
"time"
|
|
)
|
|
|
|
// These get set at build time via -ldflags magic
|
|
var version string
|
|
var buildDate string
|
|
|
|
// KubeRouter holds the information needed to run server
|
|
type KubeRouter struct {
|
|
Client kubernetes.Interface
|
|
Config *options.KubeRouterConfig
|
|
}
|
|
|
|
// NewKubeRouterDefault returns a KubeRouter object
|
|
func NewKubeRouterDefault(config *options.KubeRouterConfig) (*KubeRouter, error) {
|
|
|
|
var clientconfig *rest.Config
|
|
var err error
|
|
PrintVersion(true)
|
|
// Use out of cluster config if the URL or kubeconfig have been specified. Otherwise use incluster config.
|
|
if len(config.Master) != 0 || len(config.Kubeconfig) != 0 {
|
|
clientconfig, err = clientcmd.BuildConfigFromFlags(config.Master, config.Kubeconfig)
|
|
if err != nil {
|
|
return nil, errors.New("Failed to build configuration from CLI: " + err.Error())
|
|
}
|
|
} else {
|
|
clientconfig, err = rest.InClusterConfig()
|
|
if err != nil {
|
|
return nil, errors.New("unable to initialize inclusterconfig: " + err.Error())
|
|
}
|
|
}
|
|
|
|
clientset, err := kubernetes.NewForConfig(clientconfig)
|
|
if err != nil {
|
|
return nil, errors.New("Failed to create Kubernetes client: " + err.Error())
|
|
}
|
|
|
|
return &KubeRouter{Client: clientset, Config: config}, nil
|
|
}
|
|
|
|
// CleanupConfigAndExit performs Cleanup on all three controllers
|
|
func CleanupConfigAndExit() {
|
|
npc := netpol.NetworkPolicyController{}
|
|
npc.Cleanup()
|
|
|
|
nsc := proxy.NetworkServicesController{}
|
|
nsc.Cleanup()
|
|
|
|
nrc := routing.NetworkRoutingController{}
|
|
nrc.Cleanup()
|
|
}
|
|
|
|
// Run starts the controllers and waits forever till we get SIGINT or SIGTERM
|
|
func (kr *KubeRouter) Run() error {
|
|
var err error
|
|
var wg sync.WaitGroup
|
|
healthChan := make(chan *healthcheck.ControllerHeartbeat, 10)
|
|
defer close(healthChan)
|
|
stopCh := make(chan struct{})
|
|
|
|
if !(kr.Config.RunFirewall || kr.Config.RunServiceProxy || kr.Config.RunRouter) {
|
|
glog.Info("Router, Firewall or Service proxy functionality must be specified. Exiting!")
|
|
os.Exit(0)
|
|
}
|
|
|
|
hc, err := healthcheck.NewHealthController(kr.Config)
|
|
if err != nil {
|
|
return errors.New("Failed to create health controller: " + err.Error())
|
|
}
|
|
wg.Add(1)
|
|
go hc.RunServer(stopCh, &wg)
|
|
|
|
informerFactory := informers.NewSharedInformerFactory(kr.Client, 0)
|
|
svcInformer := informerFactory.Core().V1().Services().Informer()
|
|
epInformer := informerFactory.Core().V1().Endpoints().Informer()
|
|
podInformer := informerFactory.Core().V1().Pods().Informer()
|
|
nodeInformer := informerFactory.Core().V1().Nodes().Informer()
|
|
nsInformer := informerFactory.Core().V1().Namespaces().Informer()
|
|
npInformer := informerFactory.Networking().V1().NetworkPolicies().Informer()
|
|
informerFactory.Start(stopCh)
|
|
|
|
err = kr.CacheSyncOrTimeout(informerFactory, stopCh)
|
|
if err != nil {
|
|
return errors.New("Failed to synchronize cache: " + err.Error())
|
|
}
|
|
|
|
hc.SetAlive()
|
|
wg.Add(1)
|
|
go hc.RunCheck(healthChan, stopCh, &wg)
|
|
|
|
if (kr.Config.MetricsPort > 0) && (kr.Config.MetricsPort <= 65535) {
|
|
kr.Config.MetricsEnabled = true
|
|
mc, err := metrics.NewMetricsController(kr.Client, kr.Config)
|
|
if err != nil {
|
|
return errors.New("Failed to create metrics controller: " + err.Error())
|
|
}
|
|
wg.Add(1)
|
|
go mc.Run(healthChan, stopCh, &wg)
|
|
|
|
} else if kr.Config.MetricsPort > 65535 {
|
|
glog.Errorf("Metrics port must be over 0 and under 65535, given port: %d", kr.Config.MetricsPort)
|
|
kr.Config.MetricsEnabled = false
|
|
} else {
|
|
kr.Config.MetricsEnabled = false
|
|
}
|
|
|
|
if kr.Config.RunFirewall {
|
|
npc, err := netpol.NewNetworkPolicyController(kr.Client,
|
|
kr.Config, podInformer, npInformer, nsInformer)
|
|
if err != nil {
|
|
return errors.New("Failed to create network policy controller: " + err.Error())
|
|
}
|
|
|
|
podInformer.AddEventHandler(npc.PodEventHandler)
|
|
nsInformer.AddEventHandler(npc.NamespaceEventHandler)
|
|
npInformer.AddEventHandler(npc.NetworkPolicyEventHandler)
|
|
|
|
wg.Add(1)
|
|
go npc.Run(healthChan, stopCh, &wg)
|
|
}
|
|
|
|
if kr.Config.BGPGracefulRestart {
|
|
if kr.Config.BGPGracefulRestartDeferralTime > time.Hour*18 {
|
|
return errors.New("BGPGracefuleRestartDeferralTime should be less than 18 hours")
|
|
}
|
|
if kr.Config.BGPGracefulRestartDeferralTime <= 0 {
|
|
return errors.New("BGPGracefuleRestartDeferralTime must be positive")
|
|
}
|
|
}
|
|
|
|
if kr.Config.RunRouter {
|
|
nrc, err := routing.NewNetworkRoutingController(kr.Client, kr.Config, nodeInformer, svcInformer, epInformer)
|
|
if err != nil {
|
|
return errors.New("Failed to create network routing controller: " + err.Error())
|
|
}
|
|
|
|
nodeInformer.AddEventHandler(nrc.NodeEventHandler)
|
|
svcInformer.AddEventHandler(nrc.ServiceEventHandler)
|
|
epInformer.AddEventHandler(nrc.EndpointsEventHandler)
|
|
|
|
wg.Add(1)
|
|
go nrc.Run(healthChan, stopCh, &wg)
|
|
}
|
|
|
|
if kr.Config.RunServiceProxy {
|
|
nsc, err := proxy.NewNetworkServicesController(kr.Client, kr.Config,
|
|
svcInformer, epInformer, podInformer)
|
|
if err != nil {
|
|
return errors.New("Failed to create network services controller: " + err.Error())
|
|
}
|
|
|
|
svcInformer.AddEventHandler(nsc.ServiceEventHandler)
|
|
epInformer.AddEventHandler(nsc.EndpointsEventHandler)
|
|
|
|
wg.Add(1)
|
|
go nsc.Run(healthChan, stopCh, &wg)
|
|
}
|
|
|
|
// Handle SIGINT and SIGTERM
|
|
ch := make(chan os.Signal, 1)
|
|
signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)
|
|
<-ch
|
|
|
|
glog.Infof("Shutting down the controllers")
|
|
close(stopCh)
|
|
|
|
wg.Wait()
|
|
return nil
|
|
}
|
|
|
|
// CacheSync performs cache synchronization under timeout limit
|
|
func (kr *KubeRouter) CacheSyncOrTimeout(informerFactory informers.SharedInformerFactory, stopCh <-chan struct{}) error {
|
|
syncOverCh := make(chan struct{})
|
|
go func() {
|
|
informerFactory.WaitForCacheSync(stopCh)
|
|
close(syncOverCh)
|
|
}()
|
|
|
|
select {
|
|
case <-time.After(kr.Config.CacheSyncTimeout):
|
|
return errors.New(kr.Config.CacheSyncTimeout.String() + " timeout")
|
|
case <-syncOverCh:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func PrintVersion(logOutput bool) {
|
|
output := fmt.Sprintf("Running %v version %s, built on %s, %s\n", os.Args[0], version, buildDate, runtime.Version())
|
|
|
|
if !logOutput {
|
|
fmt.Fprintf(os.Stderr, "%s", output)
|
|
} else {
|
|
glog.Info(output)
|
|
}
|
|
}
|