Skip to content

Instantly share code, notes, and snippets.

@droyo
Created May 28, 2020 18:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save droyo/14012013507d04598c0fcc5468eb7bd0 to your computer and use it in GitHub Desktop.
Save droyo/14012013507d04598c0fcc5468eb7bd0 to your computer and use it in GitHub Desktop.
// Adds, then removes an alias IP from a VM
package main
import (
"context"
"flag"
"fmt"
"log"
"os"
"time"
"github.com/kr/pretty"
"google.golang.org/api/compute/v1"
)
var (
project = flag.String("project", "", "project id")
zone = flag.String("zone", "", "zone (required)")
subnet_range = flag.String("range", "", "subnet range to add and remove alias from")
)
func main() {
flag.Parse()
if flag.NArg() != 2 {
log.Fatalf("Usage: %s [-p project] [-z zone] INSTANCE ALIAS_IP", os.Args[0])
}
instance := flag.Arg(0)
alias := flag.Arg(1)
if *project == "" || *zone == "" || *subnet_range == "" {
log.Fatal("--project and --zone and --range are required")
}
ctx := context.Background()
computeService, err := compute.NewService(ctx)
if err != nil {
log.Fatalf("could not init compute: %s", err)
}
err = addAlias(computeService, *project, *zone, instance, *subnet_range, alias)
if err != nil {
log.Fatal(err)
}
// NOTE: in real code you'd want to wait for the previous op to complete
time.Sleep(time.Second * 10)
err = removeAlias(computeService, *project, *zone, instance, alias)
if err != nil {
log.Fatal(err)
}
}
func addAlias(gce *compute.Service, project, zone, instance_name, subnet_range, alias_ip string) error {
svc := compute.NewInstancesService(gce)
instance, err := svc.Get(project, zone, instance_name).Do()
if err != nil {
return err
}
var new_interface compute.NetworkInterface
old_interface := instance.NetworkInterfaces[0]
new_interface.AliasIpRanges = old_interface.AliasIpRanges
new_interface.AliasIpRanges = append(new_interface.AliasIpRanges, &compute.AliasIpRange{
IpCidrRange: alias_ip,
SubnetworkRangeName: subnet_range,
})
new_interface.Fingerprint = old_interface.Fingerprint
pretty.Println("old", old_interface)
pretty.Println("new", new_interface)
op, err := svc.UpdateNetworkInterface(project, zone, instance_name, "nic0", &new_interface).Do()
if err != nil {
return err
}
fmt.Println("add alias op: ", op.Name)
return nil
}
func removeAlias(gce *compute.Service, project, zone, instance_name, alias_ip string) error {
svc := compute.NewInstancesService(gce)
// To remove an alias we have to overwrite the interface's alias IP list, so we need
// the existing instance.
instance, err := svc.Get(project, zone, instance_name).Do()
if err != nil {
return err
}
var new_interface compute.NetworkInterface
old_interface := instance.NetworkInterfaces[0]
for _, r := range old_interface.AliasIpRanges {
if r.IpCidrRange != alias_ip {
new_interface.AliasIpRanges = append(new_interface.AliasIpRanges, r)
}
}
new_interface.Fingerprint = old_interface.Fingerprint
pretty.Println("old", old_interface)
pretty.Println("new", new_interface)
op, err := svc.UpdateNetworkInterface(project, zone, instance_name, "nic0", &new_interface).Do()
if err != nil {
return err
}
fmt.Println("delete alias op", op.Name)
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment