From d79ad810aa6e9e6f1033dab7fcc49b4e46e0c005 Mon Sep 17 00:00:00 2001 From: daniel-resdiary <109083091+daniel-resdiary@users.noreply.github.com> Date: Wed, 13 Dec 2023 12:38:16 +0000 Subject: [PATCH 1/2] Get VM Scale Set NIC (#13283) Calling `*armnetwork.InterfacesClient.Get()` doesn't work for Scale Set VM NIC, because these use a different Resource ID format. Use `*armnetwork.InterfacesClient.GetVirtualMachineScaleSetNetworkInterface()` instead. This needs both the scale set name and the instance ID, so add an `InstanceID` field to the `virtualMachine` struct. `InstanceID` is empty for a VM that isn't a ScaleSetVM. Signed-off-by: Daniel Nicholls --- discovery/azure/azure.go | 62 +++++++++++++++++++++++++++-------- discovery/azure/azure_test.go | 6 ++++ 2 files changed, 55 insertions(+), 13 deletions(-) diff --git a/discovery/azure/azure.go b/discovery/azure/azure.go index ef953b8026..dd5c1e5e21 100644 --- a/discovery/azure/azure.go +++ b/discovery/azure/azure.go @@ -106,7 +106,7 @@ func CloudConfigurationFromName(name string) (cloud.Configuration, error) { name = strings.ToUpper(name) env, ok := environments[name] if !ok { - return env, fmt.Errorf("There is no cloud configuration matching the name %q", name) + return env, fmt.Errorf("there is no cloud configuration matching the name %q", name) } return env, nil @@ -305,6 +305,7 @@ type virtualMachine struct { Location string OsType string ScaleSet string + InstanceID string Tags map[string]*string NetworkInterfaces []string Size string @@ -405,17 +406,31 @@ func (d *Discovery) refresh(ctx context.Context) ([]*targetgroup.Group, error) { networkInterface = v cacheHitCount.Add(1) } else { - networkInterface, err = client.getNetworkInterfaceByID(ctx, nicID) - if err != nil { - 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} + if vm.ScaleSet == "" { + networkInterface, err = client.getVMNetworkInterfaceByID(ctx, nicID) + if err != nil { + 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} + } + // Get out of this routine because we cannot continue without a network interface. + return } - // Get out of this routine because we cannot continue without a network interface. - return + d.addToCache(nicID, networkInterface) + } else { + networkInterface, err = client.getVMScaleSetVMNetworkInterfaceByID(ctx, nicID, vm.ScaleSet, vm.InstanceID) + if err != nil { + 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} + } + // Get out of this routine because we cannot continue without a network interface. + return + } + d.addToCache(nicID, networkInterface) } - d.addToCache(nicID, networkInterface) } if networkInterface.Properties == nil { @@ -623,6 +638,7 @@ func mapFromVMScaleSetVM(vm armcompute.VirtualMachineScaleSetVM, scaleSetName st Location: *(vm.Location), OsType: osType, ScaleSet: scaleSetName, + InstanceID: *(vm.InstanceID), Tags: tags, NetworkInterfaces: networkInterfaces, Size: size, @@ -631,9 +647,9 @@ func mapFromVMScaleSetVM(vm armcompute.VirtualMachineScaleSetVM, scaleSetName st var errorNotFound = errors.New("network interface does not exist") -// getNetworkInterfaceByID gets the network interface. +// getVMNetworkInterfaceByID gets the network interface. // If a 404 is returned from the Azure API, `errorNotFound` is returned. -func (client *azureClient) getNetworkInterfaceByID(ctx context.Context, networkInterfaceID string) (*armnetwork.Interface, error) { +func (client *azureClient) getVMNetworkInterfaceByID(ctx context.Context, networkInterfaceID string) (*armnetwork.Interface, error) { r, err := newAzureResourceFromID(networkInterfaceID, client.logger) if err != nil { return nil, fmt.Errorf("could not parse network interface ID: %w", err) @@ -645,7 +661,27 @@ func (client *azureClient) getNetworkInterfaceByID(ctx context.Context, networkI if errors.As(err, &responseError) && responseError.StatusCode == http.StatusNotFound { return nil, errorNotFound } - return nil, fmt.Errorf("Failed to retrieve Interface %v with error: %w", networkInterfaceID, err) + return nil, fmt.Errorf("failed to retrieve Interface %v with error: %w", networkInterfaceID, err) + } + + return &resp.Interface, nil +} + +// getVMScaleSetVMNetworkInterfaceByID gets the network interface. +// If a 404 is returned from the Azure API, `errorNotFound` is returned. +func (client *azureClient) getVMScaleSetVMNetworkInterfaceByID(ctx context.Context, networkInterfaceID, scaleSetName, instanceID string) (*armnetwork.Interface, error) { + r, err := newAzureResourceFromID(networkInterfaceID, client.logger) + if err != nil { + return nil, fmt.Errorf("could not parse network interface ID: %w", err) + } + + resp, err := client.nic.GetVirtualMachineScaleSetNetworkInterface(ctx, r.ResourceGroupName, scaleSetName, instanceID, r.Name, &armnetwork.InterfacesClientGetVirtualMachineScaleSetNetworkInterfaceOptions{Expand: to.Ptr("IPConfigurations/PublicIPAddress")}) + if err != nil { + var responseError *azcore.ResponseError + if errors.As(err, &responseError) && responseError.StatusCode == http.StatusNotFound { + return nil, errorNotFound + } + return nil, fmt.Errorf("failed to retrieve Interface %v with error: %w", networkInterfaceID, err) } return &resp.Interface, nil diff --git a/discovery/azure/azure_test.go b/discovery/azure/azure_test.go index 48f5b076c5..024cf75915 100644 --- a/discovery/azure/azure_test.go +++ b/discovery/azure/azure_test.go @@ -142,6 +142,7 @@ func TestMapFromVMScaleSetVMWithEmptyTags(t *testing.T) { vmSize := armcompute.VirtualMachineSizeTypes(size) osType := armcompute.OperatingSystemTypesLinux vmType := "type" + instanceID := "123" location := "westeurope" computerName := "computer_name" networkProfile := armcompute.NetworkProfile{ @@ -166,6 +167,7 @@ func TestMapFromVMScaleSetVMWithEmptyTags(t *testing.T) { ID: &id, Name: &name, Type: &vmType, + InstanceID: &instanceID, Location: &location, Tags: nil, Properties: properties, @@ -182,6 +184,7 @@ func TestMapFromVMScaleSetVMWithEmptyTags(t *testing.T) { Tags: map[string]*string{}, NetworkInterfaces: []string{}, ScaleSet: scaleSet, + InstanceID: instanceID, Size: size, } @@ -197,6 +200,7 @@ func TestMapFromVMScaleSetVMWithTags(t *testing.T) { vmSize := armcompute.VirtualMachineSizeTypes(size) osType := armcompute.OperatingSystemTypesLinux vmType := "type" + instanceID := "123" location := "westeurope" computerName := "computer_name" tags := map[string]*string{ @@ -224,6 +228,7 @@ func TestMapFromVMScaleSetVMWithTags(t *testing.T) { ID: &id, Name: &name, Type: &vmType, + InstanceID: &instanceID, Location: &location, Tags: tags, Properties: properties, @@ -240,6 +245,7 @@ func TestMapFromVMScaleSetVMWithTags(t *testing.T) { Tags: tags, NetworkInterfaces: []string{}, ScaleSet: scaleSet, + InstanceID: instanceID, Size: size, } From 20b4ef5d5827939c78f202aee782761a8745f08e Mon Sep 17 00:00:00 2001 From: bwplotka Date: Tue, 19 Dec 2023 19:21:42 +0000 Subject: [PATCH 2/2] Cut v2.49.0-rc.1 Signed-off-by: bwplotka --- CHANGELOG.md | 4 ++++ VERSION | 2 +- web/ui/module/codemirror-promql/package.json | 4 ++-- web/ui/module/lezer-promql/package.json | 2 +- web/ui/package-lock.json | 18 +++++++++--------- web/ui/package.json | 2 +- web/ui/react-app/package.json | 4 ++-- 7 files changed, 20 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57dcbcfd57..69ca76ca8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 2.49.0-rc.1 / 2023-12-19 + +* [BUGFIX] SD: Fix Azure VM Scale Set NIC issue. #13283 + ## 2.49.0-rc.0 / 2023-12-12 * [FEATURE] Promtool: Add `--run` flag promtool test rules command. #12206 diff --git a/VERSION b/VERSION index dcbcb992a2..da758087aa 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.49.0-rc.0 +2.49.0-rc.1 diff --git a/web/ui/module/codemirror-promql/package.json b/web/ui/module/codemirror-promql/package.json index 078433c94e..a8933b8a58 100644 --- a/web/ui/module/codemirror-promql/package.json +++ b/web/ui/module/codemirror-promql/package.json @@ -1,6 +1,6 @@ { "name": "@prometheus-io/codemirror-promql", - "version": "0.49.0-rc.0", + "version": "0.49.0-rc.1", "description": "a CodeMirror mode for the PromQL language", "types": "dist/esm/index.d.ts", "module": "dist/esm/index.js", @@ -29,7 +29,7 @@ }, "homepage": "https://github.com/prometheus/prometheus/blob/main/web/ui/module/codemirror-promql/README.md", "dependencies": { - "@prometheus-io/lezer-promql": "0.49.0-rc.0", + "@prometheus-io/lezer-promql": "0.49.0-rc.1", "lru-cache": "^7.18.3" }, "devDependencies": { diff --git a/web/ui/module/lezer-promql/package.json b/web/ui/module/lezer-promql/package.json index c49646868a..ba2a1d1b27 100644 --- a/web/ui/module/lezer-promql/package.json +++ b/web/ui/module/lezer-promql/package.json @@ -1,6 +1,6 @@ { "name": "@prometheus-io/lezer-promql", - "version": "0.49.0-rc.0", + "version": "0.49.0-rc.1", "description": "lezer-based PromQL grammar", "main": "dist/index.cjs", "type": "module", diff --git a/web/ui/package-lock.json b/web/ui/package-lock.json index cd769e93eb..8e9b009c20 100644 --- a/web/ui/package-lock.json +++ b/web/ui/package-lock.json @@ -1,12 +1,12 @@ { "name": "prometheus-io", - "version": "0.49.0-rc.0", + "version": "0.49.0-rc.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "prometheus-io", - "version": "0.49.0-rc.0", + "version": "0.49.0-rc.1", "workspaces": [ "react-app", "module/*" @@ -30,10 +30,10 @@ }, "module/codemirror-promql": { "name": "@prometheus-io/codemirror-promql", - "version": "0.49.0-rc.0", + "version": "0.49.0-rc.1", "license": "Apache-2.0", "dependencies": { - "@prometheus-io/lezer-promql": "0.49.0-rc.0", + "@prometheus-io/lezer-promql": "0.49.0-rc.1", "lru-cache": "^7.18.3" }, "devDependencies": { @@ -70,7 +70,7 @@ }, "module/lezer-promql": { "name": "@prometheus-io/lezer-promql", - "version": "0.49.0-rc.0", + "version": "0.49.0-rc.1", "license": "Apache-2.0", "devDependencies": { "@lezer/generator": "^1.5.1", @@ -20844,7 +20844,7 @@ }, "react-app": { "name": "@prometheus-io/app", - "version": "0.49.0-rc.0", + "version": "0.49.0-rc.1", "dependencies": { "@codemirror/autocomplete": "^6.11.1", "@codemirror/commands": "^6.3.2", @@ -20862,7 +20862,7 @@ "@lezer/lr": "^1.3.14", "@nexucis/fuzzy": "^0.4.1", "@nexucis/kvsearch": "^0.8.1", - "@prometheus-io/codemirror-promql": "0.49.0-rc.0", + "@prometheus-io/codemirror-promql": "0.49.0-rc.1", "bootstrap": "^4.6.2", "css.escape": "^1.5.1", "downshift": "^7.6.2", @@ -23551,7 +23551,7 @@ "@lezer/lr": "^1.3.14", "@nexucis/fuzzy": "^0.4.1", "@nexucis/kvsearch": "^0.8.1", - "@prometheus-io/codemirror-promql": "0.49.0-rc.0", + "@prometheus-io/codemirror-promql": "0.49.0-rc.1", "@testing-library/react-hooks": "^7.0.2", "@types/enzyme": "^3.10.18", "@types/flot": "0.0.36", @@ -23602,7 +23602,7 @@ "@lezer/common": "^1.1.1", "@lezer/highlight": "^1.2.0", "@lezer/lr": "^1.3.14", - "@prometheus-io/lezer-promql": "0.49.0-rc.0", + "@prometheus-io/lezer-promql": "0.49.0-rc.1", "isomorphic-fetch": "^3.0.0", "lru-cache": "^7.18.3", "nock": "^13.4.0" diff --git a/web/ui/package.json b/web/ui/package.json index 418b7857d0..cbbf0d7eac 100644 --- a/web/ui/package.json +++ b/web/ui/package.json @@ -28,5 +28,5 @@ "ts-jest": "^29.1.1", "typescript": "^4.9.5" }, - "version": "0.49.0-rc.0" + "version": "0.49.0-rc.1" } diff --git a/web/ui/react-app/package.json b/web/ui/react-app/package.json index 7d3336f3df..72d0450318 100644 --- a/web/ui/react-app/package.json +++ b/web/ui/react-app/package.json @@ -1,6 +1,6 @@ { "name": "@prometheus-io/app", - "version": "0.49.0-rc.0", + "version": "0.49.0-rc.1", "private": true, "dependencies": { "@codemirror/autocomplete": "^6.11.1", @@ -19,7 +19,7 @@ "@lezer/lr": "^1.3.14", "@nexucis/fuzzy": "^0.4.1", "@nexucis/kvsearch": "^0.8.1", - "@prometheus-io/codemirror-promql": "0.49.0-rc.0", + "@prometheus-io/codemirror-promql": "0.49.0-rc.1", "bootstrap": "^4.6.2", "css.escape": "^1.5.1", "downshift": "^7.6.2",