func validateRegionAndZone()

in cli/pkg/config/config.go [299:357]


func validateRegionAndZone(projectId string, clusterRegion string, clusterZones []string) error {
	regions := map[string]bool{} // region --> true
	zones := map[string]string{} // zone --> region

	ctx := context.Background()
	c, err := compute.NewZonesRESTClient(ctx)
	if err != nil {
		return err
	}
	defer c.Close()

	req := &computepb.ListZonesRequest{
		Project: projectId,
	}
	it := c.List(ctx, req)
	var sanitizedRegion string

	// Populate map of regions + zones for this project
	for {
		resp, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return err
		}
		r := *resp.Region

		spl := strings.Split(r, "/")
		if len(spl) < 2 {
			log.Warnf("Zone %s does not have a valid region - %s\n", *resp.Name, *resp.Region)
		}
		// Format region from https://www.googleapis.com/compute/v1/projects/megan-2021/regions/us-central1  --> us-central1
		sanitizedRegion = spl[len(spl)-1]
		regions[sanitizedRegion] = true
		zones[*resp.Name] = sanitizedRegion
		_ = resp
	}

	// Region must exist
	if _, ok := regions[clusterRegion]; !ok {
		return fmt.Errorf("region %s invalid - must be one of: %v", clusterRegion, regions)
	}

	// Zone must exist
	for _, clusterZone := range clusterZones {
		if _, ok := zones[clusterZone]; !ok {
			return fmt.Errorf("zone %s invalid - must be one of: %v", clusterZone, zones)
		}
	}

	// Zone must be in the right region
	for _, clusterZone := range clusterZones {
		if zoneRegion, _ := zones[clusterZone]; zoneRegion != clusterRegion {
			return fmt.Errorf("zone %s must be in region %s, not region %s", clusterZone, zoneRegion, clusterRegion)
		}
	}
	return nil
}