code: func (gce *Cloud) UpdateFirewall(name, desc string, sourceRanges netsets.IPNet, ports []int64, hostNames []string) error {
  	region, err := GetGCERegion(gce.localZone)
  	if err != nil {
  		return err
  	}
  	// TODO: This completely breaks modularity in the cloudprovider but the methods
  	// shared with the TCPLoadBalancer take v1.ServicePorts.
  	svcPorts := []v1.ServicePort{}
  	// TODO: Currently the only consumer of this method is the GCE L7
  	// loadbalancer controller, which never needs a protocol other than TCP.
  	// We should pipe through a mapping of port:protocol and default to TCP
  	// if UDP ports are required. This means the method signature will change,
  	// forcing downstream clients to refactor interfaces.
  	for _, p := range ports {
  		svcPorts = append(svcPorts, v1.ServicePort{Port: int32(p), Protocol: v1.ProtocolTCP})
  	}
  	hosts, err := gce.getInstancesByNames(hostNames)
  	if err != nil {
  		return err
  	}
  	return gce.updateFirewall(name, region, desc, sourceRanges, svcPorts, hosts)
  }
docs: // UpdateFirewall applies the given firewall rule as an update to an existing
  // firewall rule with the same name.