GCE: Prefer preconfigured node tags for firewalls, if available

This commit is contained in:
Alex Robinson 2016-05-04 17:34:02 +00:00
parent 83c121e921
commit b75fa08aec
3 changed files with 29 additions and 11 deletions

View File

@ -766,6 +766,13 @@ EOF
EOF EOF
fi fi
if [[ -n "${NODE_INSTANCE_PREFIX:-}" ]]; then
cat <<EOF >>/etc/gce.conf
node-tags = [${NODE_INSTANCE_PREFIX}]
EOF
CLOUD_CONFIG=/etc/gce.conf
fi
if [[ -n "${MULTIZONE:-}" ]]; then if [[ -n "${MULTIZONE:-}" ]]; then
cat <<EOF >>/etc/gce.conf cat <<EOF >>/etc/gce.conf
multizone = ${MULTIZONE} multizone = ${MULTIZONE}

View File

@ -79,17 +79,19 @@ type GCECloud struct {
localZone string // The zone in which we are running localZone string // The zone in which we are running
managedZones []string // List of zones we are spanning (for Ubernetes-Lite, primarily when running on master) managedZones []string // List of zones we are spanning (for Ubernetes-Lite, primarily when running on master)
networkURL string networkURL string
nodeTags []string // List of tags to use on firewall rules for load balancers
useMetadataServer bool useMetadataServer bool
operationPollRateLimiter flowcontrol.RateLimiter operationPollRateLimiter flowcontrol.RateLimiter
} }
type Config struct { type Config struct {
Global struct { Global struct {
TokenURL string `gcfg:"token-url"` TokenURL string `gcfg:"token-url"`
TokenBody string `gcfg:"token-body"` TokenBody string `gcfg:"token-body"`
ProjectID string `gcfg:"project-id"` ProjectID string `gcfg:"project-id"`
NetworkName string `gcfg:"network-name"` NetworkName string `gcfg:"network-name"`
Multizone bool `gcfg:"multizone"` NodeTags []string `gcfg:"node-tags"`
Multizone bool `gcfg:"multizone"`
} }
} }
@ -222,12 +224,14 @@ func newGCECloud(config io.Reader) (*GCECloud, error) {
managedZones := []string{zone} managedZones := []string{zone}
tokenSource := google.ComputeTokenSource("") tokenSource := google.ComputeTokenSource("")
var nodeTags []string
if config != nil { if config != nil {
var cfg Config var cfg Config
if err := gcfg.ReadInto(&cfg, config); err != nil { if err := gcfg.ReadInto(&cfg, config); err != nil {
glog.Errorf("Couldn't read config: %v", err) glog.Errorf("Couldn't read config: %v", err)
return nil, err return nil, err
} }
glog.Infof("Using GCE provider config %+v", cfg)
if cfg.Global.ProjectID != "" { if cfg.Global.ProjectID != "" {
projectID = cfg.Global.ProjectID projectID = cfg.Global.ProjectID
} }
@ -241,19 +245,20 @@ func newGCECloud(config io.Reader) (*GCECloud, error) {
if cfg.Global.TokenURL != "" { if cfg.Global.TokenURL != "" {
tokenSource = newAltTokenSource(cfg.Global.TokenURL, cfg.Global.TokenBody) tokenSource = newAltTokenSource(cfg.Global.TokenURL, cfg.Global.TokenBody)
} }
nodeTags = cfg.Global.NodeTags
if cfg.Global.Multizone { if cfg.Global.Multizone {
managedZones = nil // Use all zones in region managedZones = nil // Use all zones in region
} }
} }
return CreateGCECloud(projectID, region, zone, managedZones, networkURL, tokenSource, true /* useMetadataServer */) return CreateGCECloud(projectID, region, zone, managedZones, networkURL, nodeTags, tokenSource, true /* useMetadataServer */)
} }
// Creates a GCECloud object using the specified parameters. // Creates a GCECloud object using the specified parameters.
// If no networkUrl is specified, loads networkName via rest call. // If no networkUrl is specified, loads networkName via rest call.
// If no tokenSource is specified, uses oauth2.DefaultTokenSource. // If no tokenSource is specified, uses oauth2.DefaultTokenSource.
// If managedZones is nil / empty all zones in the region will be managed. // If managedZones is nil / empty all zones in the region will be managed.
func CreateGCECloud(projectID, region, zone string, managedZones []string, networkURL string, tokenSource oauth2.TokenSource, useMetadataServer bool) (*GCECloud, error) { func CreateGCECloud(projectID, region, zone string, managedZones []string, networkURL string, nodeTags []string, tokenSource oauth2.TokenSource, useMetadataServer bool) (*GCECloud, error) {
if tokenSource == nil { if tokenSource == nil {
var err error var err error
tokenSource, err = google.DefaultTokenSource( tokenSource, err = google.DefaultTokenSource(
@ -802,8 +807,8 @@ func makeFirewallName(name string) string {
} }
func makeFirewallDescription(serviceName, ipAddress string) string { func makeFirewallDescription(serviceName, ipAddress string) string {
return fmt.Sprintf(`{"kubernetes.io/service-ip":"%s", "kubernetes.io/service-name":"%s"}`, return fmt.Sprintf(`{"kubernetes.io/service-name":"%s", "kubernetes.io/service-ip":"%s"}`,
ipAddress, serviceName) serviceName, ipAddress)
} }
func slicesEqual(x, y []string) bool { func slicesEqual(x, y []string) bool {
@ -937,11 +942,17 @@ func (gce *GCECloud) firewallObject(name, region, desc string, sourceRanges nets
return firewall, nil return firewall, nil
} }
// We grab all tags from all instances being added to the pool. // 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:
// * The longest tag that is a prefix of the instance name is used // * The longest tag that is a prefix of the instance name is used
// * If any instance has a prefix tag, all instances must // * If any instance has a prefix tag, all instances must
// * If no instances have a prefix tag, no tags are used // * If no instances have a prefix tag, no tags are used
func (gce *GCECloud) computeHostTags(hosts []*gceInstance) ([]string, error) { 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 // TODO: We could store the tags in gceInstance, so we could have already fetched it
hostNamesByZone := make(map[string][]string) hostNamesByZone := make(map[string][]string)
for _, host := range hosts { for _, host := range hosts {

View File

@ -72,7 +72,7 @@ func setupProviderConfig() error {
return fmt.Errorf("error parsing GCE/GKE region from zone %q: %v", zone, err) return fmt.Errorf("error parsing GCE/GKE region from zone %q: %v", zone, err)
} }
managedZones := []string{zone} // Only single-zone for now managedZones := []string{zone} // Only single-zone for now
cloudConfig.Provider, err = gcecloud.CreateGCECloud(framework.TestContext.CloudConfig.ProjectID, region, zone, managedZones, "" /* networkUrl */, tokenSource, false /* useMetadataServer */) cloudConfig.Provider, err = gcecloud.CreateGCECloud(framework.TestContext.CloudConfig.ProjectID, region, zone, managedZones, "" /* networkUrl */, nil /* nodeTags */, tokenSource, false /* useMetadataServer */)
if err != nil { if err != nil {
return fmt.Errorf("Error building GCE/GKE provider: %v", err) return fmt.Errorf("Error building GCE/GKE provider: %v", err)
} }