Skip to content

Commit

Permalink
feat(fips): enable fips support auto provisioning flow (#1639)
Browse files Browse the repository at this point in the history
  • Loading branch information
yitingb authored Jul 23, 2024
1 parent fc4767c commit 865be65
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ public DeviceProvisioningHelper(String awsRegion, String environmentStage, Print
*/
public ThingInfo createThingForE2ETests() {
return createThing(iotClient, E2E_TESTS_POLICY_NAME_PREFIX,
E2E_TESTS_THING_NAME_PREFIX + UUID.randomUUID().toString());
E2E_TESTS_THING_NAME_PREFIX + UUID.randomUUID().toString(), "", "");
}

/**
Expand All @@ -180,9 +180,13 @@ public ThingInfo createThingForE2ETests() {
* @param client iotClient to use
* @param policyName policyName
* @param thingName thingName
* @param iotDataEndpoint iotDataEndpoint
* @param iotCredEndpoint iotCredEndpoint
* @return created thing info
*/
public ThingInfo createThing(IotClient client, String policyName, String thingName) {
@SuppressWarnings("PMD.UseObjectForClearerAPI")
public ThingInfo createThing(IotClient client, String policyName, String thingName,
String iotDataEndpoint, String iotCredEndpoint) {
// Find or create IoT policy
try {
client.getPolicy(GetPolicyRequest.builder().policyName(policyName).build());
Expand All @@ -199,6 +203,16 @@ public ThingInfo createThing(IotClient client, String policyName, String thingNa
.build());
}

// handle endpoints
if (Utils.isEmpty(iotDataEndpoint)) {
iotDataEndpoint = client.describeEndpoint(DescribeEndpointRequest.builder()
.endpointType("iot:Data-ATS").build()).endpointAddress();
}
if (Utils.isEmpty(iotCredEndpoint)) {
iotCredEndpoint = client.describeEndpoint(DescribeEndpointRequest.builder()
.endpointType("iot:CredentialProvider").build()).endpointAddress();
}

// Create cert
outStream.println("Creating keys and certificate...");
CreateKeysAndCertificateResponse keyResponse =
Expand All @@ -218,10 +232,7 @@ public ThingInfo createThing(IotClient client, String policyName, String thingNa
.build());

return new ThingInfo(thingArn, thingName, keyResponse.certificateArn(), keyResponse.certificateId(),
keyResponse.certificatePem(), keyResponse.keyPair(),
client.describeEndpoint(DescribeEndpointRequest.builder().endpointType("iot:Data-ATS").build())
.endpointAddress(), client.describeEndpoint(
DescribeEndpointRequest.builder().endpointType("iot:CredentialProvider").build()).endpointAddress());
keyResponse.certificatePem(), keyResponse.keyPair(), iotDataEndpoint, iotCredEndpoint);
}

/**
Expand Down
18 changes: 15 additions & 3 deletions src/main/java/com/aws/greengrass/easysetup/GreengrassSetup.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,13 @@
import java.util.List;
import java.util.UUID;

import static com.aws.greengrass.componentmanager.KernelConfigResolver.CONFIGURATION_CONFIG_KEY;
import static com.aws.greengrass.deployment.DeviceConfiguration.DEFAULT_NUCLEUS_COMPONENT_NAME;
import static com.aws.greengrass.deployment.DeviceConfiguration.DEVICE_PARAM_IOT_CRED_ENDPOINT;
import static com.aws.greengrass.deployment.DeviceConfiguration.DEVICE_PARAM_IOT_DATA_ENDPOINT;
import static com.aws.greengrass.easysetup.DeviceProvisioningHelper.ThingInfo;
import static com.aws.greengrass.lifecyclemanager.GreengrassService.SERVICES_NAMESPACE_TOPIC;


/**
* Easy setup for getting started with Greengrass kernel on a device.
Expand Down Expand Up @@ -510,9 +516,15 @@ private String peekArg() {

void provision(Kernel kernel) throws IOException, DeviceConfigurationException {
outStream.printf("Provisioning AWS IoT resources for the device with IoT Thing Name: [%s]...%n", thingName);
final ThingInfo thingInfo =
deviceProvisioningHelper.createThing(deviceProvisioningHelper.getIotClient(), thingPolicyName,
thingName);
// handle endpoints provided by external config
String iotDataEndpoint = Coerce.toString(kernel.getConfig().find(SERVICES_NAMESPACE_TOPIC,
DEFAULT_NUCLEUS_COMPONENT_NAME, CONFIGURATION_CONFIG_KEY, DEVICE_PARAM_IOT_DATA_ENDPOINT));
String iotCredEndpoint = Coerce.toString(kernel.getConfig().find(SERVICES_NAMESPACE_TOPIC,
DEFAULT_NUCLEUS_COMPONENT_NAME, CONFIGURATION_CONFIG_KEY, DEVICE_PARAM_IOT_CRED_ENDPOINT));

final ThingInfo thingInfo = deviceProvisioningHelper.createThing(deviceProvisioningHelper.getIotClient(),
thingPolicyName, thingName, iotDataEndpoint, iotCredEndpoint);

outStream.printf("Successfully provisioned AWS IoT resources for the device with IoT Thing Name: [%s]!%n",
thingName);
if (!Utils.isEmpty(thingGroupName)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
import static com.aws.greengrass.componentmanager.KernelConfigResolver.CONFIGURATION_CONFIG_KEY;
import static com.aws.greengrass.deployment.DeviceConfiguration.DEFAULT_NUCLEUS_COMPONENT_NAME;
import static com.aws.greengrass.deployment.DeviceConfiguration.DEVICE_PARAM_THING_NAME;
import static com.aws.greengrass.deployment.DeviceConfiguration.DEVICE_PARAM_IOT_DATA_ENDPOINT;
import static com.aws.greengrass.deployment.DeviceConfiguration.IOT_ROLE_ALIAS_TOPIC;
import static com.aws.greengrass.deployment.DeviceConfiguration.SYSTEM_NAMESPACE_KEY;
import static com.aws.greengrass.lifecyclemanager.GreengrassService.SERVICES_NAMESPACE_TOPIC;
Expand Down Expand Up @@ -148,7 +149,7 @@ void GIVEN_test_create_thing_WHEN_thing_policy_exists_THEN_use_existing_thing_po
.thenReturn(createKeysAndCertificateResponse);
when(iotClient.createThing(any(CreateThingRequest.class))).thenReturn(createThingResponse);
when(iotClient.describeEndpoint(any(DescribeEndpointRequest.class))).thenReturn(describeEndpointResponse);
deviceProvisioningHelper.createThing(iotClient, "TestThingPolicy", "TestThing");
deviceProvisioningHelper.createThing(iotClient, "TestThingPolicy", "TestThing", "", "");
verify(iotClient, times(0)).createPolicy(any(CreatePolicyRequest.class));
}

Expand All @@ -159,7 +160,7 @@ void GIVEN_test_create_thing_WHEN_thing_policy_doesnt_exist_THEN_create_thing_po
.thenReturn(createKeysAndCertificateResponse);
when(iotClient.createThing(any(CreateThingRequest.class))).thenReturn(createThingResponse);
when(iotClient.describeEndpoint(any(DescribeEndpointRequest.class))).thenReturn(describeEndpointResponse);
deviceProvisioningHelper.createThing(iotClient, "TestThingPolicy", "TestThing");
deviceProvisioningHelper.createThing(iotClient, "TestThingPolicy", "TestThing", "", "");
verify(iotClient, times(1)).createPolicy(any(CreatePolicyRequest.class));
}

Expand Down Expand Up @@ -483,4 +484,23 @@ void GIVEN_iot_client_factory_WHEN_test_get_iot_client_THEN_client_is_built_with
assertNotNull(IotSdkClientFactory.getIotClient(TEST_REGION, IotSdkClientFactory.EnvironmentStage.PROD,
Collections.singleton(Exception.class)));
}

@Test
void GIVEN_endpoints_provided_WHEN_create_thing_THEN_deviceConfig_contains_provided_endpoint() throws Exception {
when(iotClient.getPolicy(any(GetPolicyRequest.class))).thenReturn(getPolicyResponse);
when(iotClient.createKeysAndCertificate(any(CreateKeysAndCertificateRequest.class)))
.thenReturn(createKeysAndCertificateResponse);
when(iotClient.createThing(any(CreateThingRequest.class))).thenReturn(createThingResponse);
when(iotClient.describeEndpoint(any(DescribeEndpointRequest.class))).thenReturn(describeEndpointResponse);
when(createKeysAndCertificateResponse.keyPair()).thenReturn(KeyPair.builder().privateKey("privateKey").publicKey("publicKey").build());
when(createKeysAndCertificateResponse.certificatePem()).thenReturn("certPem");
when(describeEndpointResponse.endpointAddress()).thenReturn("c2ek3s7ppzzhur.credentials.iot.us-east-1.amazonaws.com");
kernel = new Kernel()
.parseArgs("-i", getClass().getResource("blank_config.yaml").toString(), "-r", tempRootDir.toString());
DeviceProvisioningHelper.ThingInfo thingInfo = deviceProvisioningHelper.createThing(iotClient, "TestThingPolicy", "TestThing", "mockEndpoint", "");

deviceProvisioningHelper.updateKernelConfigWithIotConfiguration(kernel, thingInfo, "us-east-1", "TestRoleAliasName", "TestCertPath");
assertEquals("mockEndpoint", kernel.getConfig().lookup(SERVICES_NAMESPACE_TOPIC,
DEFAULT_NUCLEUS_COMPONENT_NAME, CONFIGURATION_CONFIG_KEY, DEVICE_PARAM_IOT_DATA_ENDPOINT).getOnce());
}
}
20 changes: 10 additions & 10 deletions src/test/java/com/aws/greengrass/easysetup/GreengrassSetupTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ void cleanup() throws IOException {

@Test
void GIVEN_setup_script_WHEN_script_is_used_THEN_setup_actions_are_performed() throws Exception {
when(deviceProvisioningHelper.createThing(any(), any(), any())).thenReturn(thingInfo);
when(deviceProvisioningHelper.createThing(any(), any(), any(), any(), any())).thenReturn(thingInfo);
greengrassSetup =
new GreengrassSetup(System.out, System.err, deviceProvisioningHelper, platform, kernel, "--config",
"mock_config_path", "--root", "mock_root", "--thing-name", "mock_thing_name",
Expand All @@ -103,7 +103,7 @@ void GIVEN_setup_script_WHEN_script_is_used_THEN_setup_actions_are_performed() t
greengrassSetup.parseArgs();
greengrassSetup.setDeviceProvisioningHelper(deviceProvisioningHelper);
greengrassSetup.provision(kernel);
verify(deviceProvisioningHelper, times(1)).createThing(any(), any(), any());
verify(deviceProvisioningHelper, times(1)).createThing(any(), any(), any(), any(), any());
verify(deviceProvisioningHelper, times(1)).addThingToGroup(any(), any(), any());
verify(deviceProvisioningHelper, times(1)).updateKernelConfigWithIotConfiguration(any(), any(), any(), any(), any());
verify(deviceProvisioningHelper, times(1)).setupIoTRoleForTes(any(), any(), any());
Expand All @@ -113,7 +113,7 @@ void GIVEN_setup_script_WHEN_script_is_used_THEN_setup_actions_are_performed() t
@ParameterizedTest
@CsvSource({"--cert-path,/a/b"})
void GIVEN_setup_script_WHEN_script_is_used_THEN_setup_actions_are_performed_for_cert_path_specified(String certOption, String certPath) throws Exception {
when(deviceProvisioningHelper.createThing(any(), any(), any())).thenReturn(thingInfo);
when(deviceProvisioningHelper.createThing(any(), any(), any(), any(), any())).thenReturn(thingInfo);
greengrassSetup =
new GreengrassSetup(System.out, System.err, deviceProvisioningHelper, platform, kernel, "--config",
"mock_config_path", "--root", "mock_root", "--thing-name", "mock_thing_name",
Expand All @@ -129,7 +129,7 @@ void GIVEN_setup_script_WHEN_script_is_used_THEN_setup_actions_are_performed_for

@Test
void GIVEN_setup_script_WHEN_script_is_used_THEN_setup_actions_are_performed_for_cert_path_not_specified() throws Exception {
when(deviceProvisioningHelper.createThing(any(), any(), any())).thenReturn(thingInfo);
when(deviceProvisioningHelper.createThing(any(), any(), any(), any(), any())).thenReturn(thingInfo);
greengrassSetup =
new GreengrassSetup(System.out, System.err, deviceProvisioningHelper, platform, kernel, "--config",
"mock_config_path", "--root", "mock_root", "--thing-name", "mock_thing_name",
Expand Down Expand Up @@ -385,31 +385,31 @@ void GIVEN_setup_script_WHEN_no_region_arg_provided_but_region_in_config_THEN_pr

@Test
void GIVEN_setup_script_WHEN_no_thing_policy_name_args_provided_THEN_policy_setup_with_default() throws Exception {
when(deviceProvisioningHelper.createThing(any(), any(), any())).thenReturn(thingInfo);
when(deviceProvisioningHelper.createThing(any(), any(), any(), any(), any())).thenReturn(thingInfo);
greengrassSetup =
new GreengrassSetup(System.out, System.err, deviceProvisioningHelper, platform, kernel, "--config",
"mock_config_path", "--root", "mock_root", "--thing-name", "mock_thing_name",
"-trn", "mock_tes_role_name", "--provision", "y", "--aws-region", "us-east-1", "-ss", "false");
greengrassSetup.parseArgs();
greengrassSetup.setDeviceProvisioningHelper(deviceProvisioningHelper);
greengrassSetup.provision(kernel);
verify(deviceProvisioningHelper, times(1)).createThing(any(), any(), any());
verify(deviceProvisioningHelper, times(1)).createThing(any(), any(), any(), any(), any());
verify(deviceProvisioningHelper, times(1)).updateKernelConfigWithIotConfiguration(any(), any(), any(), any(), any());
verify(deviceProvisioningHelper, times(1)).setupIoTRoleForTes(any(), any(), any());
verify(deviceProvisioningHelper, times(1)).createAndAttachRolePolicy(any(), any());
}

@Test
void GIVEN_setup_script_WHEN_no_tes_role_args_provided_THEN_tes_setup_with_default() throws Exception {
when(deviceProvisioningHelper.createThing(any(), any(), any())).thenReturn(thingInfo);
when(deviceProvisioningHelper.createThing(any(), any(), any(), any(), any())).thenReturn(thingInfo);
greengrassSetup =
new GreengrassSetup(System.out, System.err, deviceProvisioningHelper, platform, kernel, "--config",
"mock_config_path", "--root", "mock_root", "--thing-name", "mock_thing_name", "--provision",
"y", "--aws-region", "us-east-1", "-ss", "false");
greengrassSetup.parseArgs();
greengrassSetup.setDeviceProvisioningHelper(deviceProvisioningHelper);
greengrassSetup.provision(kernel);
verify(deviceProvisioningHelper, times(1)).createThing(any(), any(), any());
verify(deviceProvisioningHelper, times(1)).createThing(any(), any(), any(), any(), any());
verify(deviceProvisioningHelper, times(1)).updateKernelConfigWithIotConfiguration(any(), any(), any(), any(), any());
verify(deviceProvisioningHelper, times(1)).setupIoTRoleForTes(any(), any(), any());
verify(deviceProvisioningHelper, times(1)).createAndAttachRolePolicy(any(), any());
Expand All @@ -418,15 +418,15 @@ void GIVEN_setup_script_WHEN_no_tes_role_args_provided_THEN_tes_setup_with_defau
@Test
void GIVEN_setup_script_WHEN_script_is_used_with_short_arg_notations_THEN_setup_actions_are_performed()
throws Exception {
when(deviceProvisioningHelper.createThing(any(), any(), any())).thenReturn(thingInfo);
when(deviceProvisioningHelper.createThing(any(), any(), any(), any(), any())).thenReturn(thingInfo);
greengrassSetup = new GreengrassSetup(System.out, System.err, deviceProvisioningHelper, platform, kernel, "-i",
"mock_config_path", "-r", "mock_root", "-tn", "mock_thing_name", "-tgn", "mock_thing_group_name",
"-trn", "mock_tes_role_name", "-tra", "mock_tes_role_alias_name", "-p", "y", "-ar", "us-east-1", "-ss",
"false");
greengrassSetup.parseArgs();
greengrassSetup.setDeviceProvisioningHelper(deviceProvisioningHelper);
greengrassSetup.provision(kernel);
verify(deviceProvisioningHelper, times(1)).createThing(any(), any(), any());
verify(deviceProvisioningHelper, times(1)).createThing(any(), any(), any(), any(), any());
verify(deviceProvisioningHelper, times(1)).addThingToGroup(any(), any(), any());
verify(deviceProvisioningHelper, times(1)).updateKernelConfigWithIotConfiguration(any(), any(), any(), any(), any());
verify(deviceProvisioningHelper, times(1)).setupIoTRoleForTes(any(), any(), any());
Expand Down

0 comments on commit 865be65

Please sign in to comment.