diff --git a/functional-test/src/test/groovy/functional/EncryptedInventorySpec.groovy b/functional-test/src/test/groovy/functional/EncryptedInventorySpec.groovy new file mode 100644 index 00000000..e7cad1e5 --- /dev/null +++ b/functional-test/src/test/groovy/functional/EncryptedInventorySpec.groovy @@ -0,0 +1,31 @@ +package functional + +import functional.base.BaseTestConfiguration +import org.testcontainers.spock.Testcontainers + +@Testcontainers +class EncryptedInventorySpec extends BaseTestConfiguration { + + static String PROJ_NAME = 'ansible-encrypted-inventory' + + def setupSpec() { + startCompose() + configureRundeck(PROJ_NAME) + } + + def "test encrypted inventory"(){ + when: + + //wait for node to be available + def result = client.apiCall {api-> api.listNodes(PROJ_NAME,".*")} + + then: + result!=null + result.size()==4 + result.get("ssh-node")!=null + result.get("ssh-node-1")!=null + result.get("ssh-node-2")!=null + } + + +} diff --git a/functional-test/src/test/groovy/functional/base/BaseTestConfiguration.groovy b/functional-test/src/test/groovy/functional/base/BaseTestConfiguration.groovy index fd0e2243..47fd531f 100644 --- a/functional-test/src/test/groovy/functional/base/BaseTestConfiguration.groovy +++ b/functional-test/src/test/groovy/functional/base/BaseTestConfiguration.groovy @@ -22,6 +22,7 @@ class BaseTestConfiguration extends Specification{ public static final String NODE_USER_PASSWORD = "testpassword123" public static final String NODE_KEY_PASSPHRASE = "testpassphrase123" public static final String USER_VAULT_PASSWORD = "vault123" + public static final String ENCRYPTED_INVENTORY_VAULT_PASSWORD = "123456" def startCompose() { if(rundeckEnvironment==null){ @@ -106,6 +107,10 @@ class BaseTestConfiguration extends Specification{ requestBody = RequestBody.create(USER_VAULT_PASSWORD.getBytes(), Client.MEDIA_TYPE_X_RUNDECK_PASSWORD) keyResult = client.apiCall {api-> api.createKeyStorage("project/$projectName/vault-user.pass", requestBody)} + //add encrypted inventory password + requestBody = RequestBody.create(ENCRYPTED_INVENTORY_VAULT_PASSWORD.getBytes(), Client.MEDIA_TYPE_X_RUNDECK_PASSWORD) + keyResult = client.apiCall {api-> api.createKeyStorage("project/$projectName/vault-inventory.password", requestBody)} + //create project def projList = client.apiCall(api -> api.listProjects()) diff --git a/functional-test/src/test/groovy/functional/base/RundeckCompose.groovy b/functional-test/src/test/groovy/functional/base/RundeckCompose.groovy index 3f843b3a..f56fb10c 100644 --- a/functional-test/src/test/groovy/functional/base/RundeckCompose.groovy +++ b/functional-test/src/test/groovy/functional/base/RundeckCompose.groovy @@ -32,6 +32,9 @@ class RundeckCompose extends DockerComposeContainer { baseUrl rdUrl passwordAuth('admin', 'admin') logger(new TestLogger()) + timeout(300) + readTimeout(300) + connectTimeout(300) build() } return client diff --git a/functional-test/src/test/resources/docker/ansible/inventory-encrypted.ini b/functional-test/src/test/resources/docker/ansible/inventory-encrypted.ini new file mode 100644 index 00000000..c62c9413 --- /dev/null +++ b/functional-test/src/test/resources/docker/ansible/inventory-encrypted.ini @@ -0,0 +1,21 @@ +$ANSIBLE_VAULT;1.1;AES256 +65366137663536643763393536326631663039653039323434663839323138653866376465653038 +3838363031653534376431396630623437383831636361380a326264346664613237383139343564 +61366565396261306238666230383366653438313234666363303165613235336637626532396431 +3465656235656238650a333137363333636435303934336434656630376637373763383830343566 +31333135653264643163653335643536616632303762396534663033373331613137663363336638 +30613632373765626662616437663162646265326133343865633430633735616663363638383263 +37333562663932386336316135356432346530666537373465653362623961643832353537336664 +39333331613431613735343066336334373964356131613163363630653338643061373961656563 +36343036623231646366313639383237303433376531306131656533633761613231336136643562 +62353330326165386433303064393435316363316236646437643431386436323530653366663238 +33343665313030623165633432393034393664376631393834666638316237633538626637633330 +37663761633234316330333232373365396235623361363262346634643764373834356434666236 +39393131666239346462613337663537643963343764396163353861663966653430323263366631 +64653436366564373130643963353864333763343330663039363465396231303461303937636161 +62613234383437353736343561363839376564326565626431363866653936653962623337363137 +64663738316637313133313463373261353038616461343236393537346235633336373766363563 +37613865303065653963376337643366313966386531616332363038613937653430303133323765 +33336363646332303432343362333638393134626138616664393363326161393639663438313031 +37643334336262396237376230313634383933643832333038373964373465306261323331343537 +37333530313466393933 \ No newline at end of file diff --git a/functional-test/src/test/resources/project-import/ansible-encrypted-inventory/rundeck-ansible-encrypted-inventory/files/acls/node-acl.aclpolicy b/functional-test/src/test/resources/project-import/ansible-encrypted-inventory/rundeck-ansible-encrypted-inventory/files/acls/node-acl.aclpolicy new file mode 100644 index 00000000..d50b4880 --- /dev/null +++ b/functional-test/src/test/resources/project-import/ansible-encrypted-inventory/rundeck-ansible-encrypted-inventory/files/acls/node-acl.aclpolicy @@ -0,0 +1,8 @@ +by: + urn: project:ansible-encrypted-inventory +for: + storage: + - match: + path: 'keys/.*' + allow: [read] +description: Allow access to key storage \ No newline at end of file diff --git a/functional-test/src/test/resources/project-import/ansible-encrypted-inventory/rundeck-ansible-encrypted-inventory/files/etc/project.properties b/functional-test/src/test/resources/project-import/ansible-encrypted-inventory/rundeck-ansible-encrypted-inventory/files/etc/project.properties new file mode 100644 index 00000000..ba35f2c2 --- /dev/null +++ b/functional-test/src/test/resources/project-import/ansible-encrypted-inventory/rundeck-ansible-encrypted-inventory/files/etc/project.properties @@ -0,0 +1,30 @@ +#Exported configuration +project.description= +project.disable.executions=false +project.disable.schedule=false +project.execution.history.cleanup.batch=500 +project.execution.history.cleanup.enabled=false +project.execution.history.cleanup.retention.days=60 +project.execution.history.cleanup.retention.minimum=50 +project.execution.history.cleanup.schedule=0 0 0 1/1 * ? * +project.jobs.gui.groupExpandLevel=1 +project.label= +project.later.executions.disable=false +project.later.executions.enable=false +project.later.schedule.disable=false +project.later.schedule.enable=false +project.name=encrypted-inventory-test +project.nodeCache.enabled=true +project.nodeCache.firstLoadSynch=true +project.output.allowUnsanitized=false +project.retry-counter=3 +project.ssh-authentication=privateKey +resources.source.1.type=local +resources.source.2.config.ansible-config-file-path=/home/rundeck/ansible +resources.source.2.config.ansible-inventory=/home/rundeck/ansible/inventory-encrypted.ini +resources.source.2.config.ansible-gather-facts=true +resources.source.2.config.ansible-ignore-errors=true +resources.source.2.config.ansible-vault-storage-path=keys/project/ansible-encrypted-inventory/vault-inventory.password +resources.source.2.type=com.batix.rundeck.plugins.AnsibleResourceModelSourceFactory +service.FileCopier.default.provider=sshj-scp +service.NodeExecutor.default.provider=sshj-ssh \ No newline at end of file diff --git a/src/main/groovy/com/rundeck/plugins/ansible/plugin/AnsibleResourceModelSource.java b/src/main/groovy/com/rundeck/plugins/ansible/plugin/AnsibleResourceModelSource.java index c924f280..553d58cf 100644 --- a/src/main/groovy/com/rundeck/plugins/ansible/plugin/AnsibleResourceModelSource.java +++ b/src/main/groovy/com/rundeck/plugins/ansible/plugin/AnsibleResourceModelSource.java @@ -190,7 +190,6 @@ public void configure(Properties configuration) throws ConfigurationException { sshAgent = (String) resolveProperty(AnsibleDescribable.ANSIBLE_SSH_USE_AGENT,null,configuration,executionDataContext); sshPassphraseStoragePath = (String) resolveProperty(AnsibleDescribable.ANSIBLE_SSH_PASSPHRASE,null,configuration,executionDataContext); - vaultPasswordPath = (String) resolveProperty(AnsibleDescribable.ANSIBLE_BECOME_PASSWORD_STORAGE_PATH,null,configuration,executionDataContext); becamePasswordStoragePath = (String) resolveProperty(AnsibleDescribable.ANSIBLE_BECOME_PASSWORD_STORAGE_PATH,null,configuration,executionDataContext);