Created
May 28, 2020 21:32
-
-
Save droyo/54ec51c13b49667c5e6094f774c1ec3b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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) | |
} | |
} | |
if len(new_interface.AliasIpRanges) == 0 { | |
// Go's `omitempty` behavior will remove this parameter from the | |
// request, but we really want to send the empty list. | |
new_interface.ForceSendFields = []string{"AliasIpRanges"} | |
} | |
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