Repository: brooklyn-server
Updated Branches:
  refs/heads/master 9ebc32c10 -> b1fc16d02


A default network is now created when deploying to Azure ARM


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/44470854
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/44470854
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/44470854

Branch: refs/heads/master
Commit: 44470854f19224fd3c62fb912db7951af0b38c3f
Parents: 0b9717a
Author: graeme.miller <[email protected]>
Authored: Tue Jun 20 15:59:04 2017 +0100
Committer: graeme.miller <[email protected]>
Committed: Wed Jun 21 11:44:04 2017 +0100

----------------------------------------------------------------------
 .../location/jclouds/JcloudsLocation.java       |   6 +
 .../creator/DefaultAzureArmNetworkCreator.java  | 129 +++++++++++++
 .../DefaultAzureArmNetworkCreatorTest.java      | 181 +++++++++++++++++++
 3 files changed, 316 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/44470854/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
----------------------------------------------------------------------
diff --git 
a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
 
b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
index a701083..2409727 100644
--- 
a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
+++ 
b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
@@ -80,6 +80,7 @@ import 
org.apache.brooklyn.core.mgmt.persist.PersistenceObjectStore;
 import 
org.apache.brooklyn.core.mgmt.persist.jclouds.JcloudsBlobStoreBasedObjectStore;
 import org.apache.brooklyn.location.jclouds.api.JcloudsLocationPublic;
 import 
org.apache.brooklyn.location.jclouds.networking.JcloudsPortForwarderExtension;
+import 
org.apache.brooklyn.location.jclouds.networking.creator.DefaultAzureArmNetworkCreator;
 import org.apache.brooklyn.location.jclouds.templates.PortableTemplateBuilder;
 import 
org.apache.brooklyn.location.jclouds.templates.customize.TemplateBuilderCustomizer;
 import 
org.apache.brooklyn.location.jclouds.templates.customize.TemplateBuilderCustomizers;
@@ -667,6 +668,11 @@ public class JcloudsLocation extends 
AbstractCloudMachineProvisioningLocation im
             Template template;
 
             try {
+                // Create default network for Azure ARM if necessary
+                if ("azurecompute-arm".equals(this.getProvider())) {
+                    
DefaultAzureArmNetworkCreator.createDefaultNetworkAndAddToTemplateOptions(computeService,
 setup);
+                }
+
                 // Setup the template
                 template = buildTemplate(computeService, setup, 
ImmutableList.of(customizersDelegate));
                 boolean expectWindows = isWindows(template, setup);

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/44470854/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/networking/creator/DefaultAzureArmNetworkCreator.java
----------------------------------------------------------------------
diff --git 
a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/networking/creator/DefaultAzureArmNetworkCreator.java
 
b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/networking/creator/DefaultAzureArmNetworkCreator.java
new file mode 100644
index 0000000..f12d929
--- /dev/null
+++ 
b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/networking/creator/DefaultAzureArmNetworkCreator.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+package org.apache.brooklyn.location.jclouds.networking.creator;
+
+import static 
org.apache.brooklyn.core.location.cloud.CloudLocationConfig.CLOUD_REGION_ID;
+import static 
org.apache.brooklyn.location.jclouds.api.JcloudsLocationConfigPublic.NETWORK_NAME;
+import static 
org.apache.brooklyn.location.jclouds.api.JcloudsLocationConfigPublic.TEMPLATE_OPTIONS;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableMap;
+
+import org.jclouds.azurecompute.arm.AzureComputeApi;
+import org.jclouds.azurecompute.arm.domain.ResourceGroup;
+import org.jclouds.azurecompute.arm.domain.Subnet;
+import org.jclouds.azurecompute.arm.domain.VirtualNetwork;
+import org.jclouds.compute.ComputeService;
+
+import org.apache.brooklyn.util.core.config.ConfigBag;
+
+public class DefaultAzureArmNetworkCreator {
+
+    public static final Logger LOG = 
LoggerFactory.getLogger(DefaultAzureArmNetworkCreator.class);
+
+    private static final String DEFAULT_RESOURCE_GROUP = 
"brooklyn-default-resource-group";
+    private static final String DEFAULT_NETWORK_NAME = 
"brooklyn-default-network";
+    private static final String DEFAULT_SUBNET_NAME = 
"brooklyn-default-subnet";
+
+    private static final String defaultVnetAddressPrefix = "10.1.0.0/16";
+    private static final String defaultSubnetAddressPrefix = "10.1.0.0/24";
+
+    public static void 
createDefaultNetworkAndAddToTemplateOptions(ComputeService computeService, 
ConfigBag config) {
+        Map<String, Object> templateOptions = config.get(TEMPLATE_OPTIONS);
+
+        //Only create a default network if we haven't specified a network name 
(in template options or config) or ip options
+        if (config.containsKey(NETWORK_NAME)) {
+            LOG.info("Network config specified when creating Azure location. 
Not creating default network");
+            return;
+        }
+        if (templateOptions != null && 
(templateOptions.containsKey(NETWORK_NAME.getName()) || 
templateOptions.containsKey("ipOptions"))) {
+            LOG.info("Network config specified when creating Azure location. 
Not creating default network");
+            return;
+        }
+
+        LOG.info("Network config not specified when creating Azure location. 
Creating default network if doesn't exist");
+
+        AzureComputeApi api = 
computeService.getContext().unwrapApi(AzureComputeApi.class);
+        String location = config.get(CLOUD_REGION_ID);
+
+        String resourceGroupName = DEFAULT_RESOURCE_GROUP  + "-" + location;
+        String vnetName = DEFAULT_NETWORK_NAME + "-" + location;
+        String subnetName = DEFAULT_SUBNET_NAME + "-" + location;
+
+        //Check if default already exists
+        Subnet preexistingSubnet = api.getSubnetApi(resourceGroupName, 
vnetName).get(subnetName);
+        if(preexistingSubnet != null){
+            LOG.info("Default Azure network and subnet already created, 
"+vnetName);
+            updateTemplateOptions(config, preexistingSubnet);
+            return;
+        }
+
+
+        LOG.info("Network config not specified when creating Azure location 
and default network/subnet does not exists. Creating");
+
+        createResourceGroupIfNeeded(api, resourceGroupName, location);
+
+        //Setup properties for creating subnet/network
+        Subnet subnet = Subnet.create(subnetName, null, null,
+                
Subnet.SubnetProperties.builder().addressPrefix(defaultSubnetAddressPrefix).build());
+
+        VirtualNetwork.VirtualNetworkProperties virtualNetworkProperties = 
VirtualNetwork.VirtualNetworkProperties
+                
.builder().addressSpace(VirtualNetwork.AddressSpace.create(Arrays.asList(defaultVnetAddressPrefix)))
+                .subnets(Arrays.asList(subnet)).build();
+
+        //Create network
+        api.getVirtualNetworkApi(resourceGroupName).createOrUpdate(vnetName, 
location, virtualNetworkProperties);
+        Subnet createdSubnet = api.getSubnetApi(resourceGroupName, 
vnetName).get(subnetName);
+
+        //Add config
+        updateTemplateOptions(config, createdSubnet);
+
+    }
+
+    private static void updateTemplateOptions(ConfigBag config, Subnet 
createdSubnet){
+        Map<String, Object> templateOptions = config.get(TEMPLATE_OPTIONS);
+
+        if(templateOptions == null) {
+            templateOptions = new HashMap<>();
+            config.put(TEMPLATE_OPTIONS, templateOptions);
+        }
+
+        Map<String, Object> ipOptions = new HashMap<>();
+        ipOptions.put("allocateNewPublicIp", true); //JClouds will not provide 
a public IP unless we set this
+        ipOptions.put("subnet", createdSubnet.id());
+        templateOptions.put("ipOptions", ipOptions);
+    }
+
+
+    private static void createResourceGroupIfNeeded(AzureComputeApi api, 
String resourceGroup, String location) {
+        LOG.debug("using resource group [%s]", resourceGroup);
+        ResourceGroup rg = api.getResourceGroupApi().get(resourceGroup);
+        if (rg == null) {
+            LOG.debug("resource group [%s] does not exist. Creating!", 
resourceGroup);
+            api.getResourceGroupApi().create(resourceGroup, location,
+                    ImmutableMap.of("description", "brooklyn default resource 
group"));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/44470854/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/networking/creator/DefaultAzureArmNetworkCreatorTest.java
----------------------------------------------------------------------
diff --git 
a/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/networking/creator/DefaultAzureArmNetworkCreatorTest.java
 
b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/networking/creator/DefaultAzureArmNetworkCreatorTest.java
new file mode 100644
index 0000000..2dd6a5d
--- /dev/null
+++ 
b/locations/jclouds/src/test/java/org/apache/brooklyn/location/jclouds/networking/creator/DefaultAzureArmNetworkCreatorTest.java
@@ -0,0 +1,181 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+package org.apache.brooklyn.location.jclouds.networking.creator;
+
+import static 
org.apache.brooklyn.core.location.cloud.CloudLocationConfig.CLOUD_REGION_ID;
+import static 
org.apache.brooklyn.location.jclouds.api.JcloudsLocationConfigPublic.NETWORK_NAME;
+import static 
org.apache.brooklyn.location.jclouds.api.JcloudsLocationConfigPublic.TEMPLATE_OPTIONS;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.testng.Assert.assertEquals;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import org.jclouds.azurecompute.arm.AzureComputeApi;
+import org.jclouds.azurecompute.arm.domain.Subnet;
+import org.jclouds.azurecompute.arm.features.ResourceGroupApi;
+import org.jclouds.azurecompute.arm.features.SubnetApi;
+import org.jclouds.azurecompute.arm.features.VirtualNetworkApi;
+import org.jclouds.compute.ComputeService;
+
+import org.apache.brooklyn.util.core.config.ConfigBag;
+
+public class DefaultAzureArmNetworkCreatorTest {
+
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS) ComputeService computeService;
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS) AzureComputeApi azureComputeApi;
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS) ResourceGroupApi 
resourceGroupApi;
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS) VirtualNetworkApi 
virtualNetworkApi;
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS) SubnetApi subnetApi;
+
+    @Mock Subnet subnet;
+
+    final String TEST_RESOURCE_GROUP = 
"brooklyn-default-resource-group-test-loc";
+    final String TEST_NETWORK_NAME = "brooklyn-default-network-test-loc";
+    final String TEST_SUBNET_NAME = "brooklyn-default-subnet-test-loc";
+    final String TEST_SUBNET_ID = "/test/resource/id";
+    final String TEST_LOCATION = "test-loc";
+
+    @BeforeMethod
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void testPreExisting() {
+        //Setup config bag
+        ConfigBag configBag = ConfigBag.newInstance();
+        configBag.put(CLOUD_REGION_ID, TEST_LOCATION);
+
+        //Setup mocks
+        
when(computeService.getContext().unwrapApi(AzureComputeApi.class)).thenReturn(azureComputeApi);
+        when(azureComputeApi.getSubnetApi(TEST_RESOURCE_GROUP, 
TEST_NETWORK_NAME)).thenReturn(subnetApi);
+        when(subnetApi.get(TEST_SUBNET_NAME)).thenReturn(subnet);
+        when(subnet.id()).thenReturn(TEST_SUBNET_ID);
+
+        //Test
+        
DefaultAzureArmNetworkCreator.createDefaultNetworkAndAddToTemplateOptions(computeService,
 configBag);
+
+        //verify
+        verify(subnetApi).get(TEST_SUBNET_NAME);
+        verify(subnet).id();
+        verify(azureComputeApi).getSubnetApi(TEST_RESOURCE_GROUP, 
TEST_NETWORK_NAME);
+
+        Map<String, Object> templateOptions = configBag.get(TEMPLATE_OPTIONS);
+        Map<String, Object> ipOptions = (Map<String, 
Object>)templateOptions.get("ipOptions");
+        assertEquals(ipOptions.get("subnet"), TEST_SUBNET_ID);
+        assertEquals(ipOptions.get("allocateNewPublicIp"), true);
+    }
+
+    @Test
+    public void testVanilla() {
+        //Setup config bag
+        ConfigBag configBag = ConfigBag.newInstance();
+        configBag.put(CLOUD_REGION_ID, TEST_LOCATION);
+
+        //Setup mocks
+        
when(computeService.getContext().unwrapApi(AzureComputeApi.class)).thenReturn(azureComputeApi);
+        when(azureComputeApi.getSubnetApi(TEST_RESOURCE_GROUP, 
TEST_NETWORK_NAME)).thenReturn(subnetApi);
+        
when(subnetApi.get(TEST_SUBNET_NAME)).thenReturn(null).thenReturn(subnet); 
//null first time, subnet next
+        when(subnet.id()).thenReturn(TEST_SUBNET_ID);
+
+        
when(azureComputeApi.getResourceGroupApi()).thenReturn(resourceGroupApi);
+        when(resourceGroupApi.get(TEST_RESOURCE_GROUP)).thenReturn(null);
+
+        
when(azureComputeApi.getVirtualNetworkApi(TEST_RESOURCE_GROUP)).thenReturn(virtualNetworkApi);
+
+
+        //Test
+        
DefaultAzureArmNetworkCreator.createDefaultNetworkAndAddToTemplateOptions(computeService,
 configBag);
+
+        //verify
+        verify(subnetApi, times(2)).get(TEST_SUBNET_NAME);
+        verify(subnet).id();
+        verify(azureComputeApi, times(2)).getSubnetApi(TEST_RESOURCE_GROUP, 
TEST_NETWORK_NAME);
+
+        verify(azureComputeApi, times(2)).getResourceGroupApi();
+        verify(resourceGroupApi).get(TEST_RESOURCE_GROUP);
+        verify(azureComputeApi).getVirtualNetworkApi(TEST_RESOURCE_GROUP);
+
+        Map<String, Object> templateOptions = configBag.get(TEMPLATE_OPTIONS);
+        Map<String, Object> ipOptions = (Map<String, 
Object>)templateOptions.get("ipOptions");
+        assertEquals(ipOptions.get("subnet"), TEST_SUBNET_ID);
+        assertEquals(ipOptions.get("allocateNewPublicIp"), true);
+    }
+
+    @Test
+    public void testNetworkInConfig() {
+        ConfigBag configBag = ConfigBag.newInstance();
+        configBag.put(CLOUD_REGION_ID, TEST_LOCATION);
+        configBag.put(NETWORK_NAME, TEST_NETWORK_NAME);
+
+        Map<String, Object> configCopy = configBag.getAllConfig();
+
+        
DefaultAzureArmNetworkCreator.createDefaultNetworkAndAddToTemplateOptions(computeService,
 configBag);
+
+        //Ensure nothing changed, and no calls were made to the compute service
+        assertEquals(configCopy, configBag.getAllConfig());
+        Mockito.verifyZeroInteractions(computeService);
+    }
+
+    @Test
+    public void testNetworkInTemplate() {
+        HashMap<String, Object> templateOptions = new HashMap<>();
+        templateOptions.put(NETWORK_NAME.getName(), TEST_NETWORK_NAME);
+
+        ConfigBag configBag = ConfigBag.newInstance();
+        configBag.put(CLOUD_REGION_ID, TEST_LOCATION);
+        configBag.put(TEMPLATE_OPTIONS, templateOptions);
+
+        Map<String, Object> configCopy = configBag.getAllConfig();
+
+        
DefaultAzureArmNetworkCreator.createDefaultNetworkAndAddToTemplateOptions(computeService,
 configBag);
+
+        //Ensure nothing changed, and no calls were made to the compute service
+        assertEquals(configCopy, configBag.getAllConfig());
+        Mockito.verifyZeroInteractions(computeService);
+    }
+
+    @Test
+    public void testIpOptionsInTemplate() {
+        HashMap<String, Object> templateOptions = new HashMap<>();
+        templateOptions.put("ipOptions", TEST_NETWORK_NAME);
+
+        ConfigBag configBag = ConfigBag.newInstance();
+        configBag.put(CLOUD_REGION_ID, TEST_LOCATION);
+        configBag.put(TEMPLATE_OPTIONS, templateOptions);
+
+        Map<String, Object> configCopy = configBag.getAllConfig();
+
+        
DefaultAzureArmNetworkCreator.createDefaultNetworkAndAddToTemplateOptions(computeService,
 configBag);
+
+        //Ensure nothing changed, and no calls were made to the compute service
+        assertEquals(configCopy, configBag.getAllConfig());
+        Mockito.verifyZeroInteractions(computeService);
+    }
+}

Reply via email to