Skip to content

Commit

Permalink
azure: virtual network gateway connection: implement
Browse files Browse the repository at this point in the history
  • Loading branch information
Phreedom committed Mar 23, 2016
1 parent 2f3cd65 commit 087b821
Show file tree
Hide file tree
Showing 4 changed files with 298 additions and 0 deletions.
94 changes: 94 additions & 0 deletions nix/azure-gateway-connection.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
{ config, lib, pkgs, uuid, name, resources, ... }:

with lib;
with (import ./lib.nix lib);
{

options = (import ./azure-mgmt-credentials.nix lib "virtual network gateway connection") // {

name = mkOption {
example = "my-gateway-connection";
default = "nixops-${uuid}-${name}";
type = types.str;
description = "Name of the Azure virtual network gateway connection.";
};

resourceGroup = mkOption {
example = "xxx-my-group";
type = types.either types.str (resource "azure-resource-group");
description = "The name or resource of an Azure resource group to create the virtual network gateway connection in.";
};

location = mkOption {
example = "westus";
type = types.str;
description = "The Azure data center location where the virtual network gateway connection should be created.";
};

tags = mkOption {
default = {};
example = { environment = "production"; };
type = types.attrsOf types.str;
description = "Tag name/value pairs to associate with the virtual network gateway connection.";
};

virtualNetworkGateway1 = mkOption {
default = null;
example = "xxx-my-vnet-gateway";
type = types.nullOr (types.either types.str (resource "azure-virtual-network-gateway"));
description = ''
The Azure Resource Id or NixOps resource of
the first virtual network gateway in the connection.
'';
};

virtualNetworkGateway2 = mkOption {
default = null;
example = "xxx-my-vnet-gateway";
type = types.nullOr (types.either types.str (resource "azure-virtual-network-gateway"));
description = ''
The Azure Resource Id or NixOps resource of
the second virtual network gateway in the connection.
'';
};

localNetworkGateway2 = mkOption {
default = null;
example = "xxx-my-vnet-gateway";
type = types.nullOr (types.either types.str (resource "azure-local-network-gateway"));
description = ''
The Azure Resource Id or NixOps resource of
the second local network gateway in the connection.
'';
};

connectionType = mkOption {
example = "Vnet2Vnet";
type = types.str;
description = "The connection type of the virtual network gateway connection.";
};

routingWeight = mkOption {
example = 10;
type = types.int;
description = "The routing weight of the virtual network gateway connection.";
};

sharedKey = mkOption {
default = null;
example = "wNEf6Vkw0Ijx2vNvdQohbZtDCaoDYqE8";
type = types.nullOr types.str;
description = ''
IPSec shared key for the connection.
Leave empty to generate automaticaly.
'';
};

};

config = {
_type = "azure-gateway-connection";
resourceGroup = mkDefault resources.azureResourceGroups.def-group;
};

}
1 change: 1 addition & 0 deletions nix/eval-machine-info.nix
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ rec {
resources.azureDNSRecordSets = evalResources ./azure-dns-record-set.nix (zipAttrs resourcesByType.azureDNSRecordSets or []);
resources.azureDNSZones = evalResources ./azure-dns-zone.nix (zipAttrs resourcesByType.azureDNSZones or []);
resources.azureFiles = evalResources ./azure-file.nix (zipAttrs resourcesByType.azureFiles or []);
resources.azureGatewayConnections = evalAzureResources ./azure-gateway-connection.nix (zipAttrs resourcesByType.azureGatewayConnections or []);
resources.azureLoadBalancers = evalAzureResources ./azure-load-balancer.nix (zipAttrs resourcesByType.azureLoadBalancers or []);
resources.azureLocalNetworkGateways = evalAzureResources ./azure-local-network-gateway.nix (zipAttrs resourcesByType.azureLocalNetworkGateways or []);
resources.azureSecurityGroups = evalAzureResources ./azure-network-security-group.nix (zipAttrs resourcesByType.azureSecurityGroups or []);
Expand Down
2 changes: 2 additions & 0 deletions nixops/azure_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ def parse(cls, r_id):
'azure-virtual-network': {'provider':'Microsoft.Network', 'type': 'virtualNetworks' },
'azure-network-security-group': { 'provider':'Microsoft.Network', 'type': 'networkSecurityGroups' },
'azure-dns-zone': { 'provider':'Microsoft.Network', 'type': 'dnsZones' },
'azure-local-network-gateway': { 'provider':'Microsoft.Network', 'type': 'localNetworkGateways' },
'azure-virtual-network-gateway': { 'provider':'Microsoft.Network', 'type': 'virtualNetworkGateways' },
}


Expand Down
201 changes: 201 additions & 0 deletions nixops/resources/azure_gateway_connection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
# -*- coding: utf-8 -*-

# Automatic provisioning of Azure virtual network gateway connections.

import os
import azure

from nixops.util import attr_property
from nixops.azure_common import ResourceDefinition, ResourceState, ResId

from azure.mgmt.network import *

class AzureGatewayConnectionDefinition(ResourceDefinition):
"""Definition of an Azure Virtual Network Gateway Connection"""

@classmethod
def get_type(cls):
return "azure-gateway-connection"

@classmethod
def get_resource_type(cls):
return "azureGatewayConnections"

def __init__(self, xml):
ResourceDefinition.__init__(self, xml)

self.connection_name = self.get_option_value(xml, 'name', str)
self.copy_option(xml, 'resourceGroup', 'resource')
self.copy_option(xml, 'location', str, empty = False)
self.copy_tags(xml)

self.copy_option(xml, 'virtualNetworkGateway1', 'res-id', optional = True)
self.copy_option(xml, 'virtualNetworkGateway2', 'res-id', optional = True)
self.copy_option(xml, 'localNetworkGateway2', 'res-id', optional = True)
self.copy_option(xml, 'connectionType', str)
self.copy_option(xml, 'routingWeight', int)
self.copy_option(xml, 'sharedKey', str, optional = True)

def show_type(self):
return "{0} [{1}]".format(self.get_type(), self.location)


class AzureGatewayConnectionState(ResourceState):
"""State of an Azure Virtual Network Gateway Connection"""

connection_name = attr_property("azure.name", None)
resource_group = attr_property("azure.resourceGroup", None)
location = attr_property("azure.location", None)
tags = attr_property("azure.tags", {}, 'json')

virtual_network_gateway1 = attr_property("azure.virtualNetworkGateway1", None)
virtual_network_gateway2 = attr_property("azure.virtualNetworkGateway2", None)
local_network_gateway2 = attr_property("azure.localNetworkGateway2", None)
connection_type = attr_property("azure.connectionType", None)
routing_weight = attr_property("azure.routingWeight", None, int)
shared_key = attr_property("azure.sharedKey", None)

@classmethod
def get_type(cls):
return "azure-gateway-connection"

def show_type(self):
s = super(AzureGatewayConnectionState, self).show_type()
if self.state == self.UP: s = "{0} [{1}]".format(s, self.location)
return s

@property
def resource_id(self):
return self.connection_name

@property
def full_name(self):
return "Azure virtual network gateway connection '{0}'".format(self.resource_id)

def get_resource(self):
try:
return self.nrpc().virtual_network_gateway_connections.get(
self.resource_group,
self.resource_id).virtual_network_gateway_connection
except azure.common.AzureMissingResourceHttpError:
return None

def destroy_resource(self):
self.nrpc().virtual_network_gateway_connections.delete(self.resource_group,
self.resource_id)

defn_properties = [ 'location', 'tags', 'virtual_network_gateway1',
'virtual_network_gateway2', 'local_network_gateway2',
'connection_type', 'routing_weight', 'shared_key' ]

def get_resource_url(self):
return ("https://management.azure.com/subscriptions/{0}"
"/resourceGroups/{1}/providers/Microsoft.Network"
"/connections/{2}?api-version=2015-05-01-preview"
.format(quote(self.subscription_id),
quote(self.resource_group),
quote(self.connection_name)))

def mk_request(self, method):
http_request = Request()
http_request.url = self.get_resource_url()
http_request.method = method
http_request.headers['Content-Type'] = 'application/json'
return http_request

def _create_or_update(self, defn):
info = {
'location': defn.location,
'tags': defn.tags,
'properties': {
'connectionType': defn.connection_type,
'routingWeight': defn.routing_weight,
'sharedKey': defn.shared_key,
}
}

if defn.virtual_network_gateway1:
info['properties']['virtualNetworkGateway1'] = { 'id': defn.virtual_network_gateway1 }
if defn.virtual_network_gateway2:
info['properties']['virtualNetworkGateway2'] = { 'id': defn.virtual_network_gateway2 }
if defn.local_network_gateway2:
info['properties']['localNetworkGateway2'] = { 'id': defn.local_network_gateway2 }

http_request = self.mk_request('PUT')
http_request.data = json.dumps(info)
http_request.headers['Content-Length'] = len(http_request.data)
response = self.nrpc().send_request(http_request)

if response.status_code not in [200, 201]:
raise AzureHttpError(response.content, response.status_code)

self.state = self.UP
self.copy_properties(defn)
self.get_settled_resource()


def create(self, defn, check, allow_reboot, allow_recreate):
self.no_property_change(defn, 'location')
self.no_property_change(defn, 'resource_group')
self.no_property_change(defn, 'connection_type')
self.no_property_change(defn, 'virtual_network_gateway1')
self.no_property_change(defn, 'virtual_network_gateway2')
self.no_property_change(defn, 'local_network_gateway2')

self.copy_mgmt_credentials(defn)
self.connection_name = defn.connection_name
self.resource_group = defn.resource_group

if check:
connection = self.get_settled_resource()
if not connection:
self.warn_missing_resource()
elif self.state == self.UP:
self.handle_changed_property('location',
connection.location, can_fix = False)
self.handle_changed_property('tags', connection.tags)
self.handle_changed_property('connection_type',
connection.connection_type, can_fix = False)
self.handle_changed_property('routing_weight',
connection.routing_weight)
# check key only if the user wants to manage it
if defn.shared_key:
self.handle_changed_property('shared_key',
connection.shared_key)
self.handle_changed_property('virtual_network_gateway1',
connection.virtual_network_gateway1 and
connection.virtual_network_gateway1.id,
can_fix = False)
self.handle_changed_property('virtual_network_gateway2',
connection.virtual_network_gateway2 and
connection.virtual_network_gateway2.id,
can_fix = False)
self.handle_changed_property('local_network_gateway2',
connection.local_network_gateway2 and
connection.local_network_gateway2.id,
can_fix = False)
else:
self.warn_not_supposed_to_exist()
self.confirm_destroy()

if self.state != self.UP:
if self.get_settled_resource():
raise Exception("tried creating a virtual network gateway connection that already exists; "
"please run 'deploy --check' to fix this")

self.log("creating {0}...".format(self.full_name))
self._create_or_update(defn)

if self.properties_changed(defn):
self.log("updating properties of {0}...".format(self.full_name))
self.get_settled_resource_assert_exists()
self._create_or_update(defn)


def create_after(self, resources, defn):
from nixops.resources.azure_resource_group import AzureResourceGroupState
from nixops.resources.azure_local_network_gateway import AzureLocalNetworkGatewayState
from nixops.resources.azure_virtual_network_gateway import AzureVirtualNetworkGatewayState
return {r for r in resources
if isinstance(r, AzureResourceGroupState) or isinstance(r, AzureLocalNetworkGatewayState) or
isinstance(r, AzureVirtualNetworkGatewayState) }

0 comments on commit 087b821

Please sign in to comment.