Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[JENKINS-51395] Switching recommended syntax to inline arguments, whi…
…le still supporting the old syntax.
  • Loading branch information
jglick committed May 17, 2018
1 parent 732e1bb commit 8c463ba
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 31 deletions.
Expand Up @@ -32,19 +32,24 @@
import hudson.model.Node;
import hudson.model.TaskListener;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import java.util.TreeMap;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import org.jenkinsci.plugins.docker.commons.credentials.DockerRegistryEndpoint;
import org.jenkinsci.plugins.docker.commons.credentials.KeyMaterialFactory;
import org.jenkinsci.plugins.docker.commons.tools.DockerTool;
import org.jenkinsci.plugins.structs.describable.UninstantiatedDescribable;
import org.jenkinsci.plugins.workflow.steps.AbstractStepDescriptorImpl;
import org.jenkinsci.plugins.workflow.steps.AbstractStepImpl;
import org.jenkinsci.plugins.workflow.steps.Step;
import org.jenkinsci.plugins.workflow.steps.StepContextParameter;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;

public class RegistryEndpointStep extends AbstractStepImpl {

private final @Nonnull DockerRegistryEndpoint registry;
private @CheckForNull String toolName;

Expand Down Expand Up @@ -105,6 +110,30 @@ public DescriptorImpl() {
return true;
}

@Override
public UninstantiatedDescribable uninstantiate(Step step) throws UnsupportedOperationException {
RegistryEndpointStep s = (RegistryEndpointStep) step;
Map<String, Object> args = new TreeMap<>();
args.put("url", s.registry.getUrl());
args.put("credentialsId", s.registry.getCredentialsId());
args.put("toolName", s.toolName);
args.values().removeAll(Collections.singleton(null));
return new UninstantiatedDescribable(args);
}

@Override
public Step newInstance(Map<String, Object> arguments) throws Exception {
if (arguments.containsKey("url") || arguments.containsKey("credentialsId")) {
if (arguments.containsKey("registry")) {
throw new IllegalArgumentException("cannot mix url/credentialsId with registry");
}
arguments.put("registry", new DockerRegistryEndpoint((String) arguments.remove("url"), (String) arguments.remove("credentialsId")));
} else if (!arguments.containsKey("registry")) {
throw new IllegalArgumentException("must specify url/credentialsId (or registry)");
}
return super.newInstance(arguments);
}

}

}
Expand Up @@ -37,7 +37,7 @@ class Docker implements Serializable {
public <V> V withRegistry(String url, String credentialsId = null, Closure<V> body) {
node {
script.withEnv(["DOCKER_REGISTRY_URL=${url}"]) {
script.withDockerRegistry(registry: [url: url, credentialsId: credentialsId], toolName: script.env.DOCKER_TOOL_NAME) {
script.withDockerRegistry(url: url, credentialsId: credentialsId, toolName: script.env.DOCKER_TOOL_NAME) {
body()
}
}
Expand Down
Expand Up @@ -29,16 +29,13 @@
import com.cloudbees.plugins.credentials.common.IdCredentials;
import com.cloudbees.plugins.credentials.domains.Domain;
import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl;
import java.util.Collections;
import java.util.Map;
import java.util.TreeMap;
import org.jenkinsci.plugins.docker.commons.credentials.DockerRegistryEndpoint;
import org.jenkinsci.plugins.structs.describable.DescribableModel;
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
import org.jenkinsci.plugins.workflow.cps.SnippetizerTester;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.steps.StepConfigTester;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.Issue;
Expand All @@ -48,32 +45,42 @@ public class RegistryEndpointStepTest {

@Rule public JenkinsRule r = new JenkinsRule();

@Ignore("fails to run withDockerRegistry without registry: prefix, which is what Snippetizer offers")
@Issue("JENKINS-51395")
@Test public void configRoundTrip() throws Exception {
SnippetizerTester st = new SnippetizerTester(r);
RegistryEndpointStep step = new RegistryEndpointStep(new DockerRegistryEndpoint("https://myreg/", null));
st.assertRoundTrip(step, "withDockerRegistry([url: 'https://myreg/']) {\n // some block\n}");
step = new RegistryEndpointStep(new DockerRegistryEndpoint(null, "hubcreds"));
st.assertRoundTrip(step, "withDockerRegistry([credentialsId: 'hubcreds']) {\n // some block\n}");
step = new RegistryEndpointStep(new DockerRegistryEndpoint("https://myreg/", "mycreds"));
step.setToolName("ce");
st.assertRoundTrip(step, "withDockerRegistry(registry: [credentialsId: 'mycreds', url: 'https://myreg/'], toolName: 'ce') {\n // some block\n}");
IdCredentials registryCredentials = new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, "registryCreds", null, "me", "pass");
CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), registryCredentials);
StepConfigTester sct = new StepConfigTester(r);
// TODO use of DescribableModel here is gratuitous; the rest should just test the UI
Map<String,Object> registryConfig = new TreeMap<>();
registryConfig.put("url", "https://docker.my.com/");
registryConfig.put("credentialsId", registryCredentials.getId());
Map<String,Object> config = Collections.singletonMap("registry", registryConfig);
step = new DescribableModel<>(RegistryEndpointStep.class).instantiate(config);
step = sct.configRoundTrip(step);
DockerRegistryEndpoint registry = step.getRegistry();
assertNotNull(registry);
assertEquals("https://docker.my.com/", registry.getUrl());
assertEquals(registryCredentials.getId(), registry.getCredentialsId());
assertEquals(config, new DescribableModel<>(RegistryEndpointStep.class).uninstantiate(step));
{ // Recommended syntax.
SnippetizerTester st = new SnippetizerTester(r);
RegistryEndpointStep step = new RegistryEndpointStep(new DockerRegistryEndpoint("https://myreg/", null));
st.assertRoundTrip(step, "withDockerRegistry(url: 'https://myreg/') {\n // some block\n}");
step = new RegistryEndpointStep(new DockerRegistryEndpoint(null, "hubcreds"));
st.assertRoundTrip(step, "withDockerRegistry(credentialsId: 'hubcreds') {\n // some block\n}");
step = new RegistryEndpointStep(new DockerRegistryEndpoint("https://myreg/", "mycreds"));
step.setToolName("ce");
st.assertRoundTrip(step, "withDockerRegistry(credentialsId: 'mycreds', toolName: 'ce', url: 'https://myreg/') {\n // some block\n}");
}
{ // Older syntax.
WorkflowJob p = r.createProject(WorkflowJob.class, "p");
p.setDefinition(new CpsFlowDefinition("node {withDockerRegistry(registry: [url: 'https://docker.my.com/'], toolName: 'irrelevant') {}}", true));
r.buildAndAssertSuccess(p);
p.setDefinition(new CpsFlowDefinition("node {withDockerRegistry(registry: [url: 'https://docker.my.com/']) {}}", true));
r.buildAndAssertSuccess(p);
p.setDefinition(new CpsFlowDefinition("node {withDockerRegistry([url: 'https://docker.my.com/']) {}}", true));
r.buildAndAssertSuccess(p);
// and new, just in case SnippetizerTester is faking it:
p.setDefinition(new CpsFlowDefinition("node {withDockerRegistry(url: 'https://docker.my.com/') {}}", true));
r.buildAndAssertSuccess(p);
}
{ // UI form.
IdCredentials registryCredentials = new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, "registryCreds", null, "me", "pass");
CredentialsProvider.lookupStores(r.jenkins).iterator().next().addCredentials(Domain.global(), registryCredentials);
StepConfigTester sct = new StepConfigTester(r);
RegistryEndpointStep step = new RegistryEndpointStep(new DockerRegistryEndpoint("https://docker.my.com/", "registryCreds"));
step = sct.configRoundTrip(step);
DockerRegistryEndpoint registry = step.getRegistry();
assertNotNull(registry);
assertEquals("https://docker.my.com/", registry.getUrl());
assertEquals("registryCreds", registry.getCredentialsId());
// TODO check toolName
}
}

}

0 comments on commit 8c463ba

Please sign in to comment.