Skip to content

Commit 0ae7115

Browse files
authored
Merge pull request #32 from rundeck-plugins/rse-109-enh-azure-node-source-filter-many-resource-groups
RSE-109: Enh: Allow Azure resource model to filter by many resourceGroups
2 parents ed9a90f + 02a09b9 commit 0ae7115

File tree

7 files changed

+48
-22
lines changed

7 files changed

+48
-22
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Settings related to the Azure connection
2626
Mapping and filter settings
2727

2828
* **Mapping Params**: Custom mapping settings. Property mapping definitions. Specify multiple mappings in the form "attributeName.selector=selector" or "attributeName.default=value", separated by ";"
29-
* **Resource Group**: Filter using resource group
29+
* **Resource Groups**: Filter using a list of allowed resource groups separated by semicolons (`;`). Eg: `RG1; RG2; RG3`
3030
* **Only Running Instances**: Filter for the "Running" instances. If false, all instances will be returned.
3131

3232
### Mapping

src/main/groovy/com/rundeck/plugins/azure/azure/AzureManager.groovy

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package com.rundeck.plugins.azure.azure
22

3+
import com.dtolabs.rundeck.core.resources.ResourceModelSourceException
34
import com.microsoft.azure.AzureEnvironment
5+
import com.microsoft.azure.CloudException
46
import com.microsoft.azure.credentials.ApplicationTokenCredentials
57
import com.microsoft.azure.management.Azure
8+
import com.microsoft.azure.management.compute.VirtualMachine
69
import com.microsoft.azure.management.compute.VirtualMachineSize
710
import com.microsoft.azure.management.resources.fluentcore.arm.Region
811
import com.microsoft.azure.management.resources.fluentcore.utils.SdkContext
@@ -19,7 +22,7 @@ class AzureManager {
1922
String pfxCertificatePath
2023
String pfxCertificatePassword
2124

22-
String resourceGroup
25+
List<String> resourceGroups
2326
String tagName
2427
String tagValue
2528
Region region
@@ -58,12 +61,23 @@ class AzureManager {
5861
this.connect()
5962

6063
def vms = azure.virtualMachines()
61-
def list
64+
List<VirtualMachine> list = new LinkedList<>()
6265

63-
if(resourceGroup!=null){
64-
list = vms.listByResourceGroup(resourceGroup)
65-
}else{
66+
if(resourceGroups.isEmpty()){
6667
list = vms.list()
68+
}else{
69+
StringBuilder errorMsgs = new StringBuilder()
70+
for(String rg : resourceGroups)
71+
try{
72+
list.addAll(vms.listByResourceGroup(rg))
73+
}catch(CloudException requestError){
74+
errorMsgs.append("\n" + requestError.getLocalizedMessage())
75+
if(debug){
76+
println("Couldn't load machines for resource group '${rg}': " + requestError.getLocalizedMessage())
77+
}
78+
}
79+
if (list.size() < 1 && errorMsgs.length() > 0)
80+
throw new ResourceModelSourceException("COULDN'T LOAD ANY VIRTUAL MACHINES. LISTING ERRORS: " + errorMsgs)
6781
}
6882

6983
if(onlyRunningInstances){
@@ -111,9 +125,9 @@ class AzureManager {
111125
def vms = azure.virtualMachines()
112126

113127
if(async){
114-
vms.startAsync(resourceGroup,name).await()
128+
vms.startAsync(resourceGroups[0],name).await()
115129
}else{
116-
vms.start(resourceGroup,name)
130+
vms.start(resourceGroups[0],name)
117131
}
118132

119133
}
@@ -124,10 +138,10 @@ class AzureManager {
124138
def vms = azure.virtualMachines()
125139

126140
if(async) {
127-
vms.powerOffAsync(resourceGroup, name).await()
141+
vms.powerOffAsync(resourceGroups[0], name).await()
128142

129143
}else{
130-
vms.powerOff(resourceGroup, name)
144+
vms.powerOff(resourceGroups[0], name)
131145
}
132146
}
133147

src/main/groovy/com/rundeck/plugins/azure/azure/AzureManagerBuilder.groovy

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class AzureManagerBuilder {
1414
String pfxCertificatePath
1515
String pfxCertificatePassword
1616

17-
String resourceGroup
17+
List<String> resourceGroups
1818
String tagName
1919
String tagValue
2020
boolean onlyRunningInstances
@@ -86,8 +86,8 @@ class AzureManagerBuilder {
8686
* @param resourceGroup Azure Resource Group
8787
* @return this builder
8888
*/
89-
AzureManagerBuilder resourceGroup(String resourceGroup){
90-
this.resourceGroup = resourceGroup
89+
AzureManagerBuilder resourceGroups(List resourceGroups){
90+
this.resourceGroups = resourceGroups
9191
return this
9292
}
9393

@@ -155,7 +155,7 @@ class AzureManagerBuilder {
155155
azure.setKey(this.key)
156156
azure.setPfxCertificatePath(this.pfxCertificatePath)
157157
azure.setPfxCertificatePassword(this.pfxCertificatePassword)
158-
azure.setResourceGroup(this.resourceGroup)
158+
azure.setResourceGroups(this.resourceGroups)
159159
azure.setOnlyRunningInstances(this.onlyRunningInstances)
160160
azure.setDebug(debug)
161161
azure.setTagName(this.tagName)

src/main/groovy/com/rundeck/plugins/azure/plugin/AzureResourceModelSource.groovy

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,20 @@ class AzureResourceModelSource implements ResourceModelSource {
4242
String key=configuration.getProperty(AzureResourceModelSourceFactory.KEY)
4343
String pfxCertificatePath=configuration.getProperty(AzureResourceModelSourceFactory.PFX_CERTIFICATE_PATH)
4444
String pfxCertificatePassword=configuration.getProperty(AzureResourceModelSourceFactory.PFX_CERTIFICATE_PASSWORD)
45-
String resourceGroup=configuration.getProperty(AzureResourceModelSourceFactory.RESOURCE_GROUP)
4645
boolean onlyRunningInstances=Boolean.parseBoolean(configuration.getProperty(AzureResourceModelSourceFactory.RUNNING_ONLY))
4746
String tagName=configuration.getProperty(AzureResourceModelSourceFactory.TAG_NAME)
4847
String tagValue=configuration.getProperty(AzureResourceModelSourceFactory.TAG_VALUE)
4948
String extraMapping=configuration.getProperty(AzureResourceModelSourceFactory.EXTRA_MAPPING)
5049
boolean useAzureTags=Boolean.parseBoolean(configuration.getProperty(AzureResourceModelSourceFactory.USE_AZURE_TAGS))
5150
String keyStoragePath=configuration.getProperty(AzureResourceModelSourceFactory.KEY_STORAGE_PATH)
5251

52+
List<String> resourceGroups = []
53+
String [] rawResourceGroupStrs = configuration.getProperty(AzureResourceModelSourceFactory.RESOURCE_GROUPS)?.split(AzureResourceModelSourceFactory.RESOURCE_GROUP_SEPARATOR)
54+
if(rawResourceGroupStrs)
55+
for( int i = 0 ; i < rawResourceGroupStrs.size() ; i++)
56+
resourceGroups << rawResourceGroupStrs[i].trim()
57+
58+
5359
if(keyStoragePath){
5460
KeyStorageTree keyStorage = services.getService(KeyStorageTree.class)
5561
key = AzurePluginUtil.getPasswordFromKeyStorage(keyStoragePath, keyStorage)
@@ -69,7 +75,7 @@ class AzureResourceModelSource implements ResourceModelSource {
6975
.key(key)
7076
.pfxCertificatePath(pfxCertificatePath)
7177
.pfxCertificatePassword(pfxCertificatePassword)
72-
.resourceGroup(resourceGroup)
78+
.resourceGroups(resourceGroups)
7379
.onlyRunningInstances(onlyRunningInstances)
7480
.tagName(tagName)
7581
.tagValue(tagValue)

src/main/groovy/com/rundeck/plugins/azure/plugin/AzureResourceModelSourceFactory.groovy

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ import com.dtolabs.rundeck.core.plugins.configuration.ConfigurationException
66
import com.dtolabs.rundeck.core.plugins.configuration.Describable
77
import com.dtolabs.rundeck.core.plugins.configuration.Description
88
import com.dtolabs.rundeck.core.plugins.configuration.PropertyUtil
9+
import com.dtolabs.rundeck.core.plugins.configuration.ValidationException
910
import com.dtolabs.rundeck.core.resources.ResourceModelSource
1011
import com.dtolabs.rundeck.core.resources.ResourceModelSourceFactory
1112
import com.dtolabs.rundeck.plugins.ServiceNameConstants
1213
import com.dtolabs.rundeck.plugins.descriptions.PluginDescription
1314
import com.dtolabs.rundeck.plugins.util.DescriptionBuilder
1415
import com.rundeck.plugins.azure.util.AzurePluginUtil
1516
import org.rundeck.app.spi.Services
17+
import java.util.regex.Pattern
1618

1719
/**
1820
* Created by luistoledo on 11/3/17.
@@ -37,12 +39,13 @@ class AzureResourceModelSourceFactory implements ResourceModelSourceFactory,Desc
3739

3840
public static final String PFX_CERTIFICATE_PATH = "pfxCertificatePath"
3941
public static final String PFX_CERTIFICATE_PASSWORD = "pfxCertificatePassword"
42+
public static final String RESOURCE_GROUP_SEPARATOR = ";"
4043

4144
//mapping
4245
public static final String EXTRA_MAPPING = "extraMapping"
4346

4447
//filters
45-
public static final String RESOURCE_GROUP = "resourceGroup"
48+
public static final String RESOURCE_GROUPS = "resourceGroup"
4649
public static final String TAG_NAME = "tagName"
4750
public static final String TAG_VALUE = "tagValue"
4851
public static final String RUNNING_ONLY = "onlyRunningInstances"
@@ -82,8 +85,12 @@ class AzureResourceModelSourceFactory implements ResourceModelSourceFactory,Desc
8285
null,null,null, renderingOptionsAuthentication))
8386
.property(PropertyUtil.string(EXTRA_MAPPING, "Mapping Params", "Property mapping definitions. Specify multiple mappings in the form \"attributeName.selector=selector\" or \"attributeName.default=value\", separated by \";\"", false,
8487
"tags.selector=azure_status",null,null, renderingOptionsConfig))
85-
.property(PropertyUtil.string(RESOURCE_GROUP, "Resource Group", "Filter using resource group", false,
86-
null,null,null, renderingOptionsConfig))
88+
.property(PropertyUtil.string(RESOURCE_GROUPS, "Resource Groups", "Filter using one or more resource group separated by '" + RESOURCE_GROUP_SEPARATOR + "' (empty for all resource groups).", false,
89+
null, { String rgStr ->
90+
if(Pattern.compile("^[a-zA-Z0-9_-]*(\\s?;\\s?[a-zA-Z0-9_-]+)*\$").matcher(rgStr).matches())
91+
return true
92+
throw new ValidationException( rgStr + "Expected: rg1;rg2;...;rgN OR adding one space on each side of the ';'");
93+
},null, renderingOptionsConfig))
8794
.property(PropertyUtil.string(TAG_NAME, "Tag Name", "Filter using tag name (this value will be ignored if either Tag Name or Tag Value is empty)", false,
8895
null,null,null, renderingOptionsConfig))
8996
.property(PropertyUtil.string(TAG_VALUE, "Tag Value", "Filter using tag value (this value will be ignored if either Tag Name or Tag Value is empty)", false,
@@ -114,7 +121,6 @@ class AzureResourceModelSourceFactory implements ResourceModelSourceFactory,Desc
114121
@Override
115122
ResourceModelSource createResourceModelSource(Services services, Properties configuration) throws ConfigurationException {
116123
final AzureResourceModelSource resource = new AzureResourceModelSource(configuration, services)
117-
118124
return resource
119125
}
120126
}

src/main/groovy/com/rundeck/plugins/azure/plugin/AzureVmStartPlugin.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ class AzureVmStartPlugin implements StepPlugin, Describable {
9696
.key(key)
9797
.pfxCertificatePath(pfxCertificatePath)
9898
.pfxCertificatePassword(pfxCertificatePassword)
99-
.resourceGroup(resourceGroup)
99+
.resourceGroups([resourceGroup])
100100
.build()
101101

102102
Map<String, String> meta = new HashMap<>();

src/main/groovy/com/rundeck/plugins/azure/plugin/AzureVmStopPlugin.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ class AzureVmStopPlugin implements StepPlugin, Describable {
100100
.key(key)
101101
.pfxCertificatePath(pfxCertificatePath)
102102
.pfxCertificatePassword(pfxCertificatePassword)
103-
.resourceGroup(resourceGroup)
103+
.resourceGroups([resourceGroup])
104104
.build()
105105

106106
Map<String, String> meta = new HashMap<>();

0 commit comments

Comments
 (0)