Skip to content

Instantly share code, notes, and snippets.

@tzolov
Last active January 29, 2020 14:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tzolov/3926f3e618a851bbf02d70be805abb91 to your computer and use it in GitHub Desktop.
Save tzolov/3926f3e618a851bbf02d70be805abb91 to your computer and use it in GitHub Desktop.
Read Container Image Labels
package org.springframework.cloud.dataflow.registry;
import java.util.Map;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.codec.binary.Base64;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
/**
* - Docker Image Labels:{configuration-properties.names=other.message, configuration-properties.classes=com.example.mylog.MyLogProperties}
* - OCI Image Labels:{configuration-properties.names=other.message, configuration-properties.classes=com.example.mylog.MyLogProperties}
* - Spring Artifactory Docker Image Labels:{com.microsoft.product=Microsoft SQL Server, com.microsoft.version=14.0.3045.24, vendor=Microsoft}
*
* @author Christian Tzolov
*/
public class ContainerImageLabelReader {
// https://github.com/opencontainers/image-spec/blob/master/media-types.md
public static String OCI_IMAGE_MANIFEST_MEDIA_TYPE = "application/vnd.oci.image.manifest.v1+json";
public static String DOCKER_IMAGE_MANIFEST_MEDIA_TYPE = "application/vnd.docker.distribution.manifest.v2+json";
public static void main(String[] args) throws JsonProcessingException {
String springArtifactoryUsername = args[0];
// Get the encrypted pass from your https://repo.spring.io/webapp/#/profile Encrypted Password
String springArtifactoryEncryptedPassword = args[1];
System.out.println(">>>> Docker Image Labels:" + imageLabels(dockerHubAuthorizationHeaders("tzolov/my-log-sink"),
"registry-1.docker.io",
"tzolov/my-log-sink", "latest", DOCKER_IMAGE_MANIFEST_MEDIA_TYPE));
System.out.println(">>>> OCI Image Labels:" + imageLabels(dockerHubAuthorizationHeaders("tzolov/my-log-sink-oci"),
"registry-1.docker.io",
"tzolov/my-log-sink-oci",
"latest",
OCI_IMAGE_MANIFEST_MEDIA_TYPE));
System.out.println(">>>> Spring Artifactory Docker Image Labels:" + imageLabels(
springArtifactoryAuthorizationHeaders(springArtifactoryUsername, springArtifactoryEncryptedPassword),
"springsource-docker-private-local.jfrog.io",
"mssql/database-prebuilt",
"2017-CU12-ubuntu", DOCKER_IMAGE_MANIFEST_MEDIA_TYPE));
}
public static Map<String, String> imageLabels(HttpHeaders headers, String registryHost, String imageRepository,
String imageTag, String manifestMediaType) throws JsonProcessingException {
RestTemplate rest = new RestTemplate();
headers.set(HttpHeaders.ACCEPT, manifestMediaType);
final HttpEntity<String> entity = new HttpEntity<>(headers);
// Docker Registry HTTP V2 API pull manifest
ResponseEntity<Map> manifest = rest.exchange("https://{registryHost}/v2/{repository}/manifests/{tag}",
HttpMethod.GET, entity, Map.class, registryHost, imageRepository, imageTag);
String configDigest = ((Map<String, String>) manifest.getBody().get("config")).get("digest");
// Docker Registry HTTP V2 API pull config blob
ResponseEntity<String> configBlobOctet = rest.exchange("https://{registryHost}/v2/{repository}/blobs/{digest}",
HttpMethod.GET, entity, String.class, registryHost, imageRepository, configDigest);
// Extract labels from the config JSON response
Map<String, Object> configBlob = new ObjectMapper().readValue(configBlobOctet.getBody(), Map.class);
Map<String, String> labels = (Map<String, String>) ((Map<String, Object>) configBlob.get("config")).get("Labels");
return labels;
}
public static HttpHeaders dockerHubAuthorizationHeaders(String imageRepository) {
Map<String, String> access = new RestTemplate().getForObject("https://auth.docker.io/token?service=registry.docker.io&scope=repository:{repository}:pull&offline_token=1&client_id=shell", Map.class, imageRepository);
String accessToken = access.get("token");
final HttpHeaders headers = new HttpHeaders();
headers.set(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken);
return headers;
}
public static HttpHeaders springArtifactoryAuthorizationHeaders(String user, String encryptedPassword) {
final HttpHeaders headers = new HttpHeaders();
headers.set(HttpHeaders.AUTHORIZATION, "Basic " + new String(Base64.encodeBase64((user + ":" + encryptedPassword).getBytes())));
return headers;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment