Skip to content

Commit

Permalink
Better azure ip handling
Browse files Browse the repository at this point in the history
  • Loading branch information
Raul Marrero committed Aug 29, 2019
1 parent f67ca47 commit d63a49c
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 8 deletions.
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ Below you will find documentation on how to use nginx-asg-sync.
- [Documentation](#documentation)
- [Supported Operating Systems](#supported-operating-systems)
- [Installation](#installation)
- [Configuration](#configuration)
- [NGINX Plus Configuration](#nginx-plus-configuration)
- [Configuration for Cloud Providers](#configuration-for-cloud-providers)
- [Usage](#usage)
- [Troubleshooting](#troubleshooting)
- [Building a Software Package](#building-a-software-package)
Expand All @@ -58,11 +58,6 @@ Support for other operating systems can be added.
* For Amazon Linux or CentOS/RHEL, run: `$ sudo rpm -i <package-name>.rpm`
* For Ubuntu, run: `$ sudo dpkg -i <package-name>.deb`

## Configuration

* For AWS, check [this example](./docs/aws.md).
* For Azure, check [this example](./docs/azure.md).

### NGINX Plus Configuration

As an example, we configure NGINX Plus to load balance two groups of instances -- backend-group-one and backend-group-two. NGINX Plus routes requests to the appropriate group based on the request URI:
Expand Down Expand Up @@ -141,6 +136,10 @@ Because cloud provider APIs return the instances IP addresses before the instanc

Small timeouts ensure that a health check will fail fast if the backend instance is not healthy. Also, the mandatory parameter ensures NGINX Plus won't consider a newly added instance healthy until a health check passes.

### Configuration for Cloud Providers

See the example for your cloud provider: [AWS](examples/aws.md), [Azure](examples/azure.md).

## Usage

nginx-asg-sync runs as a system service and supports the start/stop/restart commands.
Expand Down
27 changes: 26 additions & 1 deletion cmd/sync/azure.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ func (client *AzureClient) GetPrivateIPsForScalingGroup(name string) ([]string,
for _, iFace := range iFaces.Values() {
if iFace.VirtualMachine != nil && iFace.VirtualMachine.ID != nil {
for _, n := range *iFace.IPConfigurations {
if n.Primary != nil && *n.Primary && n.InterfaceIPConfigurationPropertiesFormat.PrivateIPAddress != nil {
ip := getPrimaryIPFromInterfaceIPConfiguration(n)
if ip != "" {
ips = append(ips, *n.InterfaceIPConfigurationPropertiesFormat.PrivateIPAddress)
break
}
Expand All @@ -76,6 +77,30 @@ func (client *AzureClient) GetPrivateIPsForScalingGroup(name string) ([]string,
return ips, nil
}

func getPrimaryIPFromInterfaceIPConfiguration(ipConfig network.InterfaceIPConfiguration) string {
if ipConfig == (network.InterfaceIPConfiguration{}) {
return ""
}

if ipConfig.Primary == nil {
return ""
}

if !*ipConfig.Primary {
return ""
}

if ipConfig.InterfaceIPConfigurationPropertiesFormat == nil {
return ""
}

if ipConfig.InterfaceIPConfigurationPropertiesFormat.PrivateIPAddress == nil {
return ""
}

return *ipConfig.InterfaceIPConfigurationPropertiesFormat.PrivateIPAddress
}

// CheckIfScalingGroupExists checks if the Virtual Machine Scale Set exists
func (client *AzureClient) CheckIfScalingGroupExists(name string) (bool, error) {
ctx := context.TODO()
Expand Down
64 changes: 63 additions & 1 deletion cmd/sync/azure_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package main

import "testing"
import (
"testing"

"github.com/Azure/azure-sdk-for-go/profiles/latest/network/mgmt/network"
)

type testInputAzure struct {
cfg *azureConfig
Expand Down Expand Up @@ -78,3 +82,61 @@ func TestValidateAzureConfigValid(t *testing.T) {
t.Errorf("validateAzureConfig() failed for the valid config: %v", err)
}
}

func TestGetPrimaryIPFromInterfaceIPConfiguration(t *testing.T) {
primary := true
address := "127.0.0.1"
ipConfig := network.InterfaceIPConfiguration{
InterfaceIPConfigurationPropertiesFormat: &network.InterfaceIPConfigurationPropertiesFormat{
Primary: &primary,
PrivateIPAddress: &address,
},
}

if getPrimaryIPFromInterfaceIPConfiguration(ipConfig) == "" {
t.Errorf("getPrimaryIPFromInterfaceIPConfiguration() returned an empty ip, expected: %v", address)
}
}

func TestGetPrimaryIPFromInterfaceIPConfigurationFail(t *testing.T) {
primaryFalse := false
primaryTrue := true
var tests = []struct {
ipConfig network.InterfaceIPConfiguration
msg string
}{
{
ipConfig: network.InterfaceIPConfiguration{},
msg: "empty primary",
},
{
ipConfig: network.InterfaceIPConfiguration{
InterfaceIPConfigurationPropertiesFormat: &network.InterfaceIPConfigurationPropertiesFormat{
Primary: &primaryFalse,
},
},
msg: "not primary interface",
},
{
ipConfig: network.InterfaceIPConfiguration{
InterfaceIPConfigurationPropertiesFormat: nil,
},
msg: "no interface properties",
},
{
ipConfig: network.InterfaceIPConfiguration{
InterfaceIPConfigurationPropertiesFormat: &network.InterfaceIPConfigurationPropertiesFormat{
Primary: &primaryTrue,
PrivateIPAddress: nil,
},
},
msg: "no private ip address",
},
}

for _, test := range tests {
if getPrimaryIPFromInterfaceIPConfiguration(test.ipConfig) != "" {
t.Errorf("getPrimaryIPFromInterfaceIPConfiguration() returned a non empty string for case: %v", test.msg)
}
}
}
File renamed without changes.
File renamed without changes.

0 comments on commit d63a49c

Please sign in to comment.