diff --git a/README.md b/README.md index f4febf1..4829522 100644 --- a/README.md +++ b/README.md @@ -2,44 +2,44 @@ This [Jenkins](http://jenkins-ci.org) plugin allows the tracking of the creation and use of Docker containers in Jenkins and their future use. -#Plugin Summary +# Plugin Summary * Container deployments summary page * Tracking of Docker image and container deployments produced in Jenkins * Tracking of Docker container events * Tracking of Docker container states being retrieved from *docker inspect* calls -* Advanced [API](#API): +* Advanced [API](#api): * Submission of events from Docker and Docker Swarm installations * Data polling from Jenkins (including Docker API-compatible JSONs) * Support of search queries - + ![Main page](/doc/images/root-action.png) -#Installation Guidelines +# Installation Guidelines -##Plugin setup +## Plugin setup 1. Install CloudBees Docker Traceability plugin from Jenkins Update Center 2. Install other Jenkins plugins, which produce image fingerprints to be traced by the plugin (see [Integrations](#Integrations)) 3. Configure security. This step is **very important**, because the plugin can store raw JSON, which may contain sensitive info like passwords * The plugin introduces new permissions, which allow to restrict the access - * **Read** - Allows to retrieve details like full container/info dumps. + * **Read** - Allows to retrieve details like full container/info dumps. Web interfaces are being managed by common Jenkins Read permission - * **Submit** - Allows the submission deployment records from the [remote API](#API) + * **Submit** - Allows the submission deployment records from the [remote API](#api) * **Delete** - Allows the deletion deployment records or entire fingerprints 4. Setup the Docker image fingerprint creation mode * By default, the plugin does not create image fingerprints on its own. These fingerprints are expected to be created by other Docker plugins based on [Docker Commons][docker-commons] * The behavior can be adjusted on the plugin's global configuration page -##Client-side configuration +## Client-side configuration ``` The section is under construction ``` -#Use-cases +# Use-cases -##Submitting deployment records +## Submitting deployment records The plugin does not support an automatic polling of events from external Docker servers. The events should be submitted by external clients or other Jenkins plugins. @@ -47,13 +47,13 @@ The plugin does not support an automatic polling of events from external Docker From external items using REST API ----- -The [plugin's API](#API) provides several commands, which allow to submit new events from remote applications. +The [plugin's API](#api) provides several commands, which allow to submit new events from remote applications. **submitContainerStatus** is a simple call, which may be used from user scripts without a generation of additional JSON files. -Examples: +Examples: ``` - curl http://localhost:8080/jenkins/docker-traceability/submitContainerStatus +curl http://localhost:8080/jenkins/docker-traceability/submitContainerStatus --data-urlencode inspectData="$(docker inspect CONTAINER_ID)" curl http://localhost:8080/jenkins/docker-traceability/submitContainerStatus @@ -68,7 +68,7 @@ curl http://localhost:8080/jenkins/docker-traceability/submitContainerStatus From other plugins ----- -The plugin provides the DockerEventListener extension point, which is being used to notify listeners about new records. +The plugin provides the DockerEventListener extension point, which is being used to notify listeners about new records. Docker Traceability functionality also listens to these endpoints, so it is possible to notify the plugin about new records using DockerEventListener#fire() method. @@ -80,24 +80,23 @@ For each container record the plugin publishes the info on the container summary ![Docker image page](/doc/images/image-page.png) - If an external client submits information about the image (which can be retrieved using *docker inspect imageId* command), the plugin captures this image and adds a new facet to the image fingerprint page. ![Docker image info facet](/doc/images/docker-image-facet.png) -Raw data is accessible via the [plugin's API](#API) or via hyperlinks on info pages. +Raw data is accessible via the [plugin's API](#api) or via hyperlinks on info pages. ## Search -You can search deployments by container IDs using the "Search" control on the "Docker Traceability" page. You can also query containers using the [plugin's API](#API). +You can search deployments by container IDs using the "Search" control on the "Docker Traceability" page. You can also query containers using the [plugin's API](#api). -#Integrations +# Integrations -CloudBees Docker Traceability plugin is based on fingerprints provided by [Docker Commons Plugin][docker-commons]. The plugin just adds additional facets to main fingerprint pages, so any other plugin can contribute to the UI by adding additional facets to the fingerprint. +CloudBees Docker Traceability plugin is based on fingerprints provided by [Docker Commons Plugin][docker-commons]. The plugin just adds additional facets to main fingerprint pages, so any other plugin can contribute to the UI by adding additional facets to the fingerprint. See [Docker Commons Plugin Wiki page][docker-commons] to get an info about existing fingerprint contributors. -#API +# API The detailed description of API endpoints is available in the "api" page of the "Docker Traceability" root action (see *$(JENKINS_URL)/docker-traceability/api*) diff --git a/docker-java-shaded/.gitignore b/docker-java-shaded/.gitignore index 2e73990..916e17c 100644 --- a/docker-java-shaded/.gitignore +++ b/docker-java-shaded/.gitignore @@ -1 +1 @@ -dependency-reduced-pom.xml \ No newline at end of file +dependency-reduced-pom.xml diff --git a/docker-traceability-plugin/src/main/java/org/jenkinsci/plugins/docker/traceability/core/DockerTraceabilityRootAction.java b/docker-traceability-plugin/src/main/java/org/jenkinsci/plugins/docker/traceability/core/DockerTraceabilityRootAction.java index 32427db..5ddc9cb 100644 --- a/docker-traceability-plugin/src/main/java/org/jenkinsci/plugins/docker/traceability/core/DockerTraceabilityRootAction.java +++ b/docker-traceability-plugin/src/main/java/org/jenkinsci/plugins/docker/traceability/core/DockerTraceabilityRootAction.java @@ -24,6 +24,7 @@ package org.jenkinsci.plugins.docker.traceability.core; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; import hudson.BulkChange; import hudson.Extension; import hudson.XmlFile; @@ -341,16 +342,16 @@ public void doImage(StaplerRequest req, StaplerResponse rsp, //TODO: filtering by container ID, imageID, containerName, imageName, hostName, hostID, environment /** * Retrieves the latest container status via API. - * The output will be retrieved in JSON. Supports filers. Missing - * "since" and "until" + * Supports filers. Missing "since" and "until" * @param id ID of the container, for which the info should be retrieved. * Short container IDs are not supported. + * @param format Format used in the response. See {@link ResponseFormat} for supported format. * @throws IOException Processing error * @throws ServletException Servlet error - * @return Raw JSON output compatible with docker inspect + * @return Response available in different formats, including a JSON output compatible with docker inspect */ - public HttpResponse doRawContainerInfo(@QueryParameter(required = true) String id) - throws IOException, ServletException { + public HttpResponse doRawContainerInfo(@QueryParameter(required = true) String id, @QueryParameter(required = false) final String format) + throws IOException, ServletException { checkPermission(DockerTraceabilityPlugin.READ_DETAILS); //TODO: check containerID format @@ -364,9 +365,8 @@ public HttpResponse doRawContainerInfo(@QueryParameter(required = true) String i return HttpResponses.error(500, "Cannot retrieve the container's status"); } - // Return raw JSON in the response InspectContainerResponse[] out = {inspectInfo}; - return toJSONResponse(out); + return toFormattedResponse(out, format); } //TODO: More filtering @@ -380,15 +380,17 @@ public HttpResponse doRawContainerInfo(@QueryParameter(required = true) String i * If the value equals to 0, the filter will be ignored (default in {@link QueryParameter}). * @param until End time. * If the value equals to 0, the filter will be ignored (default in {@link QueryParameter}). + * @param format Format used in the response. See {@link ResponseFormat} for supported format. * @throws IOException Processing error * @throws ServletException Servlet error - * @return Response containing the output JSON. may be an error if something breaks. + * @return Response available in different formats. may be an error if something breaks. */ public HttpResponse doQueryContainer( @QueryParameter(required = true) String id, @QueryParameter(required = false) String mode, @QueryParameter(required = false) long since, - @QueryParameter(required = false) long until) + @QueryParameter(required = false) long until, + @QueryParameter(required = false) String format) throws IOException, ServletException { checkPermission(DockerTraceabilityPlugin.READ_DETAILS); @@ -439,21 +441,23 @@ public HttpResponse doQueryContainer( } } - // Return raw JSON in the response - return toJSONResponse(result); + return toFormattedResponse(result, format); } /** * Retrieves the latest raw status via API. - * The output will be retrieved in JSON. + * * @param id ID of the image, for which the info should be retrieved. * Short container IDs are not supported. + * @param format Format used in the output response. See {@link ResponseFormat} for supported format. + * * @throws IOException Processing error * @throws ServletException Servlet error - * @return {@link HttpResponse} + * + * @return Response ({@link HttpResponse}) available in different formats */ - public HttpResponse doRawImageInfo(@QueryParameter(required = true) String id) - throws IOException, ServletException { + public HttpResponse doRawImageInfo(@QueryParameter(required = true) String id, @QueryParameter(required = false) String format) + throws IOException, ServletException { checkPermission(DockerTraceabilityPlugin.READ_DETAILS); final InspectImageResponse report = DockerTraceabilityHelper.getLastInspectImageResponse(id); @@ -461,9 +465,8 @@ public HttpResponse doRawImageInfo(@QueryParameter(required = true) String id) return HttpResponses.error(404, "No info available for the imageId=" + id); } - // Return raw JSON in the response InspectImageResponse[] out = {report}; - return toJSONResponse(out); + return toFormattedResponse(out, format); } /** @@ -564,18 +567,65 @@ private synchronized void load() { LOGGER.log(Level.SEVERE, "Failed to load the configuration from config path = "+config,e); } } - + + /** + * Represents the supported response formats (JSON, pretty JSON). + */ + private enum ResponseFormat { + JSON("application/json;charset=UTF-8", false), + PRETTYJSON("application/json;charset=UTF-8", true); + + private String contentType; + + private boolean pretty; + + private static final ResponseFormat DEFAULT = JSON; + + private ResponseFormat(final String contentType, final boolean pretty) { + this.contentType = contentType; + this.pretty = pretty; + } + + public static ResponseFormat fromAlias(final String alias) { + if (alias == null) { + return DEFAULT; + } + if (alias.equals("json")) { + return JSON; + } else if (alias.equals("json-pretty")) { + return PRETTYJSON; + } else { + throw new IllegalStateException("Unsupported format: " + alias); + } + } + + public String getContentType() { + return contentType; + } + + public boolean getPretty() { + return pretty; + } + } + /** - * Serves the JSON response. - * @param item Data to be serialized to JSON - * @return HTTP response with application/json MIME type + * Serves the response and manages its output format in the response. + * + * @param item Data to be serialized + * @param format Format used in the response. See {@link ResponseFormat} for supported format. + * + * @return HTTP response with MIME type */ - private static HttpResponse toJSONResponse(final Object item) { + private static HttpResponse toFormattedResponse(final Object item, final String format) { return new HttpResponse() { @Override public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { - ObjectMapper mapper = new ObjectMapper(); - rsp.setContentType("application/json;charset=UTF-8"); + ObjectMapper mapper = new ObjectMapper(); + ResponseFormat responseFormat = ResponseFormat.fromAlias(format); + rsp.setContentType(responseFormat.getContentType()); + if (responseFormat.getPretty()) { + mapper.enable(SerializationFeature.INDENT_OUTPUT); + } mapper.writeValue(rsp.getWriter(), item); } }; diff --git a/docker-traceability-plugin/src/main/resources/org/jenkinsci/plugins/docker/traceability/core/DockerTraceabilityRootAction/_api.jelly b/docker-traceability-plugin/src/main/resources/org/jenkinsci/plugins/docker/traceability/core/DockerTraceabilityRootAction/_api.jelly index 2664496..8ec2ba3 100644 --- a/docker-traceability-plugin/src/main/resources/org/jenkinsci/plugins/docker/traceability/core/DockerTraceabilityRootAction/_api.jelly +++ b/docker-traceability-plugin/src/main/resources/org/jenkinsci/plugins/docker/traceability/core/DockerTraceabilityRootAction/_api.jelly @@ -25,200 +25,227 @@ --> +
+

Additional API commands

Getting info

- Docker Deployment READ permission is required for all commands. - -

$(JENKINS_URL)/docker-traceability/container

- Gets a container page. Jenkins will redirect the request to the fingerprint page, - which addresses the specified container. -

- Returns: HTML page describing the container"s fingerprint track. -

- Query Parameters: +

Docker Deployment READ permission is required for all commands.

+

$(JENKINS_URL)/docker-traceability/container

+

Gets a container page. Jenkins will redirect the request to the fingerprint page, which addresses the specified container.

+

Returns a HTML page describing the container's fingerprint track.

+

Query Parameters:

-

$(JENKINS_URL)/docker-traceability/image

- Gets an image page by its ID. Jenkins will redirect the request to the fingerprint page, - which addresses the specified image. -

- Returns: HTML page describing the image"s fingerprint track. -

- Query Parameters: +

$(JENKINS_URL)/docker-traceability/image

+

Gets an image page by its ID. Jenkins will redirect the request to the fingerprint page, which addresses the specified image.

+

Returns a HTML page describing the image's fingerprint track.

+

Query Parameters:

- -

$(JENKINS_URL)/docker-traceability/rawContainerInfo

- Retrieves the last available info about the container. -

- Returns: JSON string similar to docker inspect $(containerId) output. - Output is compatible with Docker API v.1.16 -

- Query Parameters: + +

$(JENKINS_URL)/docker-traceability/rawContainerInfo

+

Retrieves the last available info about the container.

+

Returns a JSON string similar to docker inspect $(containerId) output. Output is compatible with Docker API v.1.16

+

Query Parameters:

- -

$(JENKINS_URL)/docker-traceability/queryContainer

- Retrieves the info about container. -

- Returns: JSON string similar to docker inspect $(containerId) output. - -

- Query Parameters: -

-
id
-
ID of the container. Only full 64-symbol IDs are supported
-
since
-
The time is specified in seconds since January 1, 1970, 00:00:00 GMT
-
until
-
The time is specified in seconds since January 1, 1970, 00:00:00 GMT
-
mode
-
Defines a data to be retrieved. Supported values: + +

$(JENKINS_URL)/docker-traceability/queryContainer

+

Retrieves the info about container.

+

Returns: JSON string similar to docker inspect $(containerId) output.

+

Query Parameters:

+
    +
  • idID of the container. Only full 64-symbol IDs are supported
  • +
  • sinceThe time is specified in seconds since January 1, 1970, 00:00:00 GMT
  • +
  • untilThe time is specified in seconds since January 1, 1970, 00:00:00 GMT
  • +
  • modeDefines a data to be retrieved. Supported values:
    -
    inspectContaner (default)
    -
    Outputs a JSON array similar to "docker inspect $(containerId)". - Output is compatible with Docker API v.1.16 -
    -
    inspectImage
    -
    Outputs a JSON array similar to "docker inspect $(imageId)". - Output is compatible with Docker API v.1.16 -
    -
    events
    +
    inspectContaner (default)
    +
    Outputs a JSON array similar to docker inspect $(containerId). Output is compatible with Docker API v.1.16
    +
    inspectImage
    +
    Outputs a JSON array similar to docker inspect $(imageId). Output is compatible with Docker API v.1.16
    +
    events
    JSON array of events
    -
    hostInfo
    -
    Outputs a JSON array similar to "docker info"
    -
    all
    +
    hostInfo
    +
    Outputs a JSON array similar to docker info
    +
    all
    Outputs all available data in an internal format
    -
-
- -

$(JENKINS_URL)/docker-traceability/rawImageInfo

- Retrieves the last available info about the container. -

- Returns: JSON string similar to docker inspect $(imageId) output. - Output is compatible with Docker API v.1.16 -

- Query Parameters: -

- -

Managing data

- Docker Deployment SUBMIT permission is required for all commands. - -

$(JENKINS_URL)/docker-traceability/submitContainerStatus

- Allows to submit the current container status snapshot with a minimal set of - parameters. Outputs of docker inspect $(containerId) can be directly - submitted to Jenkins server using this command. -

- Parameters: -

-

- Call examples: -

- -

$(JENKINS_URL)/docker-traceability/submitReport

- Submits a report using the extended JSON API. - This endpoint can be used by scripts to submit the full available info about - the container and its environment in a single command. -

- Parameters: + +

$(JENKINS_URL)/docker-traceability/rawImageInfo

+

Retrieves the last available info about the container.

+

Returns a JSON string similar to docker inspect $(imageId) output. Output is compatible with Docker API v.1.16

+

Query Parameters:

- Call example: +

Managing data

+

Docker Deployment SUBMIT permission is required for all commands.

+ +

$(JENKINS_URL)/docker-traceability/submitContainerStatus

+

Allows to submit the current container status snapshot with a minimal set of + parameters. Outputs of docker inspect $(containerId) can be directly + submitted to Jenkins server using this command.

+

Parameters:

- -

$(JENKINS_URL)/docker-traceability/deleteContainer

- Removes an obsolete container reference from the DockerTraceability registry. - The data from container fingerprints won't be deleted, so the record will be - completely restored after a new submission if its gets deleted due to a mistake. -

- Parameters: +

Call examples:

+ curl http://localhost:8080/jenkins/docker-traceability/submitContainerStatus --data-urlencode inspectData="$(docker inspect CONTAINER_ID)" + +

$(JENKINS_URL)/docker-traceability/submitReport

+

Submits a report using the extended JSON API. This endpoint can be used by scripts to submit the full available info about the container and its environment in a single command.

+

Parameters:

+

This structure has the following entries:

+
+
event
+
Describes the event, for which the record is being submitted. This entry is mandatory, but its status may have the "NONE" value, which will notify Docker Traceability Plugin that there's no status changes.
+
Data format: Single JSON entry similar to the ouput of the docker events command
+
hostInfo
+
Info about the Docker host or Swarm Instance, on which the container runs.
+
Data format: JSON version of the docker info command
+
container
+
Optional info about the container status. If the info is available, the plugin will record a new container.
+
Data format: Single JSON entry similar to the output of the docker inspect $(containerId) command
+
image
+
Optional info about the image status. If the info is available, the summary info will be added to the image fingerprint page.
+
Data format: Single JSON entry similar to the output of the docker inspect $(imageId) command
+
imageId
+
ID of the image, which may be retrieved from the container info.
+
Data format: String. Only full 64-symbol IDs are supported
+
imageName
+
Optional name of the image. It can be extracted from "docker images" command output.
+
Data format: String
+
parents
+
List of the image parents
+
Data format: Array of strings. Each entry has a format similar to imageId
+
environment
+
Optional free-style string describing the environment
+
Data format: String
+
+

Call example (from test samples):

+ curl http://localhost:8080/jenkins/docker-traceability/submitReport --data-urlencode json@src/test/resources/org/jenkinsci/plugins/docker/traceability/samples/submitReport.json +

$(JENKINS_URL)/docker-traceability/deleteContainer

+

Removes an obsolete container reference from the DockerTraceability registry. + The data from container fingerprints won't be deleted, so the record will be + completely restored after a new submission if its gets deleted due to a mistake.

+

Parameters:

+ +
diff --git a/docker-traceability-plugin/src/test/java/org/jenkinsci/plugins/docker/traceability/model/DockerTraceabilityReportTest.java b/docker-traceability-plugin/src/test/java/org/jenkinsci/plugins/docker/traceability/model/DockerTraceabilityReportTest.java index fe1ff85..8e9002b 100644 --- a/docker-traceability-plugin/src/test/java/org/jenkinsci/plugins/docker/traceability/model/DockerTraceabilityReportTest.java +++ b/docker-traceability-plugin/src/test/java/org/jenkinsci/plugins/docker/traceability/model/DockerTraceabilityReportTest.java @@ -26,6 +26,7 @@ import org.jenkinsci.plugins.docker.traceability.api.DockerTraceabilityReport; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; import java.io.IOException; import org.jenkinsci.plugins.docker.traceability.samples.JSONSamples; import static org.junit.Assert.assertEquals; @@ -41,6 +42,7 @@ public class DockerTraceabilityReportTest { @Test public void jsonRoundTrip() throws IOException { ObjectMapper mapper = new ObjectMapper(); + mapper.enable(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS); DockerTraceabilityReport report = JSONSamples.submitReport.readObject(DockerTraceabilityReport.class); assertNotNull(report.getContainer()); assertNotNull(report.getEvent());