/** * Method accessed by the Stapler framework when the following url is accessed: * <i>JENKINS_ROOT_URL/exws/browse/workspaceId/</i> * * @param workspaceId the workspace's unique id * @return the workspace whose id matches the given input id, or {@link NoFingerprintMatch} if fingerprint is not found * @throws IOException if fingerprint load operation fails * @throws IllegalArgumentException if {@link WorkspaceBrowserFacet} is not registered for the matching fingerprint */ @Restricted(NoExternalUse.class) @SuppressWarnings("unused") @Nonnull public Object getBrowse(String workspaceId) throws IOException { Fingerprint fingerprint = Jenkins.getActiveInstance()._getFingerprint(workspaceId); if (fingerprint == null) { return new NoFingerprintMatch(workspaceId); } WorkspaceBrowserFacet facet = fingerprint.getFacet(WorkspaceBrowserFacet.class); if (facet == null) { throw new IllegalArgumentException("Couldn't find the Fingerprint Facet that holds the Workspace metadata"); } return facet.getWorkspace(); }
@Test public void withRunCommand() { story.addStep(new Statement() { @Override public void evaluate() throws Throwable { assumeDocker(); WorkflowJob p = story.j.jenkins.createProject(WorkflowJob.class, "prj"); p.setDefinition(new CpsFlowDefinition( " docker.image('maven:3.3.9-jdk-8').withRun(\"--entrypoint mvn\", \"-version\") {c ->\n" + " sh \"docker logs ${c.id}\"" + "}", true)); story.j.assertBuildStatusSuccess(p.scheduleBuild2(0)); DockerClient client = new DockerClient(new Launcher.LocalLauncher(StreamTaskListener.NULL), null, null); String mavenIID = client.inspect(new EnvVars(), "maven:3.3.9-jdk-8", ".Id"); Fingerprint f = DockerFingerprints.of(mavenIID); assertNotNull(f); DockerRunFingerprintFacet facet = f.getFacet(DockerRunFingerprintFacet.class); assertNotNull(facet); } }); }
private void assertBuild(final String projectName, final String piplineCode) throws Exception { story.addStep(new Statement() { @Override public void evaluate() throws Throwable { assumeDocker(); WorkflowJob p = story.j.jenkins.createProject(WorkflowJob.class, projectName); p.setDefinition(new CpsFlowDefinition(piplineCode, true)); WorkflowRun b = story.j.assertBuildStatusSuccess(p.scheduleBuild2(0)); DockerClient client = new DockerClient(new LocalLauncher(StreamTaskListener.NULL), null, null); String ancestorImageId = client.inspect(new EnvVars(), "hello-world", ".Id"); story.j.assertLogContains("built from-with-arg", b); story.j.assertLogContains(ancestorImageId.replaceFirst("^sha256:", "").substring(0, 12), b); Fingerprint f = DockerFingerprints.of(ancestorImageId); assertNotNull(f); DockerDescendantFingerprintFacet descendantFacet = f.getFacet(DockerDescendantFingerprintFacet.class); assertNotNull(descendantFacet); } }); }
/** * Adds a new {@link ContainerRecord} for the specified image, creating necessary intermediate objects as it goes. */ public static void addRunFacet(@Nonnull ContainerRecord record, @Nonnull Run<?,?> run) throws IOException { String imageId = record.getImageId(); Fingerprint f = forImage(run, imageId); Collection<FingerprintFacet> facets = f.getFacets(); DockerRunFingerprintFacet runFacet = null; for (FingerprintFacet facet : facets) { if (facet instanceof DockerRunFingerprintFacet) { runFacet = (DockerRunFingerprintFacet) facet; break; } } BulkChange bc = new BulkChange(f); try { if (runFacet == null) { runFacet = new DockerRunFingerprintFacet(f, System.currentTimeMillis(), imageId); facets.add(runFacet); } runFacet.add(record); runFacet.addFor(run); DockerFingerprintAction.addToRun(f, imageId, run); bc.commit(); } finally { bc.abort(); } }
@Test public void test_readResolve() throws Exception { FreeStyleProject p = rule.createFreeStyleProject("test"); FreeStyleBuild b = rule.assertBuildStatusSuccess(p.scheduleBuild2(0)); ContainerRecord r1 = new ContainerRecord("192.168.1.10", "cid", IMAGE_ID, "magic", System.currentTimeMillis(), Collections.<String, String>emptyMap()); DockerFingerprints.addRunFacet(r1, b); Fingerprint fingerprint = DockerFingerprints.of(IMAGE_ID); DockerRunFingerprintFacet facet = new DockerRunFingerprintFacet(fingerprint, System.currentTimeMillis(), IMAGE_ID); ContainerRecord r2 = new ContainerRecord("192.168.1.10", "cid", null, "magic", System.currentTimeMillis(), Collections.<String, String>emptyMap()); facet.add(r2); Assert.assertNull(r2.getImageId()); facet.readResolve(); Assert.assertEquals(IMAGE_ID, r2.getImageId()); // Check that actions have been automatically added DockerFingerprintAction fpAction = b.getAction(DockerFingerprintAction.class); Assert.assertNotNull("DockerFingerprintAction should be added automatically", fpAction); Assert.assertTrue("Docker image should be referred in the action", fpAction.getImageIDs().contains(IMAGE_ID)); }
/** * Retrieves the last {@link InspectImageResponse} for the specified image. * @param imageId Image Id * @return Last available report. Null if there is no data available * (or if an internal exception happens) */ public static @CheckForNull InspectImageResponse getLastInspectImageResponse(@Nonnull String imageId) { try { final Fingerprint fp = DockerFingerprints.of(imageId); if (fp != null) { final DockerInspectImageFacet facet = FingerprintsHelper.getFacet(fp, DockerInspectImageFacet.class); if (facet != null) { return facet.getData(); } } return null; } catch (IOException ex) { LOGGER.log(Level.WARNING, "Cannot retrieve deployment reports for imageId="+imageId, ex); return null; } }
/** * Checks that the existence {@link DockerDeploymentFacet}. * @param containerId Container ID * @param imageId image ID * @return Facet (if validation passes) * @throws IOException test failure * @throws AssertionError Validation failure */ private @Nonnull DockerDeploymentFacet assertExistsDeploymentFacet (@Nonnull String containerId, @Nonnull String imageId) throws IOException { final Fingerprint containerFP = DockerTraceabilityHelper.ofValidated(containerId); assertNotNull(containerFP); final DockerDeploymentFacet containerFacet = FingerprintsHelper.getFacet(containerFP, DockerDeploymentFacet.class); assertNotNull(containerFacet); assertEquals(1, containerFacet.getDeploymentRecords().size()); final DockerContainerRecord record = containerFacet.getLatest(); assertNotNull(containerFacet.getLatest()); assertEquals(containerId, record.getContainerId()); assertEquals(DockerTraceabilityHelper.getImageHash(imageId), record.getImageFingerprintHash()); return containerFacet; }
/** * Checks that the existence {@link DockerDeploymentRefFacet}. * @param containerId Container ID * @param imageId image ID * @return Facet (if validation passes) * @throws IOException test failure * @throws AssertionError Validation failure */ public DockerDeploymentRefFacet assertExistsDeploymentRefFacet (@Nonnull String containerId, @Nonnull String imageId) throws IOException { final Fingerprint imageFP = DockerFingerprints.of(imageId); assertNotNull(imageFP); final DockerDeploymentRefFacet containerRefFacet = FingerprintsHelper.getFacet(imageFP, DockerDeploymentRefFacet.class); assertNotNull(containerRefFacet); assertEquals(1, containerRefFacet.getContainerIds().size()); for (String containerRefId : containerRefFacet.getContainerIds()) { assertNotNull(containerRefFacet.getLastStatus(containerRefId)); } assertEquals(containerId, containerRefFacet.getContainerIds().toArray()[0]); return containerRefFacet; }
private DeployedApplicationLocation addToFacets(Map.Entry<String, DeployedApplicationLocation> pair) throws IOException { DeployedApplicationLocation location = pair.getValue(); String md5sum = pair.getKey(); if (!NO_MD5.equals(md5sum)) { Jenkins j = Jenkins.getInstance(); if (j == null) { throw new IllegalStateException("Jenkins has not been started, or was already shut down"); } Fingerprint fingerprint = j._getFingerprint(md5sum); if (fingerprint != null) { fingerprint.getFacets() .add(new DeployedApplicationFingerprintFacet<DeployedApplicationLocation>(fingerprint, System.currentTimeMillis(), location)); fingerprint.save(); listener.getLogger().println("[cloudbees-deployer] Recorded deployment in fingerprint record"); } else { listener.getLogger() .println("[cloudbees-deployer] Deployed artifact does not have a fingerprint record"); } } return location; }
private void initPython() { if (pexec == null) { pexec = new PythonExecutor(this); String[] jMethods = new String[1]; jMethods[0] = "createFor"; String[] pFuncs = new String[1]; pFuncs[0] = "create_for"; Class[][] argTypes = new Class[1][]; argTypes[0] = new Class[2]; argTypes[0][0] = Fingerprint.class; argTypes[0][1] = List.class; pexec.checkAbstrMethods(jMethods, pFuncs, argTypes); String[] functions = new String[0]; int[] argsCount = new int[0]; pexec.registerFunctions(functions, argsCount); } }
/** * Registers a fingerprint for the given workspace's id. * * @param exws the workspace to register the fingerprint for * @throws IOException if fingerprint load operation fails */ private void registerFingerprint(ExternalWorkspace exws) throws IOException { FingerprintMap map = Jenkins.getActiveInstance().getFingerprintMap(); Fingerprint f = map.getOrCreate(run, exws.getDisplayName(), exws.getId()); if (f.getFacet(WorkspaceBrowserFacet.class) == null) { f.getFacets().add(new WorkspaceBrowserFacet(f, System.currentTimeMillis(), exws)); } f.save(); }
/** * Adds the current run to the fingerprint's usages. * * @param workspaceId the workspace's id * @throws IOException if fingerprint load operation fails, * or if no fingerprint is found for the given workspace id */ private void updateFingerprint(String workspaceId) throws IOException { Fingerprint f = Jenkins.getActiveInstance()._getFingerprint(workspaceId); if (f == null) { throw new AbortException("Couldn't find any Fingerprint for: " + workspaceId); } Fingerprint.RangeSet set = f.getUsages().get(run.getParent().getFullName()); if (set == null || !set.includes(run.getNumber())) { f.addFor(run); f.save(); } }
private static void deleteCredential(String id, NamespaceName name, String resourceRevision) throws IOException { Credentials existingCred = lookupCredentials(id); if (existingCred != null) { final SecurityContext previousContext = ACL.impersonate(ACL.SYSTEM); try { Fingerprint fp = CredentialsProvider .getFingerprintOf(existingCred); if (fp != null && fp.getJobs().size() > 0) { // per messages in credentials console, it is not a given, // but // it is possible for job refs to a credential to be // tracked; // if so, we will not prevent deletion, but at least note // things // for potential diagnostics StringBuffer sb = new StringBuffer(); for (String job : fp.getJobs()) sb.append(job).append(" "); logger.info("About to delete credential " + id + "which is referenced by jobs: " + sb.toString()); } CredentialsStore s = CredentialsProvider .lookupStores(Jenkins.getActiveInstance()).iterator() .next(); s.removeCredentials(Domain.global(), existingCred); logger.info("Deleted credential " + id + " from Secret " + name + " with revision: " + resourceRevision); s.save(); } finally { SecurityContextHolder.setContext(previousContext); } } }
private void verifyFileIsFingerPrinted(WorkflowJob pipeline, WorkflowRun build, String fileName) throws java.io.IOException { System.out.println(getClass() + " verifyFileIsFingerPrinted(" + build + ", " + fileName + ")"); Fingerprinter.FingerprintAction fingerprintAction = build.getAction(Fingerprinter.FingerprintAction.class); Map<String, String> records = fingerprintAction.getRecords(); System.out.println(getClass() + " records: " + records); String jarFileMd5sum = records.get(fileName); assertThat(jarFileMd5sum, not(nullValue())); Fingerprint jarFileFingerPrint = jenkinsRule.getInstance().getFingerprintMap().get(jarFileMd5sum); assertThat(jarFileFingerPrint.getFileName(), is(fileName)); assertThat(jarFileFingerPrint.getOriginal().getJob().getName(), is(pipeline.getName())); assertThat(jarFileFingerPrint.getOriginal().getNumber(), is(build.getNumber())); }
private static @CheckForNull Fingerprint ofNoException(@Nonnull String id) { try { return of(id); } catch (IOException ex) { // The error is not a hazard in CheckForNull logic LOGGER.log(Level.WARNING, "Cannot retrieve a fingerprint for Docker id="+id, ex); } return null; }
private static @Nonnull Fingerprint forDockerInstance(@CheckForNull Run<?,?> run, @Nonnull String id, @CheckForNull String name, @Nonnull String prefix) throws IOException { final Jenkins j = Jenkins.getInstance(); if (j == null) { throw new IOException("Jenkins instance is not ready"); } final String imageName = prefix + (StringUtils.isNotBlank(name) ? name : id); return j.getFingerprintMap().getOrCreate(run, imageName, getFingerprintHash(id)); }
/** * Retrieves a facet from the {@link Fingerprint}. * @param <TFacet> Facet type to be retrieved * @param fingerprint Fingerprint, which stores facets * @param facetClass Class to be retrieved * @return First matching facet. */ @SuppressWarnings("unchecked") public static @CheckForNull <TFacet extends FingerprintFacet> TFacet getFacet (@Nonnull Fingerprint fingerprint, @Nonnull Class<TFacet> facetClass) { for ( FingerprintFacet facet : fingerprint.getFacets()) { if (facetClass.isAssignableFrom(facet.getClass())) { return (TFacet)facet; } } return null; }
/** * Retrieves facets from the {@link Fingerprint}. * @param <TFacet> Facet type to be retrieved * @param fingerprint Fingerprint, which stores facets * @param facetClass Facet class to be retrieved * @return All found facets */ public static @Nonnull @SuppressWarnings("unchecked") <TFacet extends FingerprintFacet> Collection<TFacet> getFacets (@Nonnull Fingerprint fingerprint, @Nonnull Class<TFacet> facetClass) { final List<TFacet> res = new LinkedList<TFacet>(); for ( FingerprintFacet facet : fingerprint.getFacets()) { if (facetClass.isAssignableFrom(facet.getClass())) { res.add((TFacet)facet); } } return res; }
@Restricted(NoExternalUse.class) public @CheckForNull Fingerprint getFingerprint(@CheckForNull String imageId) { if (imageId == null) { return null; } try { return DockerFingerprints.of(imageId); } catch (IOException ex) { return null; // nothing to do in web UI - return null as well } }
public List<DockerFingerprintFacet> getDockerFacets(String imageId) { List<DockerFingerprintFacet> res = new LinkedList<DockerFingerprintFacet>(); final Fingerprint fp = getFingerprint(imageId); if (fp != null) { for (final FingerprintFacet f : fp.getFacets()) { if (f instanceof DockerFingerprintFacet) { res.add((DockerFingerprintFacet) f); } } } return res; }
/** * Adds an action with a reference to fingerprint if required. It's * recommended to call the method from { * * @BulkChange} transaction to avoid saving the {@link Run} multiple times. * @param fp Fingerprint * @param imageId ID of the docker image * @param run Run to be updated * @throws IOException Cannot save the action */ static void addToRun(Fingerprint fp, String imageId, Run run) throws IOException { synchronized (run) { DockerFingerprintAction action = run.getAction(DockerFingerprintAction.class); if (action == null) { action = new DockerFingerprintAction(); run.addAction(action); } if (action.imageIDs.add(imageId)) { run.save(); } // else no need to save updates } }
public DockerInspectImageFacet(@Nonnull Fingerprint fingerprint, long timestamp, @Nonnull InspectImageResponse data, @Nonnull String imageName) { super(fingerprint, timestamp); this.data = data; this.reportTimeInSeconds = timestamp; this.imageName = hudson.Util.fixEmpty(imageName); }
/** * Updates the facet by a new report. * The submission will be ignored if the current {@link #reportTimeInSeconds} is * greater than the submitted one, * @param fingerprint Fingerprint to be updated * @param reportTimeInSeconds Report generation time. * The time is specified in seconds since January 1, 1970, 00:00:00 GMT * @param data Report data from "docker inspect image" output * @param imageName Optional name of the image * @throws IOException Fingerprint save error */ public static void updateData(@Nonnull Fingerprint fingerprint, long reportTimeInSeconds, @Nonnull InspectImageResponse data, @CheckForNull String imageName) throws IOException { DockerInspectImageFacet facet = FingerprintsHelper.getFacet(fingerprint, DockerInspectImageFacet.class); if (facet == null) { facet = new DockerInspectImageFacet(fingerprint, reportTimeInSeconds, data, imageName); fingerprint.getFacets().add(facet); } else { facet.updateData(data, reportTimeInSeconds, imageName); } fingerprint.save(); }
public static DockerDeploymentRefFacet addRef(@Nonnull Fingerprint fingerprint, @Nonnull String containerId) throws IOException { DockerDeploymentRefFacet facet = getOrCreate(fingerprint, new Date().getTime()); facet.addRef(containerId); fingerprint.save(); return facet; }
/** * Retrieves a deployment facet for the specified container. * @param containerId Container ID (64-char) * @return Facet. Null if it is not available */ public static @CheckForNull DockerDeploymentFacet getDeploymentFacet(String containerId) { Fingerprint fp = DockerTraceabilityHelper.of(containerId); if (fp == null) { return null; } return FingerprintsHelper.getFacet(fp, DockerDeploymentFacet.class); }
public static @Nonnull DockerDeploymentFacet getOrCreate(@Nonnull Fingerprint fingerprint) throws IOException { DockerDeploymentFacet res = DockerFingerprints.getFacet(fingerprint, DockerDeploymentFacet.class); if (res != null) { return res; } // Create new one DockerDeploymentFacet facet = new DockerDeploymentFacet(fingerprint); fingerprint.getFacets().add(facet); fingerprint.save(); return facet; }
public static DockerDeploymentFacet addEvent(@Nonnull Fingerprint fingerprint, @Nonnull DockerTraceabilityReport event) throws IOException { DockerDeploymentFacet facet = getOrCreate(fingerprint); facet.add(new DockerContainerRecord(event)); fingerprint.save(); return facet; }
@Exported(visibility = 999) public Hashtable<String, RangeSet> getUsages() { Hashtable<String, RangeSet> res = new Hashtable<String, RangeSet>(fingerprint.getUsages().size()); for (Map.Entry<String, Fingerprint.RangeSet> set : fingerprint.getUsages().entrySet()) { res.put(set.getKey(), new RangeSet(set.getValue())); } return res; }
public static @CheckForNull @SuppressWarnings("unchecked") <TFacet extends FingerprintFacet> TFacet getFacet (@Nonnull Fingerprint fingerprint, @Nonnull Class<TFacet> facetClass) { for ( FingerprintFacet facet : fingerprint.getFacets()) { if (facetClass.isAssignableFrom(facet.getClass())) { return (TFacet)facet; } } return null; }
/** * Get a fingerprint by the specified container ID. * Logs and ignores {@link IOException}s on fingerprint loading. * @param containerId Full 64-symbol container id. Short forms are not supported. * @return Fingerprint. null if it is not available or if a loading error happens */ public static @CheckForNull Fingerprint of(@Nonnull String containerId) { try { return ofValidated(containerId); } catch (IOException ex) { LOGGER.log(Level.SEVERE, "Cannot load fingerprint for containerId=" + containerId, ex); return null; } }
/** * Get or create a fingerprint by the specified container ID. * @param containerId Full 64-symbol container id. Short forms are not supported. * @param name Optional name of the container. If it is not available, * the container ID will be used to produce the name * @return Fingerprint. null if Jenkins has not been initialized yet * @throws IOException Fingerprint loading error */ public static @CheckForNull Fingerprint make(@Nonnull String containerId, @CheckForNull String name) throws IOException { final Jenkins jenkins = Jenkins.getInstance(); if (jenkins == null) { return null; } return jenkins.getFingerprintMap().getOrCreate(null, "Container "+(name != null ? name : containerId), getContainerHash(containerId)); }
/** * Get or create a fingerprint by the specified image ID. * @param imageId Full 64-symbol image id. Short forms are not supported. * @param name Optional container name * @param timestamp Timestamp if there is a need to create a new image * @return Fingerprint. null if Jenkins has not been initialized yet * @throws IOException Fingerprint loading error */ public static @CheckForNull Fingerprint makeImage(@Nonnull String imageId, @CheckForNull String name, long timestamp) throws IOException { final Jenkins jenkins = Jenkins.getInstance(); if (jenkins == null) { return null; } // TODO: this image is not protected from the fingerprint cleanup thread final Fingerprint fp = jenkins.getFingerprintMap().getOrCreate( null, "Image "+(name != null ? name : imageId), getImageHash(imageId)); return fp; }
/** * Retrieves the last deployment record for the specified container. * @param containerId Container Id * @return Last registered record. Null if there is no data available * (or if an internal exception happens) */ public static @CheckForNull DockerContainerRecord getLastContainerRecord(@Nonnull String containerId) { final Fingerprint fp = of(containerId); if (fp != null) { final DockerDeploymentFacet facet = FingerprintsHelper.getFacet(fp, DockerDeploymentFacet.class); if (facet != null) { return facet.getLatest(); } } return null; }
@Test @Bug(28656) public void createFingerPrintsOnDemand() throws Exception { // Read data from resources String inspectData = JSONSamples.inspectContainerData.readString(); InspectContainerResponse inspectResponse = JSONSamples.inspectContainerData. readObject(InspectContainerResponse[].class)[0]; final String containerId = inspectResponse.getId(); final String imageId = inspectResponse.getImageId(); // Retrieve instances final DockerTraceabilityRootAction action = DockerTraceabilityRootAction.getInstance(); assertNotNull(action); // Enable automatic fingerprints creation DockerTraceabilityPluginConfiguration config = new DockerTraceabilityPluginConfiguration(true, false); DockerTraceabilityPluginTest.configure(config); DockerTraceabilityPlugin plugin = DockerTraceabilityPlugin.getInstance(); assertTrue(plugin.getConfiguration().isCreateImageFingerprints()); // Submit JSON HttpResponse res = action.doSubmitContainerStatus(inspectData, null, null, null, 0, null, null); // Ensure that both container and images have been created with proper facets Fingerprint imageFP = DockerFingerprints.of(imageId); Fingerprint containerFP = DockerFingerprints.of(containerId); assertNotNull(imageFP); assertNotNull(DockerFingerprints.getFacet(imageFP, DockerDeploymentRefFacet.class)); assertNotNull(containerFP); assertNotNull(DockerFingerprints.getFacet(containerFP, DockerDeploymentFacet.class)); // TODO: JENKINS-28655 (Fingerprints cleanup) // Check original references - Docker Traceability Manager should create runs // assertNotNull(imageFP.getOriginal().getJob()); // assertNotNull(containerFP.getOriginal().getJob()); }
/** * Checks that the existence {@link DockerInspectImageFacet}. * @param imageId image ID * @return Facet (if validation passes) * @throws IOException test failure * @throws AssertionError Validation failure */ public DockerInspectImageFacet assertExistsInspectImageFacet (@Nonnull String imageId) throws IOException { final Fingerprint imageFP = DockerFingerprints.of(imageId); assertNotNull(imageFP); final DockerInspectImageFacet inspectImageFacet = FingerprintsHelper.getFacet(imageFP, DockerInspectImageFacet.class); assertNotNull(inspectImageFacet); assertEquals(imageId, inspectImageFacet.getData().getId()); return inspectImageFacet; }
@Test public void testTrackingOfCredential() throws Exception { P4BaseCredentials credential = new P4PasswordImpl( CredentialsScope.GLOBAL, "testTrackingOfCredential", "desc:passwd", p4d.getRshPort(), null, "jenkins", "0", "0", null, "jenkins"); SystemCredentialsProvider.getInstance().getCredentials().add(credential); Fingerprint fingerprint = CredentialsProvider.getFingerprintOf(credential); assertThat("No fingerprint created until first use", fingerprint, nullValue()); FreeStyleProject job = jenkins.createFreeStyleProject("testTrackingOfCredential"); Workspace workspace = new StaticWorkspaceImpl("none", false, defaultClient()); Populate populate = new AutoCleanImpl(); PerforceScm scm = new PerforceScm(credential.getId(), workspace, populate); job.setScm(scm); job.save(); jenkins.assertBuildStatusSuccess(job.scheduleBuild2(0)); fingerprint = CredentialsProvider.getFingerprintOf(credential); assertThat(fingerprint, notNullValue()); assertThat(fingerprint.getJobs(), hasItem(is(job.getFullName()))); Fingerprint.RangeSet rangeSet = fingerprint.getRangeSet(job); assertThat(rangeSet, notNullValue()); assertThat(rangeSet.includes(job.getLastBuild().getNumber()), is(true)); }
@Override public Fingerprint getFingerprint() { initPython(); if (pexec.isImplemented(0)) { return (Fingerprint) pexec.execPython("get_fingerprint"); } else { return super.getFingerprint(); } }
@Before public void setUp() throws IOException, InterruptedException { git = null; repo = tempFolder.newFolder(); /* Use a repo with a special character in name - JENKINS-43931 */ String newDirName = "use " + specialCharacter + " dir"; File repoParent = repo; repo = new File(repoParent, newDirName); boolean dirCreated = repo.mkdirs(); assertTrue("Failed to create " + repo.getAbsolutePath(), dirCreated); File repoTemp = new File(repoParent, newDirName + "@tmp"); // use adjacent temp directory dirCreated = repoTemp.mkdirs(); assertTrue("Failed to create " + repoTemp.getAbsolutePath(), dirCreated); Logger logger = Logger.getLogger(this.getClass().getPackage().getName() + "-" + logCount++); handler = new LogHandler(); handler.setLevel(Level.ALL); logger.setUseParentHandlers(false); logger.addHandler(handler); logger.setLevel(Level.ALL); listener = new hudson.util.LogTaskListener(logger, Level.ALL); listener.getLogger().println(LOGGING_STARTED); git = Git.with(listener, new hudson.EnvVars()).in(repo).using(gitImpl).getClient(); if (gitImpl.equals("git")) { addExpectedLogSubstring("> git fetch "); addExpectedLogSubstring("> git checkout -b master "); } addExpectedLogSubstring("Using reference repository: "); assertTrue("Bad username, password, privateKey combo: '" + username + "', '" + password + "'", (password == null || password.isEmpty()) ^ (privateKey == null || !privateKey.exists())); if (password != null && !password.isEmpty()) { testedCredential = newUsernamePasswordCredential(username, password); } if (privateKey != null && privateKey.exists()) { testedCredential = newPrivateKeyCredential(username, privateKey); } assertThat(testedCredential, notNullValue()); Fingerprint fingerprint = CredentialsProvider.getFingerprintOf(testedCredential); assertThat("Fingerprint should not be set", fingerprint, nullValue()); }
@After public void checkFingerprintNotSet() throws Exception { /* Since these are API level tests, they should not track credential usage */ /* Credential usage is tracked at the job / project level */ Fingerprint fingerprint = CredentialsProvider.getFingerprintOf(testedCredential); assertThat("Fingerprint should not be set after API level use", fingerprint, nullValue()); }
@Issue("JENKINS-38831") @Test public void testTrackingOfCredential() { story.addStep(new Statement() { @Override public void evaluate() throws Throwable { String credentialsId = "creds"; String secret = "s3cr3t"; StringCredentialsImpl credentials = new StringCredentialsImpl(CredentialsScope.GLOBAL, credentialsId, "sample", Secret.fromString(secret)); Fingerprint fingerprint = CredentialsProvider.getFingerprintOf(credentials); CredentialsProvider.lookupStores(story.j.jenkins).iterator().next().addCredentials(Domain.global(), credentials); WorkflowJob p = story.j.jenkins.createProject(WorkflowJob.class, "p"); p.setDefinition(new CpsFlowDefinition("" + "def extract(id) {\n" + " def v\n" + " withCredentials([[$class: 'StringBinding', credentialsId: id, variable: 'temp']]) {\n" + " v = env.temp\n" + " }\n" + " v\n" + "}\n" + "node {\n" + " echo \"got: ${extract('" + credentialsId + "')}\"\n" + "}", true)); assertThat("No fingerprint created until first use", fingerprint, nullValue()); story.j.assertLogContains("got: " + secret, story.j.assertBuildStatusSuccess(p.scheduleBuild2(0).get())); fingerprint = CredentialsProvider.getFingerprintOf(credentials); assertThat(fingerprint, notNullValue()); assertThat(fingerprint.getJobs(), hasItem(is(p.getFullName()))); } }); }