Skip to content
Open
Show file tree
Hide file tree
Changes from 18 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
39 changes: 19 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,58 +2,58 @@

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):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see a need in such change, but I'm OK to replace it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@oleg-nenashev I don't remember why, but I had to change this for any reason.

* 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.

**Warning!** Currently the plugin accepts the info for previously registered fingerprints only. Other submissions will be ignored. Initial image records should be created by other plugins using (see [Integrations](#Integrations))

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
Expand All @@ -68,7 +68,7 @@ curl http://localhost:8080/jenkins/docker-traceability/submitContainerStatus

From other plugins
-----
The plugin provides the <code>DockerEventListener</code> extension point, which is being used to notify listeners about new records.
The plugin provides the <code>DockerEventListener</code> 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 <code>DockerEventListener#fire()</code> method.

Expand All @@ -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*)

Expand Down
1 change: 1 addition & 0 deletions docker-java-shaded/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/dependency-reduced-pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
* &quot;since&quot; and &quot;until&quot;
* Supports filers. Missing &quot;since&quot; and &quot;until&quot;
* @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
Expand All @@ -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
Expand All @@ -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);

Expand Down Expand Up @@ -439,31 +441,32 @@ 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);
if (report == null) {
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);
}

/**
Expand Down Expand Up @@ -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 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not just use the enum value in the web request and get stapler to parse and covert it for you?

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());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This smells to me. When you introduce a new enum (XML) this code will break but without any compile time safety.

this should be moved to a switch case to get the compile time safety - or the logic of the formatter should be moved into the enum IMHO.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jtnord Sure. I'm going to think about an alternative way.

if (responseFormat.getPretty()) {
mapper.enable(SerializationFeature.INDENT_OUTPUT);
}
mapper.writeValue(rsp.getWriter(), item);
}
};
Expand Down
Loading