Skip to content

Commit

Permalink
Merge pull request #22 from rundeck-plugins/resource-mode-accesskey
Browse files Browse the repository at this point in the history
adding option to set Azure key from the key storage
  • Loading branch information
ltamaster authored Aug 10, 2021
2 parents dbd2d49 + 2292272 commit 986b9f5
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 9 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ configurations {
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.3.11'
testCompile group: 'junit', name: 'junit', version: '4.12'
compile group: 'org.rundeck', name: 'rundeck-core', version: '2.10.0'
compile group: 'org.rundeck', name: 'rundeck-core', version: '3.3.+'
pluginLibs (group: 'com.microsoft.azure', name: 'azure', version: '1.3.0'){
exclude group: "com.fasterxml.jackson.core"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.rundeck.plugins.azure.plugin

import com.dtolabs.rundeck.core.execution.workflow.steps.FailureReason

enum AzureFailureReason implements FailureReason{

KeyStorage

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ import com.dtolabs.rundeck.core.common.NodeEntryImpl
import com.dtolabs.rundeck.core.common.NodeSetImpl
import com.dtolabs.rundeck.core.resources.ResourceModelSource
import com.dtolabs.rundeck.core.resources.ResourceModelSourceException
import com.dtolabs.rundeck.core.storage.keys.KeyStorageTree
import com.rundeck.plugins.azure.azure.AzureManager
import com.rundeck.plugins.azure.azure.AzureManagerBuilder
import com.rundeck.plugins.azure.azure.AzureNode
import com.rundeck.plugins.azure.azure.AzureNodeMapper
import com.rundeck.plugins.azure.util.AzurePluginUtil
import org.rundeck.app.spi.Services

/**
* Created by luistoledo on 11/6/17.
Expand All @@ -18,9 +21,12 @@ class AzureResourceModelSource implements ResourceModelSource {

private Properties configuration;
private AzureManager manager;
Services services

AzureResourceModelSource(Properties configuration) {

AzureResourceModelSource(Properties configuration, Services services) {
this.configuration = configuration
this.services = services
}

void setAzureManager(AzureManager manager){
Expand All @@ -42,6 +48,12 @@ class AzureResourceModelSource implements ResourceModelSource {
String tagValue=configuration.getProperty(AzureResourceModelSourceFactory.TAG_VALUE)
String extraMapping=configuration.getProperty(AzureResourceModelSourceFactory.EXTRA_MAPPING)
boolean useAzureTags=Boolean.parseBoolean(configuration.getProperty(AzureResourceModelSourceFactory.USE_AZURE_TAGS))
String keyStoragePath=configuration.getProperty(AzureResourceModelSourceFactory.KEY_STORAGE_PATH)

if(keyStoragePath){
KeyStorageTree keyStorage = services.getService(KeyStorageTree.class)
key = AzurePluginUtil.getPasswordFromKeyStorage(keyStoragePath, keyStorage)
}

boolean debug=Boolean.parseBoolean(configuration.getProperty(AzureResourceModelSourceFactory.DEBUG))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import com.dtolabs.rundeck.plugins.ServiceNameConstants
import com.dtolabs.rundeck.plugins.descriptions.PluginDescription
import com.dtolabs.rundeck.plugins.util.DescriptionBuilder
import com.rundeck.plugins.azure.util.AzurePluginUtil
import org.rundeck.app.spi.Services

/**
* Created by luistoledo on 11/3/17.
*/
Expand All @@ -31,6 +33,8 @@ class AzureResourceModelSourceFactory implements ResourceModelSourceFactory,Desc
public static final String TENANT = "tenant"
public static final String SUBSCRIPTION_ID = "subscriptionId"
public static final String KEY = "key"
public static final String KEY_STORAGE_PATH = "keyStoragePath"

public static final String PFX_CERTIFICATE_PATH = "pfxCertificatePath"
public static final String PFX_CERTIFICATE_PASSWORD = "pfxCertificatePassword"

Expand All @@ -49,6 +53,8 @@ class AzureResourceModelSourceFactory implements ResourceModelSourceFactory,Desc
final static Map<String, Object> renderingOptionsAuthentication = AzurePluginUtil.getRenderOpt("Credentials",false)
final static Map<String, Object> renderingOptionsAuthenticationPassword = AzurePluginUtil.getRenderOpt("Credentials",false, true)
final static Map<String, Object> renderingOptionsConfig = AzurePluginUtil.getRenderOpt("Configuration",false)
final static Map<String, Object> renderingOptionsAuthenticationStorage = AzurePluginUtil.getRenderOpt("Credentials",false, false, true)


AzureResourceModelSourceFactory(Framework framework) {
this.framework = framework
Expand All @@ -68,6 +74,8 @@ class AzureResourceModelSourceFactory implements ResourceModelSourceFactory,Desc
null,null,null, renderingOptionsAuthentication))
.property(PropertyUtil.string(KEY, "Key", "Azure Access Key.", false,
null,null,null, renderingOptionsAuthenticationPassword))
.property(PropertyUtil.string(KEY_STORAGE_PATH, "Key Storage Path", "Azure Access Key from Rundeck storage path.", false,
null,null,null, renderingOptionsAuthenticationStorage))
.property(PropertyUtil.string(PFX_CERTIFICATE_PATH, "Certificate Path", "Azure certificate file path.", false,
null,null,null, renderingOptionsAuthentication))
.property(PropertyUtil.string(PFX_CERTIFICATE_PASSWORD, "Certificate Password", "Azure certificate Password.", false,
Expand Down Expand Up @@ -100,7 +108,12 @@ class AzureResourceModelSourceFactory implements ResourceModelSourceFactory,Desc

@Override
ResourceModelSource createResourceModelSource(Properties configuration) throws ConfigurationException {
final AzureResourceModelSource resource = new AzureResourceModelSource(configuration)
return null
}

@Override
ResourceModelSource createResourceModelSource(Services services, Properties configuration) throws ConfigurationException {
final AzureResourceModelSource resource = new AzureResourceModelSource(configuration, services)

return resource
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package com.rundeck.plugins.azure.util

import com.dtolabs.rundeck.core.execution.workflow.steps.StepException
import com.dtolabs.rundeck.core.plugins.configuration.StringRenderingConstants
import com.dtolabs.rundeck.core.storage.ResourceMeta
import com.dtolabs.rundeck.core.storage.StorageTree
import com.dtolabs.rundeck.plugins.step.PluginStepContext
import com.microsoft.azure.management.compute.DataDisk
import com.microsoft.azure.management.compute.DiskInstanceView
import com.microsoft.azure.management.compute.InstanceViewStatus
import com.microsoft.azure.management.compute.VirtualMachine
import com.microsoft.azure.management.compute.VirtualMachineExtension
import com.rundeck.plugins.azure.plugin.AzureFailureReason
import groovy.transform.CompileStatic

/**
* Created by luistoledo on 11/6/17.
Expand Down Expand Up @@ -200,6 +202,20 @@ class AzurePluginUtil {

}

static String getPasswordFromKeyStorage(String path, StorageTree storage) {
try{
ResourceMeta contents = storage.getResource(path).getContents()
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()
contents.writeContent(byteArrayOutputStream)
String password = new String(byteArrayOutputStream.toByteArray())

return password
}catch(Exception e){
throw new StepException("error accessing ${path}: ${e.message}", AzureFailureReason.KeyStorage)
}

}

static void printMessage(String message, boolean debug, String level){


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@ import com.dtolabs.rundeck.core.common.INodeSet
import com.dtolabs.rundeck.core.resources.ResourceModelSourceException
import com.dtolabs.rundeck.core.resources.format.ResourceFormatParser
import com.dtolabs.rundeck.core.resources.format.ResourceFormatParserService
import com.dtolabs.rundeck.core.storage.ResourceMeta
import com.dtolabs.rundeck.core.storage.keys.KeyStorageTree
import com.microsoft.azure.management.Azure
import com.rundeck.plugins.azure.azure.AzureManager
import com.rundeck.plugins.azure.azure.AzureNode
import org.rundeck.app.spi.Services
import org.rundeck.storage.api.Resource
import spock.lang.Specification

/**
Expand All @@ -23,8 +27,9 @@ class AzureResourceModelSourceSpec extends Specification{
azureManager.setAzure(azure)

Properties configuration = [client:"client123",tenant:"tenant123",key:"key123",subscriptionId:"subscriptionId123"]
Services services = getServices()

def azureResource = new AzureResourceModelSource(configuration)
def azureResource = new AzureResourceModelSource(configuration, services)
azureResource.setAzureManager(azureManager)

AzureNode test = new AzureNode()
Expand All @@ -51,8 +56,9 @@ class AzureResourceModelSourceSpec extends Specification{
azureManager.setAzure(azure)

Properties configuration = [client:"1234"]
Services services = getServices()

def azureResource = new AzureResourceModelSource(configuration)
def azureResource = new AzureResourceModelSource(configuration, services)
azureResource.setAzureManager(azureManager)

AzureNode test = new AzureNode()
Expand All @@ -73,10 +79,11 @@ class AzureResourceModelSourceSpec extends Specification{
def azureManager = Mock(AzureManager)
def azure = GroovyMock(Azure)
azureManager.setAzure(azure)
Services services = getServices()

Properties configuration = [client:"client123",tenant:"tenant123",key:"key123",subscriptionId:"subscriptionId123"]

def azureResource = new AzureResourceModelSource(configuration)
def azureResource = new AzureResourceModelSource(configuration, services)

when:
azureResource.getNodes()
Expand All @@ -92,10 +99,11 @@ class AzureResourceModelSourceSpec extends Specification{
def azureManager = Mock(AzureManager)
def azure = GroovyMock(Azure)
azureManager.setAzure(azure)
Services services = getServices()

Properties configuration = [client:"client123",tenant:"tenant123",subscriptionId:"subscriptionId123"]

def azureResource = new AzureResourceModelSource(configuration)
def azureResource = new AzureResourceModelSource(configuration, services)
azureResource.setAzureManager(azureManager)

when:
Expand All @@ -106,6 +114,54 @@ class AzureResourceModelSourceSpec extends Specification{

}

def "retrieve resource success using key storage"(){
given:

def azureManager = Mock(AzureManager)
def azure = GroovyMock(Azure)
azureManager.setAzure(azure)

Services services = getServices()

Properties configuration = [client:"client123",tenant:"tenant123",keyStoragePath:"keys/azure.key",subscriptionId:"subscriptionId123"]

def azureResource = new AzureResourceModelSource(configuration, services)
azureResource.setAzureManager(azureManager)

AzureNode test = new AzureNode()
test.name="test"

AzureNode test2 = new AzureNode()
test2.name="test2"
def vmList = [test,test2]

when:
def result = azureResource.getNodes()

then:
1 * azureManager.listVms() >> vmList
result.size()==vmList.size()

}


Services getServices(){
def storageTree = Mock(KeyStorageTree)
storageTree.getResource(_) >> Mock(Resource) {
getContents() >> Mock(ResourceMeta) {
writeContent(_) >> { args ->
args[0].write('password'.bytes)
return 6L
}
}
}

Services services = Mock(Services){
getService(KeyStorageTree.class) >> storageTree
}
return services
}



}

0 comments on commit 986b9f5

Please sign in to comment.