2016-04-06 20:47:02 -07:00
|
|
|
// Copyright 2015 The Prometheus Authors
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
2016-11-21 06:51:36 -08:00
|
|
|
package azure
|
2016-04-06 20:47:02 -07:00
|
|
|
|
|
|
|
import (
|
2017-10-24 21:21:42 -07:00
|
|
|
"context"
|
2022-06-03 04:47:14 -07:00
|
|
|
"errors"
|
2016-04-06 20:47:02 -07:00
|
|
|
"fmt"
|
2016-09-05 05:40:28 -07:00
|
|
|
"net"
|
2018-08-01 04:52:21 -07:00
|
|
|
"net/http"
|
2016-04-06 20:47:02 -07:00
|
|
|
"strings"
|
2019-01-18 00:55:47 -08:00
|
|
|
"sync"
|
2016-04-06 20:47:02 -07:00
|
|
|
"time"
|
|
|
|
|
2019-01-28 10:30:29 -08:00
|
|
|
"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2018-10-01/compute"
|
|
|
|
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-10-01/network"
|
2018-07-17 21:24:15 -07:00
|
|
|
"github.com/Azure/go-autorest/autorest"
|
|
|
|
"github.com/Azure/go-autorest/autorest/adal"
|
2016-04-06 20:47:02 -07:00
|
|
|
"github.com/Azure/go-autorest/autorest/azure"
|
2021-06-11 09:17:59 -07:00
|
|
|
"github.com/go-kit/log"
|
|
|
|
"github.com/go-kit/log/level"
|
2022-03-31 05:50:17 -07:00
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
2018-01-11 07:10:25 -08:00
|
|
|
config_util "github.com/prometheus/common/config"
|
2016-04-06 20:47:02 -07:00
|
|
|
"github.com/prometheus/common/model"
|
2022-01-28 04:36:04 -08:00
|
|
|
"github.com/prometheus/common/version"
|
2019-03-25 03:54:22 -07:00
|
|
|
|
2020-08-20 05:48:26 -07:00
|
|
|
"github.com/prometheus/prometheus/discovery"
|
2019-03-25 03:54:22 -07:00
|
|
|
"github.com/prometheus/prometheus/discovery/refresh"
|
Refactor SD configuration to remove `config` dependency (#3629)
* refactor: move targetGroup struct and CheckOverflow() to their own package
* refactor: move auth and security related structs to a utility package, fix import error in utility package
* refactor: Azure SD, remove SD struct from config
* refactor: DNS SD, remove SD struct from config into dns package
* refactor: ec2 SD, move SD struct from config into the ec2 package
* refactor: file SD, move SD struct from config to file discovery package
* refactor: gce, move SD struct from config to gce discovery package
* refactor: move HTTPClientConfig and URL into util/config, fix import error in httputil
* refactor: consul, move SD struct from config into consul discovery package
* refactor: marathon, move SD struct from config into marathon discovery package
* refactor: triton, move SD struct from config to triton discovery package, fix test
* refactor: zookeeper, move SD structs from config to zookeeper discovery package
* refactor: openstack, remove SD struct from config, move into openstack discovery package
* refactor: kubernetes, move SD struct from config into kubernetes discovery package
* refactor: notifier, use targetgroup package instead of config
* refactor: tests for file, marathon, triton SD - use targetgroup package instead of config.TargetGroup
* refactor: retrieval, use targetgroup package instead of config.TargetGroup
* refactor: storage, use config util package
* refactor: discovery manager, use targetgroup package instead of config.TargetGroup
* refactor: use HTTPClient and TLS config from configUtil instead of config
* refactor: tests, use targetgroup package instead of config.TargetGroup
* refactor: fix tagetgroup.Group pointers that were removed by mistake
* refactor: openstack, kubernetes: drop prefixes
* refactor: remove import aliases forced due to vscode bug
* refactor: move main SD struct out of config into discovery/config
* refactor: rename configUtil to config_util
* refactor: rename yamlUtil to yaml_config
* refactor: kubernetes, remove prefixes
* refactor: move the TargetGroup package to discovery/
* refactor: fix order of imports
2017-12-29 12:01:34 -08:00
|
|
|
"github.com/prometheus/prometheus/discovery/targetgroup"
|
2016-04-06 20:47:02 -07:00
|
|
|
"github.com/prometheus/prometheus/util/strutil"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
azureLabel = model.MetaLabelPrefix + "azure_"
|
2018-12-07 01:40:45 -08:00
|
|
|
azureLabelSubscriptionID = azureLabel + "subscription_id"
|
|
|
|
azureLabelTenantID = azureLabel + "tenant_id"
|
2016-04-06 20:47:02 -07:00
|
|
|
azureLabelMachineID = azureLabel + "machine_id"
|
|
|
|
azureLabelMachineResourceGroup = azureLabel + "machine_resource_group"
|
|
|
|
azureLabelMachineName = azureLabel + "machine_name"
|
2021-07-25 09:34:32 -07:00
|
|
|
azureLabelMachineComputerName = azureLabel + "machine_computer_name"
|
2018-02-19 07:40:57 -08:00
|
|
|
azureLabelMachineOSType = azureLabel + "machine_os_type"
|
2016-04-06 20:47:02 -07:00
|
|
|
azureLabelMachineLocation = azureLabel + "machine_location"
|
|
|
|
azureLabelMachinePrivateIP = azureLabel + "machine_private_ip"
|
2019-04-17 08:05:44 -07:00
|
|
|
azureLabelMachinePublicIP = azureLabel + "machine_public_ip"
|
2016-04-06 20:47:02 -07:00
|
|
|
azureLabelMachineTag = azureLabel + "machine_tag_"
|
2018-08-01 04:52:21 -07:00
|
|
|
azureLabelMachineScaleSet = azureLabel + "machine_scale_set"
|
2018-12-19 02:03:33 -08:00
|
|
|
|
|
|
|
authMethodOAuth = "OAuth"
|
|
|
|
authMethodManagedIdentity = "ManagedIdentity"
|
2016-04-06 20:47:02 -07:00
|
|
|
)
|
|
|
|
|
2022-01-28 04:36:04 -08:00
|
|
|
var (
|
|
|
|
userAgent = fmt.Sprintf("Prometheus/%s", version.Version)
|
|
|
|
|
|
|
|
// DefaultSDConfig is the default Azure SD configuration.
|
|
|
|
DefaultSDConfig = SDConfig{
|
|
|
|
Port: 80,
|
|
|
|
RefreshInterval: model.Duration(5 * time.Minute),
|
|
|
|
Environment: azure.PublicCloud.Name,
|
|
|
|
AuthenticationMethod: authMethodOAuth,
|
|
|
|
HTTPClientConfig: config_util.DefaultHTTPClientConfig,
|
|
|
|
}
|
2022-03-31 05:50:17 -07:00
|
|
|
|
|
|
|
failuresCount = prometheus.NewCounter(
|
|
|
|
prometheus.CounterOpts{
|
|
|
|
Name: "prometheus_sd_azure_failures_total",
|
|
|
|
Help: "Number of Azure service discovery refresh failures.",
|
|
|
|
})
|
2022-01-28 04:36:04 -08:00
|
|
|
)
|
2016-10-20 00:23:50 -07:00
|
|
|
|
2020-08-20 05:48:26 -07:00
|
|
|
func init() {
|
|
|
|
discovery.RegisterConfig(&SDConfig{})
|
2022-03-31 05:50:17 -07:00
|
|
|
prometheus.MustRegister(failuresCount)
|
2020-08-20 05:48:26 -07:00
|
|
|
}
|
|
|
|
|
Refactor SD configuration to remove `config` dependency (#3629)
* refactor: move targetGroup struct and CheckOverflow() to their own package
* refactor: move auth and security related structs to a utility package, fix import error in utility package
* refactor: Azure SD, remove SD struct from config
* refactor: DNS SD, remove SD struct from config into dns package
* refactor: ec2 SD, move SD struct from config into the ec2 package
* refactor: file SD, move SD struct from config to file discovery package
* refactor: gce, move SD struct from config to gce discovery package
* refactor: move HTTPClientConfig and URL into util/config, fix import error in httputil
* refactor: consul, move SD struct from config into consul discovery package
* refactor: marathon, move SD struct from config into marathon discovery package
* refactor: triton, move SD struct from config to triton discovery package, fix test
* refactor: zookeeper, move SD structs from config to zookeeper discovery package
* refactor: openstack, remove SD struct from config, move into openstack discovery package
* refactor: kubernetes, move SD struct from config into kubernetes discovery package
* refactor: notifier, use targetgroup package instead of config
* refactor: tests for file, marathon, triton SD - use targetgroup package instead of config.TargetGroup
* refactor: retrieval, use targetgroup package instead of config.TargetGroup
* refactor: storage, use config util package
* refactor: discovery manager, use targetgroup package instead of config.TargetGroup
* refactor: use HTTPClient and TLS config from configUtil instead of config
* refactor: tests, use targetgroup package instead of config.TargetGroup
* refactor: fix tagetgroup.Group pointers that were removed by mistake
* refactor: openstack, kubernetes: drop prefixes
* refactor: remove import aliases forced due to vscode bug
* refactor: move main SD struct out of config into discovery/config
* refactor: rename configUtil to config_util
* refactor: rename yamlUtil to yaml_config
* refactor: kubernetes, remove prefixes
* refactor: move the TargetGroup package to discovery/
* refactor: fix order of imports
2017-12-29 12:01:34 -08:00
|
|
|
// SDConfig is the configuration for Azure based service discovery.
|
|
|
|
type SDConfig struct {
|
2018-12-19 02:03:33 -08:00
|
|
|
Environment string `yaml:"environment,omitempty"`
|
|
|
|
Port int `yaml:"port"`
|
|
|
|
SubscriptionID string `yaml:"subscription_id"`
|
|
|
|
TenantID string `yaml:"tenant_id,omitempty"`
|
|
|
|
ClientID string `yaml:"client_id,omitempty"`
|
|
|
|
ClientSecret config_util.Secret `yaml:"client_secret,omitempty"`
|
|
|
|
RefreshInterval model.Duration `yaml:"refresh_interval,omitempty"`
|
|
|
|
AuthenticationMethod string `yaml:"authentication_method,omitempty"`
|
2022-03-28 16:21:23 -07:00
|
|
|
ResourceGroup string `yaml:"resource_group,omitempty"`
|
2021-10-20 14:09:58 -07:00
|
|
|
|
|
|
|
HTTPClientConfig config_util.HTTPClientConfig `yaml:",inline"`
|
Refactor SD configuration to remove `config` dependency (#3629)
* refactor: move targetGroup struct and CheckOverflow() to their own package
* refactor: move auth and security related structs to a utility package, fix import error in utility package
* refactor: Azure SD, remove SD struct from config
* refactor: DNS SD, remove SD struct from config into dns package
* refactor: ec2 SD, move SD struct from config into the ec2 package
* refactor: file SD, move SD struct from config to file discovery package
* refactor: gce, move SD struct from config to gce discovery package
* refactor: move HTTPClientConfig and URL into util/config, fix import error in httputil
* refactor: consul, move SD struct from config into consul discovery package
* refactor: marathon, move SD struct from config into marathon discovery package
* refactor: triton, move SD struct from config to triton discovery package, fix test
* refactor: zookeeper, move SD structs from config to zookeeper discovery package
* refactor: openstack, remove SD struct from config, move into openstack discovery package
* refactor: kubernetes, move SD struct from config into kubernetes discovery package
* refactor: notifier, use targetgroup package instead of config
* refactor: tests for file, marathon, triton SD - use targetgroup package instead of config.TargetGroup
* refactor: retrieval, use targetgroup package instead of config.TargetGroup
* refactor: storage, use config util package
* refactor: discovery manager, use targetgroup package instead of config.TargetGroup
* refactor: use HTTPClient and TLS config from configUtil instead of config
* refactor: tests, use targetgroup package instead of config.TargetGroup
* refactor: fix tagetgroup.Group pointers that were removed by mistake
* refactor: openstack, kubernetes: drop prefixes
* refactor: remove import aliases forced due to vscode bug
* refactor: move main SD struct out of config into discovery/config
* refactor: rename configUtil to config_util
* refactor: rename yamlUtil to yaml_config
* refactor: kubernetes, remove prefixes
* refactor: move the TargetGroup package to discovery/
* refactor: fix order of imports
2017-12-29 12:01:34 -08:00
|
|
|
}
|
|
|
|
|
2020-08-20 05:48:26 -07:00
|
|
|
// Name returns the name of the Config.
|
|
|
|
func (*SDConfig) Name() string { return "azure" }
|
|
|
|
|
|
|
|
// NewDiscoverer returns a Discoverer for the Config.
|
|
|
|
func (c *SDConfig) NewDiscoverer(opts discovery.DiscovererOptions) (discovery.Discoverer, error) {
|
|
|
|
return NewDiscovery(c, opts.Logger), nil
|
|
|
|
}
|
|
|
|
|
2018-11-29 07:47:59 -08:00
|
|
|
func validateAuthParam(param, name string) error {
|
|
|
|
if len(param) == 0 {
|
2022-06-03 04:47:14 -07:00
|
|
|
return fmt.Errorf("azure SD configuration requires a %s", name)
|
2018-11-29 07:47:59 -08:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
Refactor SD configuration to remove `config` dependency (#3629)
* refactor: move targetGroup struct and CheckOverflow() to their own package
* refactor: move auth and security related structs to a utility package, fix import error in utility package
* refactor: Azure SD, remove SD struct from config
* refactor: DNS SD, remove SD struct from config into dns package
* refactor: ec2 SD, move SD struct from config into the ec2 package
* refactor: file SD, move SD struct from config to file discovery package
* refactor: gce, move SD struct from config to gce discovery package
* refactor: move HTTPClientConfig and URL into util/config, fix import error in httputil
* refactor: consul, move SD struct from config into consul discovery package
* refactor: marathon, move SD struct from config into marathon discovery package
* refactor: triton, move SD struct from config to triton discovery package, fix test
* refactor: zookeeper, move SD structs from config to zookeeper discovery package
* refactor: openstack, remove SD struct from config, move into openstack discovery package
* refactor: kubernetes, move SD struct from config into kubernetes discovery package
* refactor: notifier, use targetgroup package instead of config
* refactor: tests for file, marathon, triton SD - use targetgroup package instead of config.TargetGroup
* refactor: retrieval, use targetgroup package instead of config.TargetGroup
* refactor: storage, use config util package
* refactor: discovery manager, use targetgroup package instead of config.TargetGroup
* refactor: use HTTPClient and TLS config from configUtil instead of config
* refactor: tests, use targetgroup package instead of config.TargetGroup
* refactor: fix tagetgroup.Group pointers that were removed by mistake
* refactor: openstack, kubernetes: drop prefixes
* refactor: remove import aliases forced due to vscode bug
* refactor: move main SD struct out of config into discovery/config
* refactor: rename configUtil to config_util
* refactor: rename yamlUtil to yaml_config
* refactor: kubernetes, remove prefixes
* refactor: move the TargetGroup package to discovery/
* refactor: fix order of imports
2017-12-29 12:01:34 -08:00
|
|
|
// UnmarshalYAML implements the yaml.Unmarshaler interface.
|
|
|
|
func (c *SDConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|
|
|
*c = DefaultSDConfig
|
|
|
|
type plain SDConfig
|
|
|
|
err := unmarshal((*plain)(c))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-12-19 02:03:33 -08:00
|
|
|
|
2018-11-29 07:47:59 -08:00
|
|
|
if err = validateAuthParam(c.SubscriptionID, "subscription_id"); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-12-19 02:03:33 -08:00
|
|
|
|
|
|
|
if c.AuthenticationMethod == authMethodOAuth {
|
|
|
|
if err = validateAuthParam(c.TenantID, "tenant_id"); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err = validateAuthParam(c.ClientID, "client_id"); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err = validateAuthParam(string(c.ClientSecret), "client_secret"); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-11-29 07:47:59 -08:00
|
|
|
}
|
2018-12-19 02:03:33 -08:00
|
|
|
|
|
|
|
if c.AuthenticationMethod != authMethodOAuth && c.AuthenticationMethod != authMethodManagedIdentity {
|
2022-06-03 04:47:14 -07:00
|
|
|
return fmt.Errorf("unknown authentication_type %q. Supported types are %q or %q", c.AuthenticationMethod, authMethodOAuth, authMethodManagedIdentity)
|
2018-03-05 11:27:54 -08:00
|
|
|
}
|
2018-12-19 02:03:33 -08:00
|
|
|
|
2018-04-04 01:07:39 -07:00
|
|
|
return nil
|
Refactor SD configuration to remove `config` dependency (#3629)
* refactor: move targetGroup struct and CheckOverflow() to their own package
* refactor: move auth and security related structs to a utility package, fix import error in utility package
* refactor: Azure SD, remove SD struct from config
* refactor: DNS SD, remove SD struct from config into dns package
* refactor: ec2 SD, move SD struct from config into the ec2 package
* refactor: file SD, move SD struct from config to file discovery package
* refactor: gce, move SD struct from config to gce discovery package
* refactor: move HTTPClientConfig and URL into util/config, fix import error in httputil
* refactor: consul, move SD struct from config into consul discovery package
* refactor: marathon, move SD struct from config into marathon discovery package
* refactor: triton, move SD struct from config to triton discovery package, fix test
* refactor: zookeeper, move SD structs from config to zookeeper discovery package
* refactor: openstack, remove SD struct from config, move into openstack discovery package
* refactor: kubernetes, move SD struct from config into kubernetes discovery package
* refactor: notifier, use targetgroup package instead of config
* refactor: tests for file, marathon, triton SD - use targetgroup package instead of config.TargetGroup
* refactor: retrieval, use targetgroup package instead of config.TargetGroup
* refactor: storage, use config util package
* refactor: discovery manager, use targetgroup package instead of config.TargetGroup
* refactor: use HTTPClient and TLS config from configUtil instead of config
* refactor: tests, use targetgroup package instead of config.TargetGroup
* refactor: fix tagetgroup.Group pointers that were removed by mistake
* refactor: openstack, kubernetes: drop prefixes
* refactor: remove import aliases forced due to vscode bug
* refactor: move main SD struct out of config into discovery/config
* refactor: rename configUtil to config_util
* refactor: rename yamlUtil to yaml_config
* refactor: kubernetes, remove prefixes
* refactor: move the TargetGroup package to discovery/
* refactor: fix order of imports
2017-12-29 12:01:34 -08:00
|
|
|
}
|
|
|
|
|
2017-03-16 16:29:47 -07:00
|
|
|
type Discovery struct {
|
2019-03-25 03:54:22 -07:00
|
|
|
*refresh.Discovery
|
|
|
|
logger log.Logger
|
|
|
|
cfg *SDConfig
|
|
|
|
port int
|
2016-04-06 20:47:02 -07:00
|
|
|
}
|
|
|
|
|
2016-11-21 06:51:36 -08:00
|
|
|
// NewDiscovery returns a new AzureDiscovery which periodically refreshes its targets.
|
Refactor SD configuration to remove `config` dependency (#3629)
* refactor: move targetGroup struct and CheckOverflow() to their own package
* refactor: move auth and security related structs to a utility package, fix import error in utility package
* refactor: Azure SD, remove SD struct from config
* refactor: DNS SD, remove SD struct from config into dns package
* refactor: ec2 SD, move SD struct from config into the ec2 package
* refactor: file SD, move SD struct from config to file discovery package
* refactor: gce, move SD struct from config to gce discovery package
* refactor: move HTTPClientConfig and URL into util/config, fix import error in httputil
* refactor: consul, move SD struct from config into consul discovery package
* refactor: marathon, move SD struct from config into marathon discovery package
* refactor: triton, move SD struct from config to triton discovery package, fix test
* refactor: zookeeper, move SD structs from config to zookeeper discovery package
* refactor: openstack, remove SD struct from config, move into openstack discovery package
* refactor: kubernetes, move SD struct from config into kubernetes discovery package
* refactor: notifier, use targetgroup package instead of config
* refactor: tests for file, marathon, triton SD - use targetgroup package instead of config.TargetGroup
* refactor: retrieval, use targetgroup package instead of config.TargetGroup
* refactor: storage, use config util package
* refactor: discovery manager, use targetgroup package instead of config.TargetGroup
* refactor: use HTTPClient and TLS config from configUtil instead of config
* refactor: tests, use targetgroup package instead of config.TargetGroup
* refactor: fix tagetgroup.Group pointers that were removed by mistake
* refactor: openstack, kubernetes: drop prefixes
* refactor: remove import aliases forced due to vscode bug
* refactor: move main SD struct out of config into discovery/config
* refactor: rename configUtil to config_util
* refactor: rename yamlUtil to yaml_config
* refactor: kubernetes, remove prefixes
* refactor: move the TargetGroup package to discovery/
* refactor: fix order of imports
2017-12-29 12:01:34 -08:00
|
|
|
func NewDiscovery(cfg *SDConfig, logger log.Logger) *Discovery {
|
2017-08-11 11:45:52 -07:00
|
|
|
if logger == nil {
|
|
|
|
logger = log.NewNopLogger()
|
|
|
|
}
|
2019-03-25 03:54:22 -07:00
|
|
|
d := &Discovery{
|
|
|
|
cfg: cfg,
|
|
|
|
port: cfg.Port,
|
|
|
|
logger: logger,
|
2016-04-06 20:47:02 -07:00
|
|
|
}
|
2019-03-25 03:54:22 -07:00
|
|
|
d.Discovery = refresh.NewDiscovery(
|
|
|
|
logger,
|
|
|
|
"azure",
|
|
|
|
time.Duration(cfg.RefreshInterval),
|
|
|
|
d.refresh,
|
|
|
|
)
|
|
|
|
return d
|
2016-04-06 20:47:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// azureClient represents multiple Azure Resource Manager providers.
|
|
|
|
type azureClient struct {
|
2018-08-01 04:52:21 -07:00
|
|
|
nic network.InterfacesClient
|
|
|
|
vm compute.VirtualMachinesClient
|
|
|
|
vmss compute.VirtualMachineScaleSetsClient
|
|
|
|
vmssvm compute.VirtualMachineScaleSetVMsClient
|
2016-04-06 20:47:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// createAzureClient is a helper function for creating an Azure compute client to ARM.
|
Refactor SD configuration to remove `config` dependency (#3629)
* refactor: move targetGroup struct and CheckOverflow() to their own package
* refactor: move auth and security related structs to a utility package, fix import error in utility package
* refactor: Azure SD, remove SD struct from config
* refactor: DNS SD, remove SD struct from config into dns package
* refactor: ec2 SD, move SD struct from config into the ec2 package
* refactor: file SD, move SD struct from config to file discovery package
* refactor: gce, move SD struct from config to gce discovery package
* refactor: move HTTPClientConfig and URL into util/config, fix import error in httputil
* refactor: consul, move SD struct from config into consul discovery package
* refactor: marathon, move SD struct from config into marathon discovery package
* refactor: triton, move SD struct from config to triton discovery package, fix test
* refactor: zookeeper, move SD structs from config to zookeeper discovery package
* refactor: openstack, remove SD struct from config, move into openstack discovery package
* refactor: kubernetes, move SD struct from config into kubernetes discovery package
* refactor: notifier, use targetgroup package instead of config
* refactor: tests for file, marathon, triton SD - use targetgroup package instead of config.TargetGroup
* refactor: retrieval, use targetgroup package instead of config.TargetGroup
* refactor: storage, use config util package
* refactor: discovery manager, use targetgroup package instead of config.TargetGroup
* refactor: use HTTPClient and TLS config from configUtil instead of config
* refactor: tests, use targetgroup package instead of config.TargetGroup
* refactor: fix tagetgroup.Group pointers that were removed by mistake
* refactor: openstack, kubernetes: drop prefixes
* refactor: remove import aliases forced due to vscode bug
* refactor: move main SD struct out of config into discovery/config
* refactor: rename configUtil to config_util
* refactor: rename yamlUtil to yaml_config
* refactor: kubernetes, remove prefixes
* refactor: move the TargetGroup package to discovery/
* refactor: fix order of imports
2017-12-29 12:01:34 -08:00
|
|
|
func createAzureClient(cfg SDConfig) (azureClient, error) {
|
2018-09-04 08:55:40 -07:00
|
|
|
env, err := azure.EnvironmentFromName(cfg.Environment)
|
|
|
|
if err != nil {
|
|
|
|
return azureClient{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
activeDirectoryEndpoint := env.ActiveDirectoryEndpoint
|
|
|
|
resourceManagerEndpoint := env.ResourceManagerEndpoint
|
|
|
|
|
2016-04-06 20:47:02 -07:00
|
|
|
var c azureClient
|
2018-12-19 02:03:33 -08:00
|
|
|
|
|
|
|
var spt *adal.ServicePrincipalToken
|
|
|
|
|
|
|
|
switch cfg.AuthenticationMethod {
|
|
|
|
case authMethodManagedIdentity:
|
2022-03-28 16:21:23 -07:00
|
|
|
spt, err = adal.NewServicePrincipalTokenFromManagedIdentity(resourceManagerEndpoint, &adal.ManagedIdentityOptions{ClientID: cfg.ClientID})
|
2018-12-19 02:03:33 -08:00
|
|
|
if err != nil {
|
|
|
|
return azureClient{}, err
|
|
|
|
}
|
|
|
|
case authMethodOAuth:
|
|
|
|
oauthConfig, err := adal.NewOAuthConfig(activeDirectoryEndpoint, cfg.TenantID)
|
|
|
|
if err != nil {
|
|
|
|
return azureClient{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
spt, err = adal.NewServicePrincipalToken(*oauthConfig, cfg.ClientID, string(cfg.ClientSecret), resourceManagerEndpoint)
|
|
|
|
if err != nil {
|
|
|
|
return azureClient{}, err
|
|
|
|
}
|
2016-04-06 20:47:02 -07:00
|
|
|
}
|
|
|
|
|
2021-10-20 14:09:58 -07:00
|
|
|
client, err := config_util.NewClientFromConfig(cfg.HTTPClientConfig, "azure_sd")
|
|
|
|
if err != nil {
|
|
|
|
return azureClient{}, err
|
|
|
|
}
|
|
|
|
sender := autorest.DecorateSender(client)
|
2022-01-28 04:36:04 -08:00
|
|
|
preparer := autorest.WithUserAgent(userAgent)
|
2021-10-20 14:09:58 -07:00
|
|
|
|
2018-09-04 08:55:40 -07:00
|
|
|
bearerAuthorizer := autorest.NewBearerAuthorizer(spt)
|
|
|
|
|
|
|
|
c.vm = compute.NewVirtualMachinesClientWithBaseURI(resourceManagerEndpoint, cfg.SubscriptionID)
|
|
|
|
c.vm.Authorizer = bearerAuthorizer
|
2021-10-20 14:09:58 -07:00
|
|
|
c.vm.Sender = sender
|
2022-01-28 04:36:04 -08:00
|
|
|
c.vm.RequestInspector = preparer
|
2016-04-06 20:47:02 -07:00
|
|
|
|
2018-09-04 08:55:40 -07:00
|
|
|
c.nic = network.NewInterfacesClientWithBaseURI(resourceManagerEndpoint, cfg.SubscriptionID)
|
|
|
|
c.nic.Authorizer = bearerAuthorizer
|
2021-10-20 14:09:58 -07:00
|
|
|
c.nic.Sender = sender
|
2022-01-28 04:36:04 -08:00
|
|
|
c.nic.RequestInspector = preparer
|
2016-04-06 20:47:02 -07:00
|
|
|
|
2018-09-04 08:55:40 -07:00
|
|
|
c.vmss = compute.NewVirtualMachineScaleSetsClientWithBaseURI(resourceManagerEndpoint, cfg.SubscriptionID)
|
|
|
|
c.vmss.Authorizer = bearerAuthorizer
|
2022-01-28 04:36:04 -08:00
|
|
|
c.vmss.Sender = sender
|
|
|
|
c.vmss.RequestInspector = preparer
|
2018-08-01 04:52:21 -07:00
|
|
|
|
2018-09-04 08:55:40 -07:00
|
|
|
c.vmssvm = compute.NewVirtualMachineScaleSetVMsClientWithBaseURI(resourceManagerEndpoint, cfg.SubscriptionID)
|
|
|
|
c.vmssvm.Authorizer = bearerAuthorizer
|
2021-10-20 14:09:58 -07:00
|
|
|
c.vmssvm.Sender = sender
|
2022-01-28 04:36:04 -08:00
|
|
|
c.vmssvm.RequestInspector = preparer
|
2018-08-01 04:52:21 -07:00
|
|
|
|
2016-04-06 20:47:02 -07:00
|
|
|
return c, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// azureResource represents a resource identifier in Azure.
|
|
|
|
type azureResource struct {
|
|
|
|
Name string
|
|
|
|
ResourceGroup string
|
|
|
|
}
|
|
|
|
|
2018-08-01 04:52:21 -07:00
|
|
|
// virtualMachine represents an Azure virtual machine (which can also be created by a VMSS)
|
|
|
|
type virtualMachine struct {
|
2019-03-15 09:18:37 -07:00
|
|
|
ID string
|
|
|
|
Name string
|
2021-07-25 09:34:32 -07:00
|
|
|
ComputerName string
|
2019-03-15 09:18:37 -07:00
|
|
|
Type string
|
|
|
|
Location string
|
|
|
|
OsType string
|
|
|
|
ScaleSet string
|
|
|
|
Tags map[string]*string
|
|
|
|
NetworkInterfaces []string
|
2018-08-01 04:52:21 -07:00
|
|
|
}
|
|
|
|
|
2016-04-06 20:47:02 -07:00
|
|
|
// Create a new azureResource object from an ID string.
|
2017-04-28 08:12:38 -07:00
|
|
|
func newAzureResourceFromID(id string, logger log.Logger) (azureResource, error) {
|
2016-04-06 20:47:02 -07:00
|
|
|
// Resource IDs have the following format.
|
|
|
|
// /subscriptions/SUBSCRIPTION_ID/resourceGroups/RESOURCE_GROUP/providers/PROVIDER/TYPE/NAME
|
2018-11-27 08:44:29 -08:00
|
|
|
// or if embedded resource then
|
2018-08-01 04:52:21 -07:00
|
|
|
// /subscriptions/SUBSCRIPTION_ID/resourceGroups/RESOURCE_GROUP/providers/PROVIDER/TYPE/NAME/TYPE/NAME
|
2016-04-06 20:47:02 -07:00
|
|
|
s := strings.Split(id, "/")
|
2018-08-01 04:52:21 -07:00
|
|
|
if len(s) != 9 && len(s) != 11 {
|
2022-06-03 04:47:14 -07:00
|
|
|
err := fmt.Errorf("invalid ID '%s'. Refusing to create azureResource", id)
|
2017-08-11 11:45:52 -07:00
|
|
|
level.Error(logger).Log("err", err)
|
2016-04-06 20:47:02 -07:00
|
|
|
return azureResource{}, err
|
|
|
|
}
|
2018-08-01 04:52:21 -07:00
|
|
|
|
2016-04-06 20:47:02 -07:00
|
|
|
return azureResource{
|
|
|
|
Name: strings.ToLower(s[8]),
|
|
|
|
ResourceGroup: strings.ToLower(s[4]),
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2019-03-25 03:54:22 -07:00
|
|
|
func (d *Discovery) refresh(ctx context.Context) ([]*targetgroup.Group, error) {
|
2017-08-11 11:45:52 -07:00
|
|
|
defer level.Debug(d.logger).Log("msg", "Azure discovery completed")
|
|
|
|
|
2017-03-16 16:29:47 -07:00
|
|
|
client, err := createAzureClient(*d.cfg)
|
2016-04-06 20:47:02 -07:00
|
|
|
if err != nil {
|
2022-03-31 05:50:17 -07:00
|
|
|
failuresCount.Inc()
|
2022-06-03 04:47:14 -07:00
|
|
|
return nil, fmt.Errorf("could not create Azure client: %w", err)
|
2016-04-06 20:47:02 -07:00
|
|
|
}
|
|
|
|
|
2022-03-28 16:21:23 -07:00
|
|
|
machines, err := client.getVMs(ctx, d.cfg.ResourceGroup)
|
2016-04-06 20:47:02 -07:00
|
|
|
if err != nil {
|
2022-03-31 05:50:17 -07:00
|
|
|
failuresCount.Inc()
|
2022-06-03 04:47:14 -07:00
|
|
|
return nil, fmt.Errorf("could not get virtual machines: %w", err)
|
2016-04-06 20:47:02 -07:00
|
|
|
}
|
|
|
|
|
2018-08-01 04:52:21 -07:00
|
|
|
level.Debug(d.logger).Log("msg", "Found virtual machines during Azure discovery.", "count", len(machines))
|
|
|
|
|
|
|
|
// Load the vms managed by scale sets.
|
2022-03-28 16:21:23 -07:00
|
|
|
scaleSets, err := client.getScaleSets(ctx, d.cfg.ResourceGroup)
|
2018-08-01 04:52:21 -07:00
|
|
|
if err != nil {
|
2022-03-31 05:50:17 -07:00
|
|
|
failuresCount.Inc()
|
2022-06-03 04:47:14 -07:00
|
|
|
return nil, fmt.Errorf("could not get virtual machine scale sets: %w", err)
|
2018-08-01 04:52:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, scaleSet := range scaleSets {
|
2019-01-28 10:30:29 -08:00
|
|
|
scaleSetVms, err := client.getScaleSetVMs(ctx, scaleSet)
|
2016-04-06 20:47:02 -07:00
|
|
|
if err != nil {
|
2022-03-31 05:50:17 -07:00
|
|
|
failuresCount.Inc()
|
2022-06-03 04:47:14 -07:00
|
|
|
return nil, fmt.Errorf("could not get virtual machine scale set vms: %w", err)
|
2016-04-06 20:47:02 -07:00
|
|
|
}
|
2018-08-01 04:52:21 -07:00
|
|
|
machines = append(machines, scaleSetVms...)
|
2016-04-06 20:47:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// We have the slice of machines. Now turn them into targets.
|
|
|
|
// Doing them in go routines because the network interface calls are slow.
|
|
|
|
type target struct {
|
|
|
|
labelSet model.LabelSet
|
|
|
|
err error
|
|
|
|
}
|
|
|
|
|
2019-01-18 00:55:47 -08:00
|
|
|
var wg sync.WaitGroup
|
|
|
|
wg.Add(len(machines))
|
2016-04-06 20:47:02 -07:00
|
|
|
ch := make(chan target, len(machines))
|
2022-03-31 05:50:17 -07:00
|
|
|
for _, vm := range machines {
|
|
|
|
go func(vm virtualMachine) {
|
2019-01-18 00:55:47 -08:00
|
|
|
defer wg.Done()
|
2018-08-01 04:52:21 -07:00
|
|
|
r, err := newAzureResourceFromID(vm.ID, d.logger)
|
2016-04-06 20:47:02 -07:00
|
|
|
if err != nil {
|
|
|
|
ch <- target{labelSet: nil, err: err}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
labels := model.LabelSet{
|
2018-12-07 01:40:45 -08:00
|
|
|
azureLabelSubscriptionID: model.LabelValue(d.cfg.SubscriptionID),
|
|
|
|
azureLabelTenantID: model.LabelValue(d.cfg.TenantID),
|
2018-08-01 04:52:21 -07:00
|
|
|
azureLabelMachineID: model.LabelValue(vm.ID),
|
|
|
|
azureLabelMachineName: model.LabelValue(vm.Name),
|
2021-07-25 09:34:32 -07:00
|
|
|
azureLabelMachineComputerName: model.LabelValue(vm.ComputerName),
|
2018-08-01 04:52:21 -07:00
|
|
|
azureLabelMachineOSType: model.LabelValue(vm.OsType),
|
|
|
|
azureLabelMachineLocation: model.LabelValue(vm.Location),
|
2016-04-06 20:47:02 -07:00
|
|
|
azureLabelMachineResourceGroup: model.LabelValue(r.ResourceGroup),
|
|
|
|
}
|
|
|
|
|
2018-08-01 04:52:21 -07:00
|
|
|
if vm.ScaleSet != "" {
|
|
|
|
labels[azureLabelMachineScaleSet] = model.LabelValue(vm.ScaleSet)
|
|
|
|
}
|
|
|
|
|
2020-05-01 23:25:44 -07:00
|
|
|
for k, v := range vm.Tags {
|
|
|
|
name := strutil.SanitizeLabelName(k)
|
|
|
|
labels[azureLabelMachineTag+model.LabelName(name)] = model.LabelValue(*v)
|
2016-04-06 20:47:02 -07:00
|
|
|
}
|
|
|
|
|
2016-05-03 21:42:27 -07:00
|
|
|
// Get the IP address information via separate call to the network provider.
|
2019-03-15 09:18:37 -07:00
|
|
|
for _, nicID := range vm.NetworkInterfaces {
|
|
|
|
networkInterface, err := client.getNetworkInterfaceByID(ctx, nicID)
|
2016-04-06 20:47:02 -07:00
|
|
|
if err != nil {
|
2022-03-31 05:50:17 -07:00
|
|
|
if errors.Is(err, errorNotFound) {
|
|
|
|
level.Warn(d.logger).Log("msg", "Network interface does not exist", "name", nicID, "err", err)
|
|
|
|
} else {
|
|
|
|
ch <- target{labelSet: nil, err: err}
|
|
|
|
}
|
2016-04-06 20:47:02 -07:00
|
|
|
// Get out of this routine because we cannot continue without a network interface.
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-01-28 10:30:29 -08:00
|
|
|
if networkInterface.InterfacePropertiesFormat == nil {
|
2018-11-19 04:23:12 -08:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2018-12-12 00:27:12 -08:00
|
|
|
// Unfortunately Azure does not return information on whether a VM is deallocated.
|
|
|
|
// This information is available via another API call however the Go SDK does not
|
|
|
|
// yet support this. On deallocated machines, this value happens to be nil so it
|
|
|
|
// is a cheap and easy way to determine if a machine is allocated or not.
|
2019-01-28 10:30:29 -08:00
|
|
|
if networkInterface.Primary == nil {
|
2018-12-12 00:27:12 -08:00
|
|
|
level.Debug(d.logger).Log("msg", "Skipping deallocated virtual machine", "machine", vm.Name)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-01-28 10:30:29 -08:00
|
|
|
if *networkInterface.Primary {
|
|
|
|
for _, ip := range *networkInterface.IPConfigurations {
|
2022-02-11 11:26:28 -08:00
|
|
|
// IPAddress is a field defined in PublicIPAddressPropertiesFormat,
|
|
|
|
// therefore we need to validate that both are not nil.
|
|
|
|
if ip.PublicIPAddress != nil && ip.PublicIPAddress.PublicIPAddressPropertiesFormat != nil && ip.PublicIPAddress.IPAddress != nil {
|
2019-04-17 08:05:44 -07:00
|
|
|
labels[azureLabelMachinePublicIP] = model.LabelValue(*ip.PublicIPAddress.IPAddress)
|
|
|
|
}
|
2019-01-28 10:30:29 -08:00
|
|
|
if ip.PrivateIPAddress != nil {
|
|
|
|
labels[azureLabelMachinePrivateIP] = model.LabelValue(*ip.PrivateIPAddress)
|
|
|
|
address := net.JoinHostPort(*ip.PrivateIPAddress, fmt.Sprintf("%d", d.port))
|
2016-04-06 20:47:02 -07:00
|
|
|
labels[model.AddressLabel] = model.LabelValue(address)
|
|
|
|
ch <- target{labelSet: labels, err: nil}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
// If we made it here, we don't have a private IP which should be impossible.
|
|
|
|
// Return an empty target and error to ensure an all or nothing situation.
|
2022-06-03 04:47:14 -07:00
|
|
|
err = fmt.Errorf("unable to find a private IP for VM %s", vm.Name)
|
2016-04-06 20:47:02 -07:00
|
|
|
ch <- target{labelSet: nil, err: err}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-03-31 05:50:17 -07:00
|
|
|
}(vm)
|
2016-04-06 20:47:02 -07:00
|
|
|
}
|
|
|
|
|
2019-01-18 00:55:47 -08:00
|
|
|
wg.Wait()
|
|
|
|
close(ch)
|
|
|
|
|
2019-03-25 03:54:22 -07:00
|
|
|
var tg targetgroup.Group
|
2019-01-18 00:55:47 -08:00
|
|
|
for tgt := range ch {
|
2016-04-06 20:47:02 -07:00
|
|
|
if tgt.err != nil {
|
2022-03-31 05:50:17 -07:00
|
|
|
failuresCount.Inc()
|
2022-06-03 04:47:14 -07:00
|
|
|
return nil, fmt.Errorf("unable to complete Azure service discovery: %w", tgt.err)
|
2016-04-06 20:47:02 -07:00
|
|
|
}
|
|
|
|
if tgt.labelSet != nil {
|
|
|
|
tg.Targets = append(tg.Targets, tgt.labelSet)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-25 03:54:22 -07:00
|
|
|
return []*targetgroup.Group{&tg}, nil
|
2016-04-06 20:47:02 -07:00
|
|
|
}
|
2018-08-01 04:52:21 -07:00
|
|
|
|
2022-03-28 16:21:23 -07:00
|
|
|
func (client *azureClient) getVMs(ctx context.Context, resourceGroup string) ([]virtualMachine, error) {
|
2018-09-04 08:55:40 -07:00
|
|
|
var vms []virtualMachine
|
2022-03-28 16:21:23 -07:00
|
|
|
var result compute.VirtualMachineListResultPage
|
|
|
|
var err error
|
|
|
|
if len(resourceGroup) == 0 {
|
|
|
|
result, err = client.vm.ListAll(ctx)
|
|
|
|
} else {
|
|
|
|
result, err = client.vm.List(ctx, resourceGroup)
|
|
|
|
}
|
2018-08-01 04:52:21 -07:00
|
|
|
if err != nil {
|
2022-06-03 04:47:14 -07:00
|
|
|
return nil, fmt.Errorf("could not list virtual machines: %w", err)
|
2018-08-01 04:52:21 -07:00
|
|
|
}
|
2019-01-28 10:30:29 -08:00
|
|
|
for result.NotDone() {
|
|
|
|
for _, vm := range result.Values() {
|
2018-08-01 04:52:21 -07:00
|
|
|
vms = append(vms, mapFromVM(vm))
|
|
|
|
}
|
2019-03-20 02:03:47 -07:00
|
|
|
err = result.NextWithContext(ctx)
|
|
|
|
if err != nil {
|
2022-06-03 04:47:14 -07:00
|
|
|
return nil, fmt.Errorf("could not list virtual machines: %w", err)
|
2019-03-20 02:03:47 -07:00
|
|
|
}
|
2018-08-01 04:52:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return vms, nil
|
|
|
|
}
|
|
|
|
|
2022-03-28 16:21:23 -07:00
|
|
|
type VmssListResultPage interface {
|
|
|
|
NextWithContext(ctx context.Context) (err error)
|
|
|
|
NotDone() bool
|
|
|
|
Values() []compute.VirtualMachineScaleSet
|
|
|
|
}
|
|
|
|
|
|
|
|
func (client *azureClient) getScaleSets(ctx context.Context, resourceGroup string) ([]compute.VirtualMachineScaleSet, error) {
|
2018-09-04 08:55:40 -07:00
|
|
|
var scaleSets []compute.VirtualMachineScaleSet
|
2022-03-28 16:21:23 -07:00
|
|
|
var result VmssListResultPage
|
|
|
|
var err error
|
|
|
|
if len(resourceGroup) == 0 {
|
|
|
|
var rtn compute.VirtualMachineScaleSetListWithLinkResultPage
|
|
|
|
rtn, err = client.vmss.ListAll(ctx)
|
|
|
|
if err != nil {
|
2022-06-03 04:47:14 -07:00
|
|
|
return nil, fmt.Errorf("could not list virtual machine scale sets: %w", err)
|
2022-03-28 16:21:23 -07:00
|
|
|
}
|
|
|
|
result = &rtn
|
|
|
|
} else {
|
|
|
|
var rtn compute.VirtualMachineScaleSetListResultPage
|
|
|
|
rtn, err = client.vmss.List(ctx, resourceGroup)
|
|
|
|
if err != nil {
|
2022-06-03 04:47:14 -07:00
|
|
|
return nil, fmt.Errorf("could not list virtual machine scale sets: %w", err)
|
2022-03-28 16:21:23 -07:00
|
|
|
}
|
|
|
|
result = &rtn
|
2018-08-01 04:52:21 -07:00
|
|
|
}
|
2022-03-28 16:21:23 -07:00
|
|
|
|
2019-01-28 10:30:29 -08:00
|
|
|
for result.NotDone() {
|
2019-03-20 02:03:47 -07:00
|
|
|
scaleSets = append(scaleSets, result.Values()...)
|
2019-01-28 10:30:29 -08:00
|
|
|
err = result.NextWithContext(ctx)
|
2018-08-01 04:52:21 -07:00
|
|
|
if err != nil {
|
2022-06-03 04:47:14 -07:00
|
|
|
return nil, fmt.Errorf("could not list virtual machine scale sets: %w", err)
|
2018-08-01 04:52:21 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return scaleSets, nil
|
|
|
|
}
|
|
|
|
|
2019-01-28 10:30:29 -08:00
|
|
|
func (client *azureClient) getScaleSetVMs(ctx context.Context, scaleSet compute.VirtualMachineScaleSet) ([]virtualMachine, error) {
|
2018-09-04 08:55:40 -07:00
|
|
|
var vms []virtualMachine
|
2021-10-22 01:06:44 -07:00
|
|
|
// TODO do we really need to fetch the resourcegroup this way?
|
2018-08-01 04:52:21 -07:00
|
|
|
r, err := newAzureResourceFromID(*scaleSet.ID, nil)
|
|
|
|
if err != nil {
|
2022-06-03 04:47:14 -07:00
|
|
|
return nil, fmt.Errorf("could not parse scale set ID: %w", err)
|
2018-08-01 04:52:21 -07:00
|
|
|
}
|
|
|
|
|
2019-01-28 10:30:29 -08:00
|
|
|
result, err := client.vmssvm.List(ctx, r.ResourceGroup, *(scaleSet.Name), "", "", "")
|
2018-08-01 04:52:21 -07:00
|
|
|
if err != nil {
|
2022-06-03 04:47:14 -07:00
|
|
|
return nil, fmt.Errorf("could not list virtual machine scale set vms: %w", err)
|
2018-08-01 04:52:21 -07:00
|
|
|
}
|
2019-01-28 10:30:29 -08:00
|
|
|
for result.NotDone() {
|
|
|
|
for _, vm := range result.Values() {
|
2018-08-01 04:52:21 -07:00
|
|
|
vms = append(vms, mapFromVMScaleSetVM(vm, *scaleSet.Name))
|
|
|
|
}
|
2019-03-20 02:03:47 -07:00
|
|
|
err = result.NextWithContext(ctx)
|
|
|
|
if err != nil {
|
2022-06-03 04:47:14 -07:00
|
|
|
return nil, fmt.Errorf("could not list virtual machine scale set vms: %w", err)
|
2019-03-20 02:03:47 -07:00
|
|
|
}
|
2018-08-01 04:52:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
return vms, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func mapFromVM(vm compute.VirtualMachine) virtualMachine {
|
2019-01-28 10:30:29 -08:00
|
|
|
osType := string(vm.StorageProfile.OsDisk.OsType)
|
2018-08-02 02:10:17 -07:00
|
|
|
tags := map[string]*string{}
|
2019-03-15 09:18:37 -07:00
|
|
|
networkInterfaces := []string{}
|
2021-07-28 06:53:17 -07:00
|
|
|
var computerName string
|
2018-08-02 02:10:17 -07:00
|
|
|
|
|
|
|
if vm.Tags != nil {
|
2019-01-28 10:30:29 -08:00
|
|
|
tags = vm.Tags
|
2018-08-02 02:10:17 -07:00
|
|
|
}
|
2018-08-01 04:52:21 -07:00
|
|
|
|
2019-03-15 09:18:37 -07:00
|
|
|
if vm.NetworkProfile != nil {
|
|
|
|
for _, vmNIC := range *(vm.NetworkProfile.NetworkInterfaces) {
|
|
|
|
networkInterfaces = append(networkInterfaces, *vmNIC.ID)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-24 15:30:18 -07:00
|
|
|
if vm.VirtualMachineProperties != nil &&
|
|
|
|
vm.VirtualMachineProperties.OsProfile != nil &&
|
|
|
|
vm.VirtualMachineProperties.OsProfile.ComputerName != nil {
|
2021-07-28 06:53:17 -07:00
|
|
|
computerName = *(vm.VirtualMachineProperties.OsProfile.ComputerName)
|
|
|
|
}
|
|
|
|
|
2018-08-01 04:52:21 -07:00
|
|
|
return virtualMachine{
|
2019-03-15 09:18:37 -07:00
|
|
|
ID: *(vm.ID),
|
|
|
|
Name: *(vm.Name),
|
2021-07-28 06:53:17 -07:00
|
|
|
ComputerName: computerName,
|
2019-03-15 09:18:37 -07:00
|
|
|
Type: *(vm.Type),
|
|
|
|
Location: *(vm.Location),
|
|
|
|
OsType: osType,
|
|
|
|
ScaleSet: "",
|
|
|
|
Tags: tags,
|
|
|
|
NetworkInterfaces: networkInterfaces,
|
2018-08-01 04:52:21 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func mapFromVMScaleSetVM(vm compute.VirtualMachineScaleSetVM, scaleSetName string) virtualMachine {
|
2019-01-28 10:30:29 -08:00
|
|
|
osType := string(vm.StorageProfile.OsDisk.OsType)
|
2018-08-02 02:10:17 -07:00
|
|
|
tags := map[string]*string{}
|
2019-03-15 09:18:37 -07:00
|
|
|
networkInterfaces := []string{}
|
2021-07-28 06:53:17 -07:00
|
|
|
var computerName string
|
2018-08-02 02:10:17 -07:00
|
|
|
|
|
|
|
if vm.Tags != nil {
|
2019-01-28 10:30:29 -08:00
|
|
|
tags = vm.Tags
|
2018-08-02 02:10:17 -07:00
|
|
|
}
|
2018-08-01 04:52:21 -07:00
|
|
|
|
2019-03-15 09:18:37 -07:00
|
|
|
if vm.NetworkProfile != nil {
|
|
|
|
for _, vmNIC := range *(vm.NetworkProfile.NetworkInterfaces) {
|
|
|
|
networkInterfaces = append(networkInterfaces, *vmNIC.ID)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-28 06:53:17 -07:00
|
|
|
if vm.VirtualMachineScaleSetVMProperties != nil && vm.VirtualMachineScaleSetVMProperties.OsProfile != nil {
|
|
|
|
computerName = *(vm.VirtualMachineScaleSetVMProperties.OsProfile.ComputerName)
|
|
|
|
}
|
|
|
|
|
2018-08-01 04:52:21 -07:00
|
|
|
return virtualMachine{
|
2019-03-15 09:18:37 -07:00
|
|
|
ID: *(vm.ID),
|
|
|
|
Name: *(vm.Name),
|
2021-07-28 06:53:17 -07:00
|
|
|
ComputerName: computerName,
|
2019-03-15 09:18:37 -07:00
|
|
|
Type: *(vm.Type),
|
|
|
|
Location: *(vm.Location),
|
|
|
|
OsType: osType,
|
|
|
|
ScaleSet: scaleSetName,
|
|
|
|
Tags: tags,
|
|
|
|
NetworkInterfaces: networkInterfaces,
|
2018-08-01 04:52:21 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-31 05:50:17 -07:00
|
|
|
var errorNotFound = errors.New("network interface does not exist")
|
|
|
|
|
|
|
|
// getNetworkInterfaceByID gets the network interface.
|
|
|
|
// If a 404 is returned from the Azure API, `errorNotFound` is returned.
|
|
|
|
// On all other errors, an autorest.DetailedError is returned.
|
2019-02-26 05:47:26 -08:00
|
|
|
func (client *azureClient) getNetworkInterfaceByID(ctx context.Context, networkInterfaceID string) (*network.Interface, error) {
|
2018-08-01 04:52:21 -07:00
|
|
|
result := network.Interface{}
|
|
|
|
queryParameters := map[string]interface{}{
|
2019-01-28 10:30:29 -08:00
|
|
|
"api-version": "2018-10-01",
|
2018-08-01 04:52:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
preparer := autorest.CreatePreparer(
|
|
|
|
autorest.AsGet(),
|
|
|
|
autorest.WithBaseURL(client.nic.BaseURI),
|
|
|
|
autorest.WithPath(networkInterfaceID),
|
2022-01-28 04:36:04 -08:00
|
|
|
autorest.WithQueryParameters(queryParameters),
|
|
|
|
autorest.WithUserAgent(userAgent))
|
2019-02-26 05:47:26 -08:00
|
|
|
req, err := preparer.Prepare((&http.Request{}).WithContext(ctx))
|
2018-08-01 04:52:21 -07:00
|
|
|
if err != nil {
|
2019-01-28 10:30:29 -08:00
|
|
|
return nil, autorest.NewErrorWithError(err, "network.InterfacesClient", "Get", nil, "Failure preparing request")
|
2018-08-01 04:52:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
resp, err := client.nic.GetSender(req)
|
|
|
|
if err != nil {
|
2019-01-28 10:30:29 -08:00
|
|
|
return nil, autorest.NewErrorWithError(err, "network.InterfacesClient", "Get", resp, "Failure sending request")
|
2018-08-01 04:52:21 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
result, err = client.nic.GetResponder(resp)
|
|
|
|
if err != nil {
|
2022-03-31 05:50:17 -07:00
|
|
|
if resp.StatusCode == http.StatusNotFound {
|
|
|
|
return nil, errorNotFound
|
|
|
|
}
|
2019-01-28 13:31:45 -08:00
|
|
|
return nil, autorest.NewErrorWithError(err, "network.InterfacesClient", "Get", resp, "Failure responding to request")
|
2018-08-01 04:52:21 -07:00
|
|
|
}
|
|
|
|
|
2019-01-28 10:30:29 -08:00
|
|
|
return &result, nil
|
2018-08-01 04:52:21 -07:00
|
|
|
}
|