@Override public AuthConfig authConfig() { checkNotNull(dockerClientConfig.getRegistryUsername(), "Configured username is null."); checkNotNull(dockerClientConfig.getRegistryUrl(), "Configured serverAddress is null."); return new AuthConfig() .withUsername(dockerClientConfig.getRegistryUsername()) .withPassword(dockerClientConfig.getRegistryPassword()) .withEmail(dockerClientConfig.getRegistryEmail()) .withRegistryAddress(dockerClientConfig.getRegistryUrl()); }
@Test public void lookupAuthConfigWithBasicAuthCredentials() throws URISyntaxException { final RegistryAuthLocator authLocator = createTestAuthLocator("config-basic-auth.json"); final AuthConfig authConfig = authLocator.lookupAuthConfig(new DockerImageName("registry.example.com/org/repo"), new AuthConfig()); assertEquals("Default docker registry URL is set on auth config", "https://registry.example.com", authConfig.getRegistryAddress()); assertEquals("Username is set", "user", authConfig.getUsername()); assertEquals("Password is set", "pass", authConfig.getPassword()); }
private AuthConfig findExistingAuthConfig(final JsonNode config, final String reposName) throws Exception { final Map.Entry<String, JsonNode> entry = findAuthNode(config, reposName); if (entry != null && entry.getValue() != null && entry.getValue().size() > 0) { final AuthConfig deserializedAuth = OBJECT_MAPPER .treeToValue(entry.getValue(), AuthConfig.class) .withRegistryAddress(entry.getKey()); if (isBlank(deserializedAuth.getUsername()) && isBlank(deserializedAuth.getPassword()) && !isBlank(deserializedAuth.getAuth())) { final String rawAuth = new String(Base64.getDecoder().decode(deserializedAuth.getAuth())); final String[] splitRawAuth = rawAuth.split(":"); if (splitRawAuth.length == 2) { deserializedAuth.withUsername(splitRawAuth[0]); deserializedAuth.withPassword(splitRawAuth[1]); } } return deserializedAuth; } return null; }
private static void decodeAuth(AuthConfig config) throws IOException { if (config.getAuth() == null) { return; } String str = new String(Base64.decodeBase64(config.getAuth()), StandardCharsets.UTF_8); String[] parts = str.split(":", 2); if (parts.length != 2) { throw new IOException("Invalid auth configuration file"); } config.withUsername(parts[0]); config.withPassword(parts[1]); }
public static String toSafeString(AuthConfig authConfig) { if (authConfig == null) { return "null"; } return MoreObjects.toStringHelper(authConfig) .add("username", authConfig.getUsername()) .add("password", obfuscated(authConfig.getPassword())) .add("auth", obfuscated(authConfig.getAuth())) .add("email", authConfig.getEmail()) .add("registryAddress", authConfig.getRegistryAddress()) .add("registryToken", obfuscated(authConfig.getRegistrytoken())) .toString(); }
/** * Pull docker image using the docker java client. * * @param imageTag * @param username * @param password * @param host */ public static void pullImage(String imageTag, String username, String password, String host) throws IOException { final AuthConfig authConfig = new AuthConfig(); authConfig.withUsername(username); authConfig.withPassword(password); DockerClient dockerClient = null; try { dockerClient = getDockerClient(host); dockerClient.pullImageCmd(imageTag).withAuthConfig(authConfig).exec(new PullImageResultCallback()).awaitSuccess(); } finally { closeQuietly(dockerClient); } }
@CheckForNull private static DockerConfigFile loadLegacyConfig(String dockerConfigPath) throws IOException { File dockerLegacyCfgFile = new File(dockerConfigPath, DOCKER_LEGACY_CFG); if (!dockerLegacyCfgFile.exists() || !dockerLegacyCfgFile.isFile()) { return null; } //parse legacy auth config file format try { return new DockerConfigFile(MAPPER.<Map<String, AuthConfig>>readValue(dockerLegacyCfgFile, CONFIG_MAP_TYPE)); } catch (IOException e) { // pass } List<String> authFileContent = FileUtils.readLines(dockerLegacyCfgFile, StandardCharsets.UTF_8); if (authFileContent.size() < 2) { throw new IOException("The Auth Config file is empty"); } AuthConfig config = new AuthConfig(); String[] origAuth = authFileContent.get(0).split(" = "); if (origAuth.length != 2) { throw new IOException("Invalid Auth config file"); } config.withAuth(origAuth[1]); String[] origEmail = authFileContent.get(1).split(" = "); if (origEmail.length != 2) { throw new IOException("Invalid Auth config file"); } config.withEmail(origEmail[1]); return new DockerConfigFile(new HashMap<>(Collections.singletonMap(config.getRegistryAddress(), config))); }
@Test public void lookupAuthConfigWithCredentialsNotFound() throws URISyntaxException { Map<String, String> notFoundMessagesReference = new HashMap<>(); final RegistryAuthLocator authLocator = createTestAuthLocator("config-with-store.json", notFoundMessagesReference); DockerImageName dockerImageName = new DockerImageName("registry2.example.com/org/repo"); final AuthConfig authConfig = authLocator.lookupAuthConfig(dockerImageName, new AuthConfig()); assertNull("No username should have been obtained from a credential store", authConfig.getUsername()); assertNull("No secret should have been obtained from a credential store", authConfig.getPassword()); assertEquals("Should have one 'credentials not found' message discovered", 1, notFoundMessagesReference.size()); String discoveredMessage = notFoundMessagesReference.values().iterator().next(); assertEquals( "Not correct message discovered", "Fake credentials not found on credentials store 'https://not.a.real.registry/url'", discoveredMessage); }
private static DockerClient createDockerClient(String dockerUrl, String dockerVersion, String dockerCertPath, AuthConfig authConfig) { // TODO JENKINS-26512 SSLConfig dummySSLConf = (new SSLConfig() { public SSLContext getSSLContext() throws KeyManagementException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException { return null; } }); if (dockerCertPath != null) { dummySSLConf = new LocalDirectorySSLConfig(dockerCertPath); } DefaultDockerClientConfig.Builder configBuilder = new DefaultDockerClientConfig.Builder().withDockerHost(dockerUrl) .withApiVersion(dockerVersion).withCustomSslConfig(dummySSLConf); if (authConfig != null) { configBuilder.withRegistryUsername(authConfig.getUsername()) .withRegistryEmail(authConfig.getEmail()) .withRegistryPassword(authConfig.getPassword()) .withRegistryUrl(authConfig.getRegistryAddress()); } // using jaxrs/jersey implementation here (netty impl is also available) DockerCmdExecFactory dockerCmdExecFactory = new DockerCmdExecFactoryImpl() .withConnectTimeout(1000) .withMaxTotalConnections(1) .withMaxPerRouteConnections(1); return DockerClientBuilder.getInstance(configBuilder).withDockerCmdExecFactory(dockerCmdExecFactory).build(); }
public AuthConfig effectiveAuthConfig(String imageName) { // allow docker-java auth config to be used as a fallback AuthConfig fallbackAuthConfig; try { fallbackAuthConfig = delegate.effectiveAuthConfig(imageName); } catch (Exception e) { log.debug("Delegate call to effectiveAuthConfig failed with cause: '{}'. " + "Resolution of auth config will continue using RegistryAuthLocator.", e.getMessage()); fallbackAuthConfig = new AuthConfig(); } // try and obtain more accurate auth config using our resolution final DockerImageName parsed = new DockerImageName(imageName); final AuthConfig effectiveAuthConfig = RegistryAuthLocator.instance() .lookupAuthConfig(parsed, fallbackAuthConfig); log.debug("Effective auth config [{}]", toSafeString(effectiveAuthConfig)); return effectiveAuthConfig; }
@Nonnull public static DockerConfigFile loadConfig(@CheckForNull String dockerConfigPath) throws IOException { // no any configs, but for empty auths return non null object if (dockerConfigPath == null) { return new DockerConfigFile(); } //parse new docker config file format DockerConfigFile dockerConfig = loadCurrentConfig(dockerConfigPath); //parse old auth config file format if (dockerConfig == null) { dockerConfig = loadLegacyConfig(dockerConfigPath); } //otherwise create default config if (dockerConfig == null) { dockerConfig = new DockerConfigFile(); } for (Map.Entry<String, AuthConfig> entry : dockerConfig.getAuths().entrySet()) { AuthConfig authConfig = entry.getValue(); decodeAuth(authConfig); authConfig.withAuth(null); authConfig.withRegistryAddress(entry.getKey()); } return dockerConfig; }
private String name(PushImageCmd command) { String name = command.getName(); AuthConfig authConfig = command.getAuthConfig(); return (name.contains("/") || authConfig == null) ? name : authConfig.getUsername(); }
void addAuthConfig(AuthConfig config) { auths.put(config.getRegistryAddress(), config); }
/** * Push docker image using the docker java client. * * @param imageTag * @param username * @param password * @param host */ public static void pushImage(String imageTag, String username, String password, String host) throws IOException { final AuthConfig authConfig = new AuthConfig(); authConfig.withUsername(username); authConfig.withPassword(password); DockerClient dockerClient = null; try { dockerClient = getDockerClient(host); dockerClient.pushImageCmd(imageTag).withAuthConfig(authConfig).exec(new PushImageResultCallback()).awaitSuccess(); } finally { closeQuietly(dockerClient); } }
public static String toSafeString(AuthConfig authConfig) { if (authConfig == null) { return "null"; } return MoreObjects.toStringHelper(authConfig).add("username", authConfig.getUsername()).add("password", obfuscated(authConfig.getPassword())).add("auth", obfuscated(authConfig.getAuth())).add("email", authConfig.getEmail()).add("registryAddress", authConfig.getRegistryAddress()).add("registryToken", obfuscated(authConfig.getRegistrytoken())).toString(); }
private static void decodeAuth(AuthConfig config) throws IOException { if (config.getAuth() == null) { return; } String str = new String(Base64.decodeBase64(config.getAuth()), StandardCharsets.UTF_8); String[] parts = str.split(":", 2); if (parts.length != 2) { throw new IOException("Invalid auth configuration file"); } config.withUsername(parts[0]); config.withPassword(parts[1]); }
@CheckForNull private static DockerConfigFile loadLegacyConfig(String dockerConfigPath) throws IOException { File dockerLegacyCfgFile = new File(dockerConfigPath, DOCKER_LEGACY_CFG); if (!dockerLegacyCfgFile.exists() || !dockerLegacyCfgFile.isFile()) { return null; } //parse legacy auth config file format try { return new DockerConfigFile(MAPPER.<Map<String, AuthConfig>>readValue(dockerLegacyCfgFile, CONFIG_MAP_TYPE)); } catch (IOException e) { // pass } List<String> authFileContent = FileUtils.readLines(dockerLegacyCfgFile, StandardCharsets.UTF_8); if (authFileContent.size() < 2) { throw new IOException("The Auth Config file is empty"); } AuthConfig config = new AuthConfig(); String[] origAuth = authFileContent.get(0).split(" = "); if (origAuth.length != 2) { throw new IOException("Invalid Auth config file"); } config.withAuth(origAuth[1]); String[] origEmail = authFileContent.get(1).split(" = "); if (origEmail.length != 2) { throw new IOException("Invalid Auth config file"); } config.withEmail(origEmail[1]); return new DockerConfigFile(new HashMap<>(Collections.singletonMap(config.getRegistryAddress(), config))); }
public AuthConfig effectiveAuthConfig(String imageName) { // allow docker-java auth config to be used as a fallback AuthConfig fallbackAuthConfig; try { fallbackAuthConfig = delegate.effectiveAuthConfig(imageName); } catch (Exception e) { log.debug("Delegate call to effectiveAuthConfig failed with cause: \'{}\'. Resolution of auth config will continue using RegistryAuthLocator.", e.getMessage()); fallbackAuthConfig = new AuthConfig(); } // try and obtain more accurate auth config using our resolution final DockerImageName parsed = new DockerImageName(imageName); final AuthConfig effectiveAuthConfig = RegistryAuthLocator.instance().lookupAuthConfig(parsed, fallbackAuthConfig); log.debug("Effective auth config [{}]", toSafeString(effectiveAuthConfig)); return effectiveAuthConfig; }
@Nonnull public static DockerConfigFile loadConfig(@CheckForNull String dockerConfigPath) throws IOException { // no any configs, but for empty auths return non null object if (dockerConfigPath == null) { return new DockerConfigFile(); } //parse new docker config file format DockerConfigFile dockerConfig = loadCurrentConfig(dockerConfigPath); //parse old auth config file format if (dockerConfig == null) { dockerConfig = loadLegacyConfig(dockerConfigPath); } //otherwise create default config if (dockerConfig == null) { dockerConfig = new DockerConfigFile(); } for (Map.Entry<String, AuthConfig> entry : dockerConfig.getAuths().entrySet()) { AuthConfig authConfig = entry.getValue(); decodeAuth(authConfig); authConfig.withAuth(null); authConfig.withRegistryAddress(entry.getKey()); } return dockerConfig; }
private String name(PushImageCmd command) { String name = command.getName(); AuthConfig authConfig = command.getAuthConfig(); return (name.contains("/") || authConfig == null) ? name : authConfig.getUsername(); }