Search in sources :

Example 6 with TaskListener

use of hudson.model.TaskListener in project sonar-scanner-jenkins by SonarSource.

the class BuilderUtilsTest method buildEnv.

@Test
public void buildEnv() throws IOException, InterruptedException {
    TaskListener l = mock(TaskListener.class);
    AbstractBuild<?, ?> r = mock(AbstractBuild.class);
    EnvVars env = new EnvVars("key", "value", "key2", "value2");
    when(r.getEnvironment(l)).thenReturn(env);
    when(r.getBuildVariables()).thenReturn(ImmutableMap.of("key", "newValue"));
    env = BuilderUtils.getEnvAndBuildVars(r, l);
    assertThat(env.descendingMap()).contains(entry("key", "newValue"), entry("key2", "value2"));
}
Also used : EnvVars(hudson.EnvVars) TaskListener(hudson.model.TaskListener) Test(org.junit.Test)

Example 7 with TaskListener

use of hudson.model.TaskListener in project workflow-cps-plugin by jenkinsci.

the class DSL method reportAmbiguousStepInvocation.

private void reportAmbiguousStepInvocation(CpsStepContext context, StepDescriptor d, @Nullable TaskListener listener) {
    if (listener != null) {
        List<String> ambiguousClassNames = StepDescriptor.all().stream().filter(sd -> sd.getFunctionName().equals(d.getFunctionName())).map(sd -> sd.clazz.getName()).collect(Collectors.toList());
        String message = String.format("Warning: Invoking ambiguous Pipeline Step ā€˜%1$sā€™ (%2$s). " + "ā€˜%1$sā€™ could refer to any of the following steps: %3$s. " + "You can invoke steps by class name instead to avoid ambiguity. " + "For example: steps.'%2$s'(...)", d.getFunctionName(), d.clazz.getName(), ambiguousClassNames);
        listener.getLogger().println(message);
        return;
    }
    LOGGER.log(Level.FINE, "Unable to report ambiguous step invocation for: " + d.getFunctionName());
}
Also used : Arrays(java.util.Arrays) StringUtils(org.apache.commons.lang.StringUtils) Step(org.jenkinsci.plugins.workflow.steps.Step) Closure(groovy.lang.Closure) Symbol(org.jenkinsci.Symbol) EnvironmentExpander(org.jenkinsci.plugins.workflow.steps.EnvironmentExpander) ReflectionCache(org.codehaus.groovy.reflection.ReflectionCache) NoStaplerConstructorException(org.kohsuke.stapler.NoStaplerConstructorException) Map(java.util.Map) NonNull(edu.umd.cs.findbugs.annotations.NonNull) GroovyObjectSupport(groovy.lang.GroovyObjectSupport) PersistenceContext(org.jenkinsci.plugins.workflow.cps.persistence.PersistenceContext) Restricted(org.kohsuke.accmod.Restricted) GroovyRuntimeException(groovy.lang.GroovyRuntimeException) Jenkins(jenkins.model.Jenkins) Set(java.util.Set) Logger(java.util.logging.Logger) Collectors(java.util.stream.Collectors) LoadStep(org.jenkinsci.plugins.workflow.cps.steps.LoadStep) ParallelStep(org.jenkinsci.plugins.workflow.cps.steps.ParallelStep) ClassDescriptor(org.kohsuke.stapler.ClassDescriptor) Run(hudson.model.Run) Serializable(java.io.Serializable) GString(groovy.lang.GString) CachedClass(org.codehaus.groovy.reflection.CachedClass) DescribableModel(org.jenkinsci.plugins.structs.describable.DescribableModel) StepStartNode(org.jenkinsci.plugins.workflow.cps.nodes.StepStartNode) List(java.util.List) Continuable(com.cloudbees.groovy.cps.Continuable) Annotation(java.lang.annotation.Annotation) Entry(java.util.Map.Entry) DescribableParameter(org.jenkinsci.plugins.structs.describable.DescribableParameter) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings) FlowNode(org.jenkinsci.plugins.workflow.graph.FlowNode) FlowExecutionOwner(org.jenkinsci.plugins.workflow.flow.FlowExecutionOwner) InterpolatedSecretsAction(org.jenkinsci.plugins.workflow.cps.view.InterpolatedSecretsAction) StepListener(org.jenkinsci.plugins.workflow.flow.StepListener) TreeSet(java.util.TreeSet) Computer(hudson.model.Computer) ArrayList(java.util.ArrayList) Level(java.util.logging.Level) GroovyObject(groovy.lang.GroovyObject) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) Queue(hudson.model.Queue) ArgumentsActionImpl(org.jenkinsci.plugins.workflow.cps.actions.ArgumentsActionImpl) UninstantiatedDescribable(org.jenkinsci.plugins.structs.describable.UninstantiatedDescribable) EnvVars(hudson.EnvVars) BodyExecutionCallback(org.jenkinsci.plugins.workflow.steps.BodyExecutionCallback) Index(org.jvnet.hudson.annotation_indexer.Index) Util(hudson.Util) PersistIn(org.jenkinsci.plugins.workflow.cps.persistence.PersistIn) AbortException(hudson.AbortException) TaskListener(hudson.model.TaskListener) SymbolLookup(org.jenkinsci.plugins.structs.SymbolLookup) Descriptor(hudson.model.Descriptor) StepExecution(org.jenkinsci.plugins.workflow.steps.StepExecution) NoExternalUse(org.kohsuke.accmod.restrictions.NoExternalUse) IOException(java.io.IOException) StepContext(org.jenkinsci.plugins.workflow.steps.StepContext) Outcome(com.cloudbees.groovy.cps.Outcome) TreeMap(java.util.TreeMap) Nullable(edu.umd.cs.findbugs.annotations.Nullable) Describable(hudson.model.Describable) StepDescriptor(org.jenkinsci.plugins.workflow.steps.StepDescriptor) StepAtomNode(org.jenkinsci.plugins.workflow.cps.nodes.StepAtomNode) StepEndNode(org.jenkinsci.plugins.workflow.cps.nodes.StepEndNode) CheckForNull(edu.umd.cs.findbugs.annotations.CheckForNull) Collections(java.util.Collections) ExtensionList(hudson.ExtensionList) ThreadTaskResult(org.jenkinsci.plugins.workflow.cps.ThreadTaskResult) GString(groovy.lang.GString)

Example 8 with TaskListener

use of hudson.model.TaskListener in project workflow-cps-plugin by jenkinsci.

the class DSL method invokeStep.

/**
 * When {@link #invokeMethod(String, Object)} is calling a {@link StepDescriptor}
 * @param d The {@link StepDescriptor} being invoked.
 * @param name The name used to invoke the step. May be {@link StepDescriptor#getFunctionName}, a symbol as in {@link StepDescriptor#metaStepsOf}, or {@code d.clazz.getName()}.
 * @param args The arguments passed to the step.
 */
protected Object invokeStep(StepDescriptor d, String name, Object args) {
    final NamedArgsAndClosure ps = parseArgs(args, d);
    CpsThread thread = CpsThread.current();
    FlowNode an;
    // TODO: generalize the notion of Step taking over the FlowNode creation.
    boolean hack = d instanceof ParallelStep.DescriptorImpl || d instanceof LoadStep.DescriptorImpl;
    if (ps.body == null && !hack) {
        if (!(d.getClass().getName().equals("org.jenkinsci.plugins.workflow.support.steps.StageStep$DescriptorImpl")) && d.takesImplicitBlockArgument()) {
            throw new IllegalStateException(String.format("%s step must be called with a body", name));
        } else {
            an = new StepAtomNode(exec, d, thread.head.get());
        }
    } else {
        an = new StepStartNode(exec, d, thread.head.get());
    }
    final CpsStepContext context = new CpsStepContext(d, thread, handle, an, ps.body);
    EnvVars allEnv = null;
    Set<String> sensitiveVariables = Collections.emptySet();
    try {
        allEnv = context.get(EnvVars.class);
        EnvironmentExpander envExpander = context.get(EnvironmentExpander.class);
        if (envExpander != null) {
            sensitiveVariables = new HashSet<>(envExpander.getSensitiveVariables());
        }
    } catch (IOException | InterruptedException e) {
        LOGGER.log(Level.WARNING, "Unable to retrieve environment variables", e);
    }
    // Ensure ArgumentsAction is attached before we notify even synchronous listeners:
    ArgumentsActionImpl argumentsAction = null;
    try {
        // No point storing empty arguments, and ParallelStep is a special case where we can't store its closure arguments
        if (ps.namedArgs != null && !(ps.namedArgs.isEmpty()) && isKeepStepArguments() && !(d instanceof ParallelStep.DescriptorImpl)) {
            // Get the environment variables to find ones that might be credentials bindings
            Computer comp = context.get(Computer.class);
            if (comp != null && allEnv != null) {
                allEnv.entrySet().removeAll(comp.getEnvironment().entrySet());
            }
            argumentsAction = new ArgumentsActionImpl(ps.namedArgs, allEnv, sensitiveVariables);
            an.addAction(argumentsAction);
        }
    } catch (Exception e) {
        // Avoid breaking execution because we can't store some sort of crazy Step argument
        LOGGER.log(Level.WARNING, "Error storing the arguments for step: " + d.getFunctionName(), e);
    }
    // TODO: use CPS call stack to obtain the current call site source location. See JENKINS-23013
    thread.head.setNewHead(an);
    Step s;
    boolean sync;
    ClassLoader originalLoader = Thread.currentThread().getContextClassLoader();
    try {
        TaskListener listener = context.get(TaskListener.class);
        logInterpolationWarnings(name, argumentsAction, ps.interpolatedStrings, allEnv, sensitiveVariables, listener);
        if (unreportedAmbiguousFunctions.remove(name)) {
            reportAmbiguousStepInvocation(context, d, listener);
        }
        d.checkContextAvailability(context);
        Thread.currentThread().setContextClassLoader(CpsVmExecutorService.ORIGINAL_CONTEXT_CLASS_LOADER.get());
        if (Util.isOverridden(StepDescriptor.class, d.getClass(), "newInstance", Map.class)) {
            s = d.newInstance(ps.namedArgs);
        } else {
            DescribableModel<? extends Step> stepModel = DescribableModel.of(d.clazz);
            s = stepModel.instantiate(ps.namedArgs, listener);
        }
        // Persist the node - block start and end nodes do their own persistence.
        CpsFlowExecution.maybeAutoPersistNode(an);
        // Call any registered StepListeners.
        for (StepListener sl : ExtensionList.lookup(StepListener.class)) {
            try {
                sl.notifyOfNewStep(s, context);
            } catch (Throwable e) {
                LOGGER.log(Level.WARNING, "failed to notify step listener before starting " + s.getDescriptor().getFunctionName(), e);
            }
        }
        if (!context.isCompleted()) {
            StepExecution e = s.start(context);
            thread.setStep(e);
            sync = e.start();
        } else {
            s = null;
            sync = true;
        }
    } catch (Exception e) {
        context.onFailure(e);
        s = null;
        sync = true;
    } finally {
        Thread.currentThread().setContextClassLoader(originalLoader);
    }
    if (sync) {
        assert context.withBodyInvokers(List::isEmpty) : "If a step claims synchronous completion, it shouldn't invoke body";
        if (context.getOutcome() == null) {
            context.onFailure(new AssertionError("Step " + s + " claimed to have ended synchronously, but didn't set the result via StepContext.onSuccess/onFailure"));
        }
        thread.setStep(null);
        // we just move on accordingly
        if (an instanceof StepStartNode) {
            // no body invoked, so EndNode follows StartNode immediately.
            thread.head.setNewHead(new StepEndNode(exec, (StepStartNode) an, an));
        }
        thread.head.markIfFail(context.getOutcome());
        return context.replay();
    } else {
        // if it's in progress, suspend it until we get invoked later.
        // when it resumes, the CPS caller behaves as if this method returned with the resume value
        Continuable.suspend(name, new ThreadTaskImpl(context));
        // so the execution will never reach here.
        throw new AssertionError();
    }
}
Also used : EnvironmentExpander(org.jenkinsci.plugins.workflow.steps.EnvironmentExpander) GString(groovy.lang.GString) Step(org.jenkinsci.plugins.workflow.steps.Step) LoadStep(org.jenkinsci.plugins.workflow.cps.steps.LoadStep) ParallelStep(org.jenkinsci.plugins.workflow.cps.steps.ParallelStep) StepAtomNode(org.jenkinsci.plugins.workflow.cps.nodes.StepAtomNode) StepExecution(org.jenkinsci.plugins.workflow.steps.StepExecution) ArgumentsActionImpl(org.jenkinsci.plugins.workflow.cps.actions.ArgumentsActionImpl) Computer(hudson.model.Computer) TaskListener(hudson.model.TaskListener) List(java.util.List) ArrayList(java.util.ArrayList) ExtensionList(hudson.ExtensionList) StepStartNode(org.jenkinsci.plugins.workflow.cps.nodes.StepStartNode) LoadStep(org.jenkinsci.plugins.workflow.cps.steps.LoadStep) IOException(java.io.IOException) StepEndNode(org.jenkinsci.plugins.workflow.cps.nodes.StepEndNode) NoStaplerConstructorException(org.kohsuke.stapler.NoStaplerConstructorException) GroovyRuntimeException(groovy.lang.GroovyRuntimeException) AbortException(hudson.AbortException) IOException(java.io.IOException) ParallelStep(org.jenkinsci.plugins.workflow.cps.steps.ParallelStep) EnvVars(hudson.EnvVars) StepListener(org.jenkinsci.plugins.workflow.flow.StepListener) FlowNode(org.jenkinsci.plugins.workflow.graph.FlowNode)

Example 9 with TaskListener

use of hudson.model.TaskListener in project workflow-cps-plugin by jenkinsci.

the class DSL method logInterpolationWarnings.

private void logInterpolationWarnings(String stepName, @CheckForNull ArgumentsActionImpl argumentsAction, Set<String> interpolatedStrings, @CheckForNull EnvVars envVars, @NonNull Set<String> sensitiveVariables, TaskListener listener) throws IOException {
    if (UNSAFE_GROOVY_INTERPOLATION.equals("ignore")) {
        return;
    }
    boolean shouldFail;
    if (UNSAFE_GROOVY_INTERPOLATION.equals("fail")) {
        shouldFail = true;
    } else {
        shouldFail = false;
    }
    if (argumentsAction == null || interpolatedStrings.isEmpty() || envVars == null || envVars.isEmpty() || sensitiveVariables.isEmpty()) {
        return;
    }
    // Workaround for NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE false positive in lambdas: https://github.com/spotbugs/spotbugs/issues/552.
    final EnvVars nonNullEnvVars = envVars;
    List<String> scanResults = sensitiveVariables.stream().filter(e -> !nonNullEnvVars.get(e, "").isEmpty() && interpolatedStrings.stream().anyMatch(g -> g.contains(nonNullEnvVars.get(e)))).collect(Collectors.toList());
    if (scanResults != null && !scanResults.isEmpty()) {
        String warningType;
        if (shouldFail) {
            warningType = "Error";
        } else {
            warningType = "Warning";
        }
        String warning = String.format("%s: A secret was passed to \"%s\" using Groovy String interpolation, which is insecure.%n\t\t Affected argument(s) used the following variable(s): %s%n\t\t See https://jenkins.io/redirect/groovy-string-interpolation for details.", warningType, stepName, scanResults.toString());
        FlowExecutionOwner owner = exec.getOwner();
        if (owner != null && owner.getExecutable() instanceof Run) {
            InterpolatedSecretsAction runReport = ((Run) owner.getExecutable()).getAction(InterpolatedSecretsAction.class);
            if (runReport == null) {
                runReport = new InterpolatedSecretsAction();
                ((Run) owner.getExecutable()).addAction(runReport);
            }
            runReport.record(stepName, scanResults);
        } else {
            LOGGER.log(Level.FINE, "Unable to generate Interpolated Secrets Report");
        }
        if (shouldFail) {
            throw new AbortException(warning);
        } else {
            listener.getLogger().println(warning);
        }
    }
}
Also used : Arrays(java.util.Arrays) StringUtils(org.apache.commons.lang.StringUtils) Step(org.jenkinsci.plugins.workflow.steps.Step) Closure(groovy.lang.Closure) Symbol(org.jenkinsci.Symbol) EnvironmentExpander(org.jenkinsci.plugins.workflow.steps.EnvironmentExpander) ReflectionCache(org.codehaus.groovy.reflection.ReflectionCache) NoStaplerConstructorException(org.kohsuke.stapler.NoStaplerConstructorException) Map(java.util.Map) NonNull(edu.umd.cs.findbugs.annotations.NonNull) GroovyObjectSupport(groovy.lang.GroovyObjectSupport) PersistenceContext(org.jenkinsci.plugins.workflow.cps.persistence.PersistenceContext) Restricted(org.kohsuke.accmod.Restricted) GroovyRuntimeException(groovy.lang.GroovyRuntimeException) Jenkins(jenkins.model.Jenkins) Set(java.util.Set) Logger(java.util.logging.Logger) Collectors(java.util.stream.Collectors) LoadStep(org.jenkinsci.plugins.workflow.cps.steps.LoadStep) ParallelStep(org.jenkinsci.plugins.workflow.cps.steps.ParallelStep) ClassDescriptor(org.kohsuke.stapler.ClassDescriptor) Run(hudson.model.Run) Serializable(java.io.Serializable) GString(groovy.lang.GString) CachedClass(org.codehaus.groovy.reflection.CachedClass) DescribableModel(org.jenkinsci.plugins.structs.describable.DescribableModel) StepStartNode(org.jenkinsci.plugins.workflow.cps.nodes.StepStartNode) List(java.util.List) Continuable(com.cloudbees.groovy.cps.Continuable) Annotation(java.lang.annotation.Annotation) Entry(java.util.Map.Entry) DescribableParameter(org.jenkinsci.plugins.structs.describable.DescribableParameter) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings) FlowNode(org.jenkinsci.plugins.workflow.graph.FlowNode) FlowExecutionOwner(org.jenkinsci.plugins.workflow.flow.FlowExecutionOwner) InterpolatedSecretsAction(org.jenkinsci.plugins.workflow.cps.view.InterpolatedSecretsAction) StepListener(org.jenkinsci.plugins.workflow.flow.StepListener) TreeSet(java.util.TreeSet) Computer(hudson.model.Computer) ArrayList(java.util.ArrayList) Level(java.util.logging.Level) GroovyObject(groovy.lang.GroovyObject) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) Queue(hudson.model.Queue) ArgumentsActionImpl(org.jenkinsci.plugins.workflow.cps.actions.ArgumentsActionImpl) UninstantiatedDescribable(org.jenkinsci.plugins.structs.describable.UninstantiatedDescribable) EnvVars(hudson.EnvVars) BodyExecutionCallback(org.jenkinsci.plugins.workflow.steps.BodyExecutionCallback) Index(org.jvnet.hudson.annotation_indexer.Index) Util(hudson.Util) PersistIn(org.jenkinsci.plugins.workflow.cps.persistence.PersistIn) AbortException(hudson.AbortException) TaskListener(hudson.model.TaskListener) SymbolLookup(org.jenkinsci.plugins.structs.SymbolLookup) Descriptor(hudson.model.Descriptor) StepExecution(org.jenkinsci.plugins.workflow.steps.StepExecution) NoExternalUse(org.kohsuke.accmod.restrictions.NoExternalUse) IOException(java.io.IOException) StepContext(org.jenkinsci.plugins.workflow.steps.StepContext) Outcome(com.cloudbees.groovy.cps.Outcome) TreeMap(java.util.TreeMap) Nullable(edu.umd.cs.findbugs.annotations.Nullable) Describable(hudson.model.Describable) StepDescriptor(org.jenkinsci.plugins.workflow.steps.StepDescriptor) StepAtomNode(org.jenkinsci.plugins.workflow.cps.nodes.StepAtomNode) StepEndNode(org.jenkinsci.plugins.workflow.cps.nodes.StepEndNode) CheckForNull(edu.umd.cs.findbugs.annotations.CheckForNull) Collections(java.util.Collections) ExtensionList(hudson.ExtensionList) ThreadTaskResult(org.jenkinsci.plugins.workflow.cps.ThreadTaskResult) EnvVars(hudson.EnvVars) FlowExecutionOwner(org.jenkinsci.plugins.workflow.flow.FlowExecutionOwner) Run(hudson.model.Run) GString(groovy.lang.GString) InterpolatedSecretsAction(org.jenkinsci.plugins.workflow.cps.view.InterpolatedSecretsAction) AbortException(hudson.AbortException)

Example 10 with TaskListener

use of hudson.model.TaskListener in project workflow-cps-plugin by jenkinsci.

the class EnvActionImpl method getProperty.

@Override
public String getProperty(String propertyName) {
    try {
        CpsThread t = CpsThread.current();
        TaskListener listener = getListener();
        return EnvironmentExpander.getEffectiveEnvironment(getEnvironment(listener), t.getContextVariable(EnvVars.class, this::getExecution, this::getNode), t.getContextVariable(EnvironmentExpander.class, this::getExecution, this::getNode), null, listener).get(propertyName);
    } catch (Exception x) {
        LOGGER.log(Level.WARNING, null, x);
        return null;
    }
}
Also used : LogTaskListener(hudson.util.LogTaskListener) TaskListener(hudson.model.TaskListener) IOException(java.io.IOException)

Aggregations

TaskListener (hudson.model.TaskListener)42 Test (org.junit.Test)28 AmazonCloudFormation (com.amazonaws.services.cloudformation.AmazonCloudFormation)25 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)24 DescribeStacksResult (com.amazonaws.services.cloudformation.model.DescribeStacksResult)16 AmazonCloudFormationWaiters (com.amazonaws.services.cloudformation.waiters.AmazonCloudFormationWaiters)16 Waiter (com.amazonaws.waiters.Waiter)15 DescribeStacksRequest (com.amazonaws.services.cloudformation.model.DescribeStacksRequest)14 Stack (com.amazonaws.services.cloudformation.model.Stack)12 EnvVars (hudson.EnvVars)10 Output (com.amazonaws.services.cloudformation.model.Output)9 DescribeChangeSetResult (com.amazonaws.services.cloudformation.model.DescribeChangeSetResult)8 IOException (java.io.IOException)8 DescribeChangeSetRequest (com.amazonaws.services.cloudformation.model.DescribeChangeSetRequest)6 LogTaskListener (hudson.util.LogTaskListener)4 PrintStream (java.io.PrintStream)4 ArrayList (java.util.ArrayList)4 Change (com.amazonaws.services.cloudformation.model.Change)3 CreateChangeSetRequest (com.amazonaws.services.cloudformation.model.CreateChangeSetRequest)3 ExecuteChangeSetRequest (com.amazonaws.services.cloudformation.model.ExecuteChangeSetRequest)3