Skip to content

Instantly share code, notes, and snippets.

@JeanMertz
Last active August 20, 2017 21:49
Show Gist options
  • Save JeanMertz/9fabe929cddfa7cf155ab9c72b61d140 to your computer and use it in GitHub Desktop.
Save JeanMertz/9fabe929cddfa7cf155ab9c72b61d140 to your computer and use it in GitHub Desktop.
Automated Kubernetes Google Cloud Platform routes
package main
import (
"fmt"
"log"
"time"
"golang.org/x/net/context"
"golang.org/x/oauth2/google"
compute "google.golang.org/api/compute/v1"
apiv1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)
// RouteRule dictates if an existing rule is valid or not.
type RouteRule struct {
Valid bool
Route *compute.Route
}
var (
computeService *compute.Service
clientset *kubernetes.Clientset
project = ""
destRange = "xxx.xxx.xxx.xxx/20"
network = "default"
zone = "europe-west1-d"
routeName = "%s-serviceip"
description = "gke-serviceip-route"
ctx = context.Background()
)
func main() {
var err error
computeService, err = newComputeClient()
if err != nil {
panic(err.Error())
}
clientset, err = newKubernetesClient()
if err != nil {
panic(err.Error())
}
for {
err = validateRoutes()
if err != nil {
log.Println(err.Error())
}
time.Sleep(60 * time.Second)
}
}
func validateRoutes() error {
rules, err := newRules()
if err != nil {
return err
}
nodes, err := clientset.Nodes().List(v1.ListOptions{})
if err != nil {
return err
}
for _, n := range nodes.Items {
var match bool
for _, r := range rules {
if fmt.Sprintf(routeName, n.Name) == r.Route.Name {
match = true
r.Valid = true
}
}
if match {
continue
}
err := createRoute(n)
if err != nil {
return err
}
}
return deleteInvalidRoutes(rules)
}
func createRoute(node apiv1.Node) error {
route := &compute.Route{
Description: description,
DestRange: destRange,
Name: fmt.Sprintf(routeName, node.Name),
Network: fmt.Sprintf("projects/%s/global/networks/%s", project, network),
NextHopInstance: fmt.Sprintf("projects/%s/zones/%s/instances/%s", project, zone, node.Name),
}
_, err := computeService.Routes.Insert(project, route).Context(ctx).Do()
return err
}
func deleteRoute(route *compute.Route) error {
_, err := computeService.Routes.Delete(project, route.Name).Context(ctx).Do()
return err
}
func deleteInvalidRoutes(rules []*RouteRule) error {
for _, r := range rules {
if r.Valid {
continue
}
err := deleteRoute(r.Route)
if err != nil {
return err
}
}
return nil
}
func newRules() ([]*RouteRule, error) {
var rules []*RouteRule
filter := fmt.Sprintf("description eq ", description)
routeList, err := computeService.Routes.List(project).Filter(filter).Context(ctx).Do()
if err != nil {
return rules, err
}
for _, r := range routeList.Items {
rules = append(rules, &RouteRule{Route: r})
}
return rules, nil
}
func newComputeClient() (*compute.Service, error) {
c, err := google.DefaultClient(ctx, compute.ComputeScope)
if err != nil {
return nil, err
}
return compute.New(c)
}
func newKubernetesClient() (*kubernetes.Clientset, error) {
config, err := rest.InClusterConfig()
if err != nil {
return nil, err
}
return kubernetes.NewForConfig(config)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment