Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion job-dsl-plugin/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ dependencies {
compile(project(':job-dsl-core')) {
exclude group: 'org.jvnet.hudson', module:'xstream'
}
jenkinsPlugins 'org.jenkins-ci.plugins:cloudbees-folder:5.14'
jenkinsPlugins 'org.jenkins-ci.plugins:structs:1.19'
jenkinsPlugins 'org.jenkins-ci.plugins:script-security:1.54'
optionalJenkinsPlugins('org.jenkins-ci.plugins:vsphere-cloud:1.1.11') {
Expand All @@ -99,7 +100,6 @@ dependencies {
optionalJenkinsPlugins 'io.jenkins:configuration-as-code:1.15'
jenkinsTest 'io.jenkins:configuration-as-code:1.15'
jenkinsTest 'io.jenkins:configuration-as-code:1.15:tests'
jenkinsTest 'org.jenkins-ci.plugins:cloudbees-folder:5.14'
jenkinsTest 'org.jenkins-ci.plugins:matrix-auth:1.3'
jenkinsTest 'org.jenkins-ci.plugins:nested-view:1.14'
jenkinsTest 'org.jenkins-ci.plugins:credentials:2.1.10'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package javaposse.jobdsl.plugin

import com.cloudbees.hudson.plugins.folder.AbstractFolderProperty
import hudson.model.Items
import javaposse.jobdsl.dsl.Item

class DslItemConfigurer {
private static final String XML_HEADER = "<?xml version='1.1' encoding='UTF-8'?>"

/**
* Merge an {@link AbstractFolderProperty} into a new {@link Item}'s properties.
*
* @param item the property to merge
* @param dslItem the DSL item to merge the properties into
*/
static void mergeCredentials(AbstractFolderProperty<?> property, Item dslItem) {
String xml = Items.XSTREAM2.toXML(property)
Node node = new XmlParser().parseText(XML_HEADER + xml)
dslItem.configure { p -> p / 'properties' << node }
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
package javaposse.jobdsl.plugin;

import static hudson.model.Result.UNSTABLE;
import static hudson.model.View.createViewFromXML;
import static java.lang.String.format;
import static java.nio.charset.StandardCharsets.UTF_8;

import com.cloudbees.hudson.plugins.folder.AbstractFolderProperty;
import com.cloudbees.hudson.plugins.folder.Folder;
import com.cloudbees.hudson.plugins.folder.properties.FolderCredentialsProvider.FolderCredentialsProperty;
import com.google.common.collect.Collections2;
import com.google.common.collect.Iterables;
import com.thoughtworks.xstream.io.xml.XppDriver;
Expand Down Expand Up @@ -52,6 +60,7 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
Expand Down Expand Up @@ -444,6 +453,7 @@ private String lookupJob(String path) throws IOException {
}

private boolean updateExistingItem(AbstractItem item, javaposse.jobdsl.dsl.Item dslItem) {
mergeCredentials(item, dslItem);
String config = dslItem.getXml();

item.checkPermission(Item.EXTENDED_READ);
Expand Down Expand Up @@ -576,6 +586,22 @@ private void renameJob(Job from, String to) throws IOException {
from.renameTo(FilenameUtils.getName(to));
}

private void mergeCredentials(AbstractItem item, javaposse.jobdsl.dsl.Item dslItem) {
if (item instanceof Folder) {
Folder folder = (Folder) item;
Optional<AbstractFolderProperty<?>> maybeProperty =
folder.getProperties().stream()
.filter(p -> p instanceof FolderCredentialsProperty)
.findFirst();

if (maybeProperty.isPresent()) {
LOGGER.log(Level.FINE, format("Merging credentials for %s", item.getName()));
DslItemConfigurer.mergeCredentials(maybeProperty.get(), dslItem);
}
}
}


@SuppressWarnings("unchecked")
private static <I extends AbstractItem & TopLevelItem> void move(Item item, DirectlyModifiableTopLevelItemGroup destination) throws IOException {
Items.move((I) item, destination);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
package javaposse.jobdsl.plugin

import com.cloudbees.hudson.plugins.folder.AbstractFolder
import com.cloudbees.hudson.plugins.folder.AbstractFolderProperty
import com.cloudbees.hudson.plugins.folder.AbstractFolderPropertyDescriptor
import com.cloudbees.hudson.plugins.folder.Folder
import com.cloudbees.hudson.plugins.folder.properties.FolderCredentialsProvider
import com.cloudbees.plugins.credentials.CredentialsScope
import com.cloudbees.plugins.credentials.domains.Domain
import com.cloudbees.plugins.credentials.domains.DomainCredentials
import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl
import com.google.common.io.Resources
import hudson.Extension
import hudson.FilePath
import hudson.model.AbstractBuild
import hudson.model.AllView
Expand Down Expand Up @@ -632,6 +641,32 @@ class JenkinsJobManagementSpec extends Specification {
e.message == 'Type of item "my-job" does not match existing type, item type can not be changed'
}

def 'createOrUpdateConfig should preserve credentials if they exist on a folder'() {
setup:
Folder folder = jenkinsRule.createProject(Folder, 'folder')
folder.addProperty(createCredentialProperty())

when:
jobManagement.createOrUpdateConfig(createItem('folder', '/folder.xml'), false)

then:
def actual = jenkinsRule.jenkins.getItem('folder')
actual.properties.size() == 1
}

def 'createOrUpdateConfig should ignore other properties on the folder'() {
setup:
Folder folder = jenkinsRule.createProject(Folder, 'folder')
folder.addProperty(new FakeProperty())

when:
jobManagement.createOrUpdateConfig(createItem('folder', '/folder.xml'), false)

then:
def actual = jenkinsRule.jenkins.getItem('folder')
actual.properties.size() == 0
}

def 'createOrUpdateView should work if view type changes'() {
setup:
jenkinsRule.jenkins.addView(new AllView('foo'))
Expand Down Expand Up @@ -973,10 +1008,27 @@ class JenkinsJobManagementSpec extends Specification {
Resources.toString(Resources.getResource(resourceName), UTF_8)
}

private static FolderCredentialsProvider.FolderCredentialsProperty createCredentialProperty() {
UsernamePasswordCredentialsImpl credentials = new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, '',
'', '', '')
DomainCredentials[] domainCredentials = new DomainCredentials[1]
domainCredentials[0] = new DomainCredentials(Domain.global(), Collections.singletonList(credentials))

new FolderCredentialsProvider.FolderCredentialsProperty(domainCredentials)
}

private static class FakeProperty extends AbstractFolderProperty<AbstractFolder<?>> {

@Extension(optional = true)
static class DescriptorImpl extends AbstractFolderPropertyDescriptor {
final String displayName = ''
}
}

private Item createItem(String name, String config) {
new Item(jobManagement, name) {
@Override
Node getNode() {
Node getNodeTemplate() {
new XmlParser().parse(JenkinsJobManagementSpec.getResourceAsStream(config))
}
}
Expand Down
2 changes: 2 additions & 0 deletions job-dsl-plugin/src/test/resources/folder.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<com.cloudbees.hudson.plugins.folder.Folder>
</com.cloudbees.hudson.plugins.folder.Folder>