From fb31d0ec6bcdd5a2f52c4c3b94dc4db260ed8b21 Mon Sep 17 00:00:00 2001 From: James Phillips Date: Fri, 19 Jan 2018 16:24:08 -0800 Subject: [PATCH 1/2] Updates hashicorp/go-discover to pull in support for Azure Virtual Machine Scale Sets. --- .../hashicorp/go-discover/README.md | 4 +- .../provider/azure/azure_discover.go | 73 ++++++++++++++++++- vendor/vendor.json | 4 +- 3 files changed, 75 insertions(+), 6 deletions(-) diff --git a/vendor/github.com/hashicorp/go-discover/README.md b/vendor/github.com/hashicorp/go-discover/README.md index 1b75c98f99..fb398fc34c 100644 --- a/vendor/github.com/hashicorp/go-discover/README.md +++ b/vendor/github.com/hashicorp/go-discover/README.md @@ -25,7 +25,7 @@ function. * Amazon AWS [Config options](https://github.com/hashicorp/go-discover/blob/master/provider/aws/aws_discover.go#L19-L33) * DigitalOcean [Config options](https://github.com/hashicorp/go-discover/blob/master/provider/digitalocean/digitalocean_discover.go#L16-L24) * Google Cloud [Config options](https://github.com/hashicorp/go-discover/blob/master/provider/gce/gce_discover.go#L17-L37) - * Microsoft Azure [Config options](https://github.com/hashicorp/go-discover/blob/master/provider/azure/azure_discover.go#L16-L30) + * Microsoft Azure [Config options](https://github.com/hashicorp/go-discover/blob/master/provider/azure/azure_discover.go#L16-L37) * Openstack [Config options](https://github.com/hashicorp/go-discover/blob/master/provider/os/os_discover.go#L23-L38) * Scaleway [Config options](https://github.com/hashicorp/go-discover/blob/master/provider/scaleway/scaleway_discover.go#L14-L22) * SoftLayer [Config options](https://github.com/hashicorp/go-discover/blob/master/provider/softlayer/softlayer_discover.go#L16-L25) @@ -107,4 +107,4 @@ For complete API documentation, see [GoDoc](https://godoc.org/github.com/hashicorp/go-discover). The configuration for the supported providers is documented in the [providers](https://godoc.org/github.com/hashicorp/go-discover/provider) -sub-package. +sub-package. \ No newline at end of file diff --git a/vendor/github.com/hashicorp/go-discover/provider/azure/azure_discover.go b/vendor/github.com/hashicorp/go-discover/provider/azure/azure_discover.go index ed114a2110..6a7ee46068 100644 --- a/vendor/github.com/hashicorp/go-discover/provider/azure/azure_discover.go +++ b/vendor/github.com/hashicorp/go-discover/provider/azure/azure_discover.go @@ -21,10 +21,17 @@ func (p *Provider) Help() string { client_id: The id of the client subscription_id: The id of the subscription secret_access_key: The authentication credential + + Use these configuration parameters when using network interfaces: tag_name: The name of the tag to filter on tag_value: The value of the tag to filter on - The only permission needed is the 'ListAll' method for 'NetworkInterfaces'. + Use these configuration parameters when using vm scale sets: + resource_group: The name of the resource group to filter on + vm_scale_set: The name of the virtual machine scale set to filter on + + When using tags the only permission needed is the 'ListAll' method for 'NetworkInterfaces'. + When using vm scale sets the only Role Action needed is "Microsoft.Compute/virtualMachineScaleSets/*/read". It is recommended you make a dedicated key used only for auto-joining. ` } @@ -42,9 +49,15 @@ func (p *Provider) Addrs(args map[string]string, l *log.Logger) ([]string, error clientID := args["client_id"] subscriptionID := args["subscription_id"] secretKey := args["secret_access_key"] + + // Use tags if using network interfaces tagName := args["tag_name"] tagValue := args["tag_value"] + // Use resourceGroup and vmScaleSet if using vm scale sets + resourceGroup := args["resource_group"] + vmScaleSet := args["vm_scale_set"] + // Only works for the Azure PublicCLoud for now; no ability to test other Environment oauthConfig, err := azure.PublicCloud.OAuthConfigForTenant(tenantID) if err != nil { @@ -63,6 +76,21 @@ func (p *Provider) Addrs(args map[string]string, l *log.Logger) ([]string, error vmnet.Sender = autorest.CreateSender(autorest.WithLogging(l)) vmnet.Authorizer = sbt + if tagName != "" && tagValue != "" && resourceGroup == "" && vmScaleSet == "" { + l.Printf("[DEBUG] discover-azure: using tag method. tag_name: %s, tag_value: %s", tagName, tagValue) + return fetchAddrsWithTags(tagName, tagValue, vmnet, l) + } else if resourceGroup != "" && vmScaleSet != "" && tagName == "" && tagValue == "" { + l.Printf("[DEBUG] discover-azure: using vm scale set method. resource_group: %s, vm_scale_set: %s", resourceGroup, vmScaleSet) + return fetchAddrsWithVmScaleSet(resourceGroup, vmScaleSet, vmnet, l) + } else { + l.Printf("[ERROR] discover-azure: tag_name: %s, tag_value: %s", tagName, tagValue) + l.Printf("[ERROR] discover-azure: resource_group %s, vm_scale_set %s", resourceGroup, vmScaleSet) + return nil, fmt.Errorf("discover-azure: unclear configuration. use (tag name and value) or (resouce_group and vm_scale_set)") + } + +} + +func fetchAddrsWithTags(tagName string, tagValue string, vmnet network.InterfacesClient, l *log.Logger) ([]string, error) { // Get all network interfaces across resource groups // unless there is a compelling reason to restrict netres, err := vmnet.ListAll() @@ -77,22 +105,63 @@ func (p *Provider) Addrs(args map[string]string, l *log.Logger) ([]string, error // Choose any PrivateIPAddress with the matching tag var addrs []string for _, v := range *netres.Value { + id := *v.ID if v.Tags == nil { + l.Printf("[DEBUG] discover-azure: Interface %s has no tags", id) continue } tv := (*v.Tags)[tagName] // *string if tv == nil || *tv != tagValue { + l.Printf("[DEBUG] discover-azure: Interface %s tag value was: %s which did not match: %s", id, *tv, tagValue) continue } if v.IPConfigurations == nil { + l.Printf("[DEBUG] discover-azure: Interface %s had no ip configuration", id) + continue + } + for _, x := range *v.IPConfigurations { + if x.PrivateIPAddress == nil { + l.Printf("[DEBUG] discover-azure: Interface %s had no private ip", id) + continue + } + iAddr := *x.PrivateIPAddress + l.Printf("[DEBUG] discover-azure: Interface %s has private ip: %s", id, iAddr) + addrs = append(addrs, iAddr) + } + } + l.Printf("[DEBUG] discover-azure: Found ip addresses: %v", addrs) + return addrs, nil +} + +func fetchAddrsWithVmScaleSet(resourceGroup string, vmScaleSet string, vmnet network.InterfacesClient, l *log.Logger) ([]string, error) { + // Get all network interfaces for a specific virtual machine scale set + netres, err := vmnet.ListVirtualMachineScaleSetNetworkInterfaces(resourceGroup, vmScaleSet) + if err != nil { + return nil, fmt.Errorf("discover-azure: %s", err) + } + + if netres.Value == nil { + return nil, fmt.Errorf("discover-azure: no interfaces") + } + + // Get all of PrivateIPAddresses we can. + var addrs []string + for _, v := range *netres.Value { + id := *v.ID + if v.IPConfigurations == nil { + l.Printf("[DEBUG] discover-azure: Interface %s had no ip configuration", id) continue } for _, x := range *v.IPConfigurations { if x.PrivateIPAddress == nil { + l.Printf("[DEBUG] discover-azure: Interface %s had no private ip", id) continue } - addrs = append(addrs, *x.PrivateIPAddress) + iAddr := *x.PrivateIPAddress + l.Printf("[DEBUG] discover-azure: Interface %s has private ip: %s", id, iAddr) + addrs = append(addrs, iAddr) } } + l.Printf("[DEBUG] discover-azure: Found ip addresses: %v", addrs) return addrs, nil } diff --git a/vendor/vendor.json b/vendor/vendor.json index f125b198c0..b359d33cf7 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -25,10 +25,10 @@ {"path":"github.com/hashicorp/errwrap","checksumSHA1":"cdOCt0Yb+hdErz8NAQqayxPmRsY=","revision":"7554cd9344cec97297fa6649b055a8c98c2a1e55","revisionTime":"2014-10-28T05:47:10Z"}, {"path":"github.com/hashicorp/go-checkpoint","checksumSHA1":"D267IUMW2rcb+vNe3QU+xhfSrgY=","revision":"1545e56e46dec3bba264e41fde2c1e2aa65b5dd4","revisionTime":"2017-10-09T17:35:28Z"}, {"path":"github.com/hashicorp/go-cleanhttp","checksumSHA1":"YAq1rqZIp+M74Q+jMBQkkMKm3VM=","revision":"d5fe4b57a186c716b0e00b8c301cbd9b4182694d","revisionTime":"2017-12-18T14:54:08Z"}, - {"path":"github.com/hashicorp/go-discover","checksumSHA1":"Ks9Bo8kevhaI5xTRdw1lULNMoOA=","revision":"c98e36ab72ce62b7d8fbc7f7e76f9a60e163cb45","revisionTime":"2017-10-30T10:26:55Z"}, + {"path":"github.com/hashicorp/go-discover","checksumSHA1":"yG6DzmNiB7kOdLcgvI1v9GacoSA=","revision":"4e49190abe2f3801a8653d7745a14bc445381615","revisionTime":"2018-01-20T00:19:59Z"}, {"path":"github.com/hashicorp/go-discover/provider/aliyun","checksumSHA1":"ZmU/47XUGUQpFP6E8T6Tl8QKszI=","revision":"c98e36ab72ce62b7d8fbc7f7e76f9a60e163cb45","revisionTime":"2017-10-30T10:26:55Z","tree":true}, {"path":"github.com/hashicorp/go-discover/provider/aws","checksumSHA1":"lyPRg8aZKgGiNkMILk/VKwOqMy4=","revision":"c98e36ab72ce62b7d8fbc7f7e76f9a60e163cb45","revisionTime":"2017-10-30T10:26:55Z","tree":true}, - {"path":"github.com/hashicorp/go-discover/provider/azure","checksumSHA1":"r97P32e+VmNMh2vwLkZa1zPEDQU=","revision":"c98e36ab72ce62b7d8fbc7f7e76f9a60e163cb45","revisionTime":"2017-10-30T10:26:55Z","tree":true}, + {"path":"github.com/hashicorp/go-discover/provider/azure","checksumSHA1":"+5VD2xEOEvTZhWn2Uk009wD6XvY=","revision":"4e49190abe2f3801a8653d7745a14bc445381615","revisionTime":"2018-01-20T00:19:59Z","tree":true}, {"path":"github.com/hashicorp/go-discover/provider/digitalocean","checksumSHA1":"qoy/euk2dwrONYMUsaAPznHHpxQ=","revision":"c98e36ab72ce62b7d8fbc7f7e76f9a60e163cb45","revisionTime":"2017-10-30T10:26:55Z","tree":true}, {"path":"github.com/hashicorp/go-discover/provider/gce","checksumSHA1":"tnKls5vtzpNQAj7b987N4i81HvY=","revision":"7642001b443a3723e2aba277054f16d1df172d97","revisionTime":"2018-01-03T21:14:29Z","tree":true}, {"path":"github.com/hashicorp/go-discover/provider/os","checksumSHA1":"LZwn9B00AjulYRCKapmJWFAamoo=","revision":"c98e36ab72ce62b7d8fbc7f7e76f9a60e163cb45","revisionTime":"2017-10-30T10:26:55Z","tree":true}, From d93eb3659c201be8342de149930921405590acfc Mon Sep 17 00:00:00 2001 From: James Phillips Date: Fri, 19 Jan 2018 16:30:21 -0800 Subject: [PATCH 2/2] Updates configuration docs for Azure VMSS support. --- website/source/docs/agent/options.html.md | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/website/source/docs/agent/options.html.md b/website/source/docs/agent/options.html.md index d60455ab13..8bc6c5d9dd 100644 --- a/website/source/docs/agent/options.html.md +++ b/website/source/docs/agent/options.html.md @@ -318,8 +318,8 @@ will exit with an error at startup. ### Microsoft Azure This returns the first private IP address of all servers in the given region - which have the given `tag_key` and `tag_value` in the tenant and - subscription. + which have the given `tag_key` and `tag_value` in the tenant and subscription, or in + the given `resource_group` of a `vm_scale_set` for Virtual Machine Scale Sets. ```sh $ consul agent -retry-join "provider=azure tag_name=... tag_value=... tenant_id=... client_id=... subscription_id=... secret_access_key=..." @@ -332,12 +332,21 @@ will exit with an error at startup. ``` - `provider` (required) - the name of the provider ("azure" in this case). - - `tag_name` (required) - the name of the tag to auto-join on. - - `tag_value` (required) - the value of the tag to auto-join on. - `tenant_id` (required) - the tenant to join machines in. - `client_id` (required) - the client to authenticate with. - `secret_access_key` (required) - the secret client key. + Use these configuration parameters when using tags: + - `tag_name` - the name of the tag to auto-join on. + - `tag_value` - the value of the tag to auto-join on. + + Use these configuration parameters when using Virtual Machine Scale Sets (Consul 1.0.3 and later): + - `resource_group` - the name of the resource group to filter on. + - `vm_scale_set` - the name of the virtual machine scale set to filter on. + + When using tags the only permission needed is the `ListAll` method for `NetworkInterfaces`. When using + Virtual Machine Scale Sets the only role action needed is `Microsoft.Compute/virtualMachineScaleSets/*/read`. + ### Google Compute Engine This returns the first private IP address of all servers in the given