Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refuse to create a firewall rule with no target tag #25929

Merged
merged 1 commit into from
Jun 18, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
34 changes: 17 additions & 17 deletions pkg/cloudprovider/providers/gce/gce.go
Original file line number Diff line number Diff line change
Expand Up @@ -938,10 +938,16 @@ func (gce *GCECloud) firewallObject(name, region, desc string, sourceRanges nets
for ix := range ports {
allowedPorts[ix] = strconv.Itoa(int(ports[ix].Port))
}
hostTags, err := gce.computeHostTags(hosts)
if err != nil {
return nil, err
// If the node tags to be used for this cluster have been predefined in the
// provider config, just use them. Otherwise, invoke computeHostTags method to get the tags.
hostTags := gce.nodeTags
if len(hostTags) == 0 {
var err error
if hostTags, err = gce.computeHostTags(hosts); err != nil {
return nil, fmt.Errorf("No node tags supplied and also failed to parse the given lists of hosts for tags. Abort creating firewall rule.")
}
}

firewall := &compute.Firewall{
Name: makeFirewallName(name),
Description: desc,
Expand All @@ -963,17 +969,13 @@ func (gce *GCECloud) firewallObject(name, region, desc string, sourceRanges nets
return firewall, nil
}

// If the node tags to be used for this cluster have been predefined in the
// provider config, just use them. Otherwise, grab all tags from all relevant
// instances:
// ComputeHostTags grabs all tags from all instances being added to the pool.
// * The longest tag that is a prefix of the instance name is used
// * If any instance has a prefix tag, all instances must
// * If no instances have a prefix tag, no tags are used
// * If any instance has no matching prefix tag, return error
// Invoking this method to get host tags is risky since it depends on the format
// of the host names in the cluster. Only use it as a fallback if gce.nodeTags
// is unspecified
func (gce *GCECloud) computeHostTags(hosts []*gceInstance) ([]string, error) {
if len(gce.nodeTags) > 0 {
return gce.nodeTags, nil
}

// TODO: We could store the tags in gceInstance, so we could have already fetched it
hostNamesByZone := make(map[string][]string)
for _, host := range hosts {
Expand Down Expand Up @@ -1012,20 +1014,18 @@ func (gce *GCECloud) computeHostTags(hosts []*gceInstance) ([]string, error) {
}
if len(longest_tag) > 0 {
tags.Insert(longest_tag)
} else if len(tags) > 0 {
return nil, fmt.Errorf("Some, but not all, instances have prefix tags (%s is missing)", instance.Name)
} else {
return nil, fmt.Errorf("Could not find any tag that is a prefix of instance name for instance %s", instance.Name)
}
}
}
if page >= maxPages {
glog.Errorf("computeHostTags exceeded maxPages=%d for Instances.List: truncating.", maxPages)
}
}

if len(tags) == 0 {
glog.V(2).Info("No instances had tags, creating rule without target tags")
return nil, fmt.Errorf("No instances found")
}

return tags.List(), nil
}

Expand Down
10 changes: 10 additions & 0 deletions pkg/cloudprovider/providers/gce/gce_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,16 @@ func TestScrubDNS(t *testing.T) {
}
}

func TestCreateFirewallFails(t *testing.T) {
name := "loadbalancer"
region := "us-central1"
desc := "description"
gce := &GCECloud{}
if err := gce.createFirewall(name, region, desc, nil, nil, nil); err == nil {
t.Errorf("error expected when creating firewall without any tags found")
}
}

func TestRestrictTargetPool(t *testing.T) {
const maxInstances = 5
tests := []struct {
Expand Down