Generate Azure VM password on the fly
Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/180efdf7 Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/180efdf7 Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/180efdf7 Branch: refs/heads/master Commit: 180efdf799c3df627f5538aae0b9429fa173b935 Parents: cb55642 Author: Svetoslav Neykov <[email protected]> Authored: Wed Jul 12 08:08:54 2017 +0300 Committer: Svetoslav Neykov <[email protected]> Committed: Wed Jul 12 14:50:06 2017 +0300 ---------------------------------------------------------------------- .../arm/AzureComputeProviderMetadata.java | 5 +-- .../arm/compute/AzureComputeServiceAdapter.java | 11 ++++--- .../CreateResourcesThenCreateNodes.java | 15 +++++++++ .../azurecompute/arm/util/Passwords.java | 32 ++++++++++++++++++++ 4 files changed, 56 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds/blob/180efdf7/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java index 6a5c587..a866ffb 100644 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java @@ -94,8 +94,9 @@ public class AzureComputeProviderMetadata extends BaseProviderMetadata { properties.put(RESOURCENAME_PREFIX, "jclouds"); properties.put(RESOURCENAME_DELIMITER, "-"); properties.put(IMAGE_PUBLISHERS, "Canonical,RedHat"); - // Default credentials for all images - properties.put(IMAGE_LOGIN_USER, "jclouds:Password12345!"); + // Default credentials for all images, Azure doesn't accept root, admin; generate the password on the fly + properties.put(IMAGE_LOGIN_USER, "jclouds"); + // Azure allows for passwordless sudo only when using a public key to login to the machine properties.put(IMAGE_AUTHENTICATE_SUDO, "true"); properties.put(TEMPLATE, "imageNameMatches=UbuntuServer,osVersionMatches=1[456]\\.[01][04](\\.[0-9])?-LTS"); // Api versions used in each API http://git-wip-us.apache.org/repos/asf/jclouds/blob/180efdf7/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java index ccb748a..0a37d5d 100644 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java @@ -375,18 +375,19 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual private OSProfile createOsProfile(String computerName, Template template) { String defaultLoginUser = template.getImage().getDefaultCredentials().getUser(); - String defaultLoginPassword = template.getImage().getDefaultCredentials().getOptionalPassword().get(); String adminUsername = Objects.firstNonNull(template.getOptions().getLoginUser(), defaultLoginUser); - String adminPassword = Objects.firstNonNull(template.getOptions().getLoginPassword(), defaultLoginPassword); + // Password already generated in CreateResourcesThenCreateNodes (if not set by user) + String adminPassword = template.getOptions().getLoginPassword(); OSProfile.Builder builder = OSProfile.builder().adminUsername(adminUsername).adminPassword(adminPassword) .computerName(computerName); if (template.getOptions().getPublicKey() != null && OsFamily.WINDOWS != template.getImage().getOperatingSystem().getFamily()) { OSProfile.LinuxConfiguration linuxConfiguration = OSProfile.LinuxConfiguration.create("true", - OSProfile.LinuxConfiguration.SSH.create(of(OSProfile.LinuxConfiguration.SSH.SSHPublicKey - .create(String.format("/home/%s/.ssh/authorized_keys", adminUsername), template.getOptions() - .getPublicKey())))); + OSProfile.LinuxConfiguration.SSH.create(of( + OSProfile.LinuxConfiguration.SSH.SSHPublicKey.create( + String.format("/home/%s/.ssh/authorized_keys", adminUsername), + template.getOptions().getPublicKey())))); builder.linuxConfiguration(linuxConfiguration); } http://git-wip-us.apache.org/repos/asf/jclouds/blob/180efdf7/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/CreateResourcesThenCreateNodes.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/CreateResourcesThenCreateNodes.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/CreateResourcesThenCreateNodes.java index 2ddb340..e1d346c 100644 --- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/CreateResourcesThenCreateNodes.java +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/CreateResourcesThenCreateNodes.java @@ -34,6 +34,7 @@ import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; +import com.google.common.base.Optional; import org.jclouds.Constants; import org.jclouds.azurecompute.arm.AzureComputeApi; import org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndName; @@ -49,10 +50,12 @@ import org.jclouds.azurecompute.arm.domain.Subnet; import org.jclouds.azurecompute.arm.domain.Subnet.SubnetProperties; import org.jclouds.azurecompute.arm.domain.VirtualNetwork.AddressSpace; import org.jclouds.azurecompute.arm.domain.VirtualNetwork.VirtualNetworkProperties; +import org.jclouds.azurecompute.arm.util.Passwords; import org.jclouds.compute.config.CustomizationResponse; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.Template; import org.jclouds.compute.functions.GroupNamingConvention; +import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap; @@ -108,6 +111,9 @@ public class CreateResourcesThenCreateNodes extends CreateNodesWithGroupEncodedI Multimap<NodeMetadata, CustomizationResponse> customizationResponses) { AzureTemplateOptions options = template.getOptions().as(AzureTemplateOptions.class); + + // TODO Generate a private key instead. Also no need to use AUTHENTICATE_SUDO in this case. + generatePasswordIfNoneProvided(template); // If there is a script to be run on the node and public key // authentication has been configured, warn users if the private key @@ -130,6 +136,15 @@ public class CreateResourcesThenCreateNodes extends CreateNodesWithGroupEncodedI return super.execute(group, count, template, goodNodes, badNodes, customizationResponses); } + // Azure requires that we pass it the VM password. Need to generate one if not overridden by the user. + private void generatePasswordIfNoneProvided(Template template) { + TemplateOptions options = template.getOptions(); + if (options.getLoginPassword() == null) { + Optional<String> passwordOptional = template.getImage().getDefaultCredentials().getOptionalPassword(); + options.overrideLoginPassword(passwordOptional.or(Passwords.generate())); + } + } + protected synchronized void createDefaultNetworkIfNeeded(String group, String location, AzureTemplateOptions options) { if (options.getIpOptions().isEmpty()) { String name = namingConvention.create().sharedNameForGroup(group); http://git-wip-us.apache.org/repos/asf/jclouds/blob/180efdf7/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/util/Passwords.java ---------------------------------------------------------------------- diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/util/Passwords.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/util/Passwords.java new file mode 100644 index 0000000..9bc189e --- /dev/null +++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/util/Passwords.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.azurecompute.arm.util; + +import com.google.common.io.BaseEncoding; + +import java.util.Random; + +// Seems to be a common theme between providers, perhaps should be provided by core (see other 'Passwords' classes) +public class Passwords { + private static final Random random = new Random(); + + public static String generate() { + final byte[] buffer = new byte[15]; + random.nextBytes(buffer); + return BaseEncoding.base64Url().omitPadding().encode(buffer); + } +}
