Last active
January 29, 2020 14:22
-
-
Save tzolov/3926f3e618a851bbf02d70be805abb91 to your computer and use it in GitHub Desktop.
Read Container Image Labels
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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