diff --git a/source/packages/services/greengrass2-provisioning/README.md b/source/packages/services/greengrass2-provisioning/README.md index 8af86450d..12716a511 100644 --- a/source/packages/services/greengrass2-provisioning/README.md +++ b/source/packages/services/greengrass2-provisioning/README.md @@ -228,6 +228,15 @@ A template is what defines what components should be deployed to a Greengrass2 c Replace `` with the name of the template. +**NOTE: The template name is used as part of creating a thing group name, thing group applies limitation on how the name can be defined. Refer to the points below for quick reference and refer to the link on the thing group naming convention from the developer document** +[Thing Group Developer Document](https://docs.aws.amazon.com/iot/latest/developerguide/thing-groups.html) + +``` +- Thing group names can't contain international characters, such as û, é and ñ. +- You should not use personally identifiable information in your thing group name. The thing group name can appear in unencrypted communications and reports. +- You should not use a colon character ( : ) in a thing group name. The colon character is used as a delimiter by other AWS IoT services and this can cause them to parse strings with thing group names incorrectly. +``` + #### Request ```sh diff --git a/source/packages/services/greengrass2-provisioning/src/deployments/deployments.service.ts b/source/packages/services/greengrass2-provisioning/src/deployments/deployments.service.ts index 32cdcb907..9e4c9bb31 100644 --- a/source/packages/services/greengrass2-provisioning/src/deployments/deployments.service.ts +++ b/source/packages/services/greengrass2-provisioning/src/deployments/deployments.service.ts @@ -52,35 +52,6 @@ export class DeploymentsService { this.ggv2 = ggv2Factory(); } - // public async get(name:string): Promise { - // logger.debug(`deployments.service get: in: name:${name}`); - - // ow(name, ow.string.nonEmpty); - - // const coreFuture = this.coresDao.get(name); - // const installedComponentsFuture = this.ggv2.send( - // new ListInstalledComponentsCommand({ - // coreDeviceThingName: name - // // TODO: manage pagination of installed components - // })); - // const [core, components] = await Promise.all([coreFuture, installedComponentsFuture]); - // logger.silly(`deployments.service get: components:${JSON.stringify(components)}`); - - // core.installedComponents= []; - // if ((components.installedComponents?.length??0)>0) { - // for (const c of components.installedComponents) { - // core.installedComponents.push({ - // key: c.componentName, - // version: c.componentVersion - // // TODO: determine whether installed component matches what is on template or not - // }) - // } - // } - - // logger.debug(`deployments.service get: exit: ${JSON.stringify(core)}`); - // return core; - // } - public async createDeployments(taskId: string, deployments: NewDeployment[]): Promise { logger.debug(`deployments.service createDeployments: in: taskId:${taskId}, deployments: ${JSON.stringify(deployments)}`); @@ -147,6 +118,7 @@ export class DeploymentsService { try { await this.ggv2.send(new GetCoreDeviceCommand({ coreDeviceThingName: deployment.coreName })); } catch (e) { + logger.error(`deployments.service createDeployment: error: ${JSON.stringify(e)}`); if (e.name === 'ResourceNotFoundException') { this.markAsFailed(deployment, 'Core device not registered with Greengrass V2'); } else { @@ -181,6 +153,7 @@ export class DeploymentsService { logger.silly(`deployments.service createDeployment: CreateThingGroupCommandOutput: ${JSON.stringify(r)}`); thingGroupArn = r.thingGroupArn; } catch (e) { + logger.error(`deployments.service createDeployment: error: ${JSON.stringify(e)}`); if (e.name === 'ResourceAlreadyExistsException') { logger.warn(`deployments.service createDeployment: thingGroup: ${thingGroupName} already exists`); const r = await this.iot.send(new DescribeThingGroupCommand({ thingGroupName })); @@ -228,6 +201,7 @@ export class DeploymentsService { logger.silly(`deployments.service createDeployment: TagResourceCommandOutput: ${JSON.stringify(tagResourceOutput)}`); } catch (e) { + logger.error(`deployments.service createDeployment: error: ${JSON.stringify(e)}`); this.markAsFailed(deployment, `Failed to create deployment: ${e.name}`); } } @@ -237,6 +211,7 @@ export class DeploymentsService { try { await this.templatesService.associateDeployment(template) } catch (e) { + logger.error(`deployments.service createDeployment: error: ${JSON.stringify(e)}`); this.markAsFailed(deployment, `Failed to associate deployment with template: ${e.name}`); } } @@ -272,6 +247,7 @@ export class DeploymentsService { thingGroupName: template.deployment.thingGroupName })); } catch (e) { + logger.error(`deployments.service createDeployment: error: ${JSON.stringify(e)}`); this.markAsFailed(deployment, `Failed to add core device to deployment thing group target: ${e.name}`); } } diff --git a/source/packages/services/installer/CHANGELOG.json b/source/packages/services/installer/CHANGELOG.json index c3258b458..803fece3e 100644 --- a/source/packages/services/installer/CHANGELOG.json +++ b/source/packages/services/installer/CHANGELOG.json @@ -1,6 +1,18 @@ { "name": "@cdf/installer", "entries": [ + { + "version": "1.3.1", + "tag": "@cdf/installer_v1.3.1", + "date": "Thu, 04 Aug 2022 18:39:36 GMT", + "comments": { + "patch": [ + { + "comment": "fix installer issue when specifying PCA alias" + } + ] + } + }, { "version": "1.3.0", "tag": "@cdf/installer_v1.3.0", diff --git a/source/packages/services/installer/CHANGELOG.md b/source/packages/services/installer/CHANGELOG.md index 4d321bd7f..cb3b74652 100644 --- a/source/packages/services/installer/CHANGELOG.md +++ b/source/packages/services/installer/CHANGELOG.md @@ -1,6 +1,13 @@ # Change Log - @cdf/installer -This log was last generated on Fri, 29 Jul 2022 02:59:14 GMT and should not be manually modified. +This log was last generated on Thu, 04 Aug 2022 18:39:36 GMT and should not be manually modified. + +## 1.3.1 +Thu, 04 Aug 2022 18:39:36 GMT + +### Patches + +- fix installer issue when specifying PCA alias ## 1.3.0 Fri, 29 Jul 2022 02:59:14 GMT diff --git a/source/packages/services/installer/package.json b/source/packages/services/installer/package.json index dde4d7690..5620e34c9 100644 --- a/source/packages/services/installer/package.json +++ b/source/packages/services/installer/package.json @@ -1,6 +1,6 @@ { "name": "@cdf/installer", - "version": "1.3.0", + "version": "1.3.1", "description": "CDF install wizard.", "author": "Dean Hart", "scripts": { diff --git a/source/packages/services/installer/src/commands/modules/service/provisioning.ts b/source/packages/services/installer/src/commands/modules/service/provisioning.ts index a5fe16d36..ca69e4f98 100644 --- a/source/packages/services/installer/src/commands/modules/service/provisioning.ts +++ b/source/packages/services/installer/src/commands/modules/service/provisioning.ts @@ -116,69 +116,78 @@ export class ProvisioningInstaller implements RestModule { }, }], updatedAnswers); - updatedAnswers = await inquirer.prompt([{ - message: `Create or modify AWS IoT CA alias list ?`, - type: 'confirm', - name: 'provisioning.setIotCaAliases', - default: answers.provisioning?.setIotCaAliases ?? true, - askAnswered: true, - when(answers: Answers) { - return answers.provisioning?.pcaIntegrationEnabled; - } - }],updatedAnswers); - - //Collect the IoT CA List - let iotCaFinished = false; - if(answers.provisioning.setIotCaAliases){ - while (!iotCaFinished){ - const iotCaAliases = await this.getIotCaAliases(updatedAnswers); - updatedAnswers.provisioning.iotCaAliases = iotCaAliases; - updatedAnswers = await inquirer.prompt([..._.getIoTCAPrompt(answers,iotCaAliases)],updatedAnswers); - // Update the iotCaAlias to upper case + updatedAnswers = await inquirer.prompt([{ + message: `Create or modify AWS IoT CA alias list ?`, + type: 'confirm', + name: 'provisioning.setIotCaAliases', + default: answers.provisioning?.setIotCaAliases ?? true, + askAnswered: true, + when(answers: Answers) { + return answers.provisioning?.pcaIntegrationEnabled; + } + }], updatedAnswers); + + //Collect the IoT CA List + let iotCaFinished = false; + if (updatedAnswers.provisioning?.setIotCaAliases) { + while (!iotCaFinished) { + const iotCaAliases = await this.getIotCaAliases(updatedAnswers); + updatedAnswers.provisioning.iotCaAliases = iotCaAliases; + updatedAnswers = await inquirer.prompt([..._.getIoTCAPrompt(answers, iotCaAliases)], updatedAnswers); + // Update the iotCaAlias to upper case + if (updatedAnswers.provisioning.iotCaAlias === undefined) { + updatedAnswers.provisioning.iotCaFinished = true + } else { updatedAnswers.provisioning.iotCaAlias = updatedAnswers.provisioning.iotCaAlias.toUpperCase(); - if (!updatedAnswers.provisioning.iotCaAliases.list.includes(updatedAnswers.provisioning.iotCaAlias)){ - const alias = updatedAnswers.provisioning.iotCaAlias; + if (!updatedAnswers.provisioning.iotCaAliases.list.includes(updatedAnswers.provisioning.iotCaAlias)) { + const alias = updatedAnswers.provisioning.iotCaAlias; const value = updatedAnswers.provisioning.iotCaArn; - updatedAnswers.provisioning.iotCaAliases.cas.push({alias, value}); + updatedAnswers.provisioning.iotCaAliases.cas.push({ alias, value }); + updatedAnswers.provisioning.iotCaAliases.list.push(alias); } - iotCaFinished = answers.provisioning.iotCaFinished; } + + iotCaFinished = updatedAnswers.provisioning.iotCaFinished; } + } - updatedAnswers = await inquirer.prompt([{ - message: `Create or modify ACM PCA CA alias list ?`, - type: 'confirm', - name: 'provisioning.setPcaAliases', - default: answers.provisioning?.setPcaAliases ?? true, - askAnswered: true, - when(answers: Answers) { - return answers.provisioning?.pcaIntegrationEnabled; - }, - }],updatedAnswers); - - //Collect the ACM PCA List - let pcaFinished = false; - if(answers.provisioning.setPcaAliases){ - while (!pcaFinished){ - const pcaAliases = await this.getPcaAliases(updatedAnswers); - updatedAnswers.provisioning.pcaAliases = pcaAliases; - updatedAnswers = await inquirer.prompt([..._.getPCAPrompt(answers,pcaAliases)],updatedAnswers); - + updatedAnswers = await inquirer.prompt([{ + message: `Create or modify ACM PCA CA alias list ?`, + type: 'confirm', + name: 'provisioning.setPcaAliases', + default: answers.provisioning?.setPcaAliases ?? true, + askAnswered: true, + when(answers: Answers) { + return answers.provisioning?.pcaIntegrationEnabled; + }, + }], updatedAnswers); + + //Collect the ACM PCA List + let pcaFinished = false; + if (updatedAnswers.provisioning?.setPcaAliases) { + while (!pcaFinished) { + const pcaAliases = await this.getPcaAliases(updatedAnswers); + updatedAnswers.provisioning.pcaAliases = pcaAliases; + updatedAnswers = await inquirer.prompt([..._.getPCAPrompt(answers, pcaAliases)], updatedAnswers); + if (updatedAnswers.provisioning.pcaAlias === undefined) { + updatedAnswers.provisioning.pcaFinished = true + } else { // Update the pcaAlias to upper case to be stored in the installer config updatedAnswers.provisioning.pcaAlias = updatedAnswers.provisioning.pcaAlias.toUpperCase(); - if (!updatedAnswers.provisioning.pcaAliases.list.includes(updatedAnswers.provisioning.pcaAlias)){ - const alias = updatedAnswers.provisioning.pcaAlias; + if (!updatedAnswers.provisioning.pcaAliases.list.includes(updatedAnswers.provisioning.pcaAlias)) { + const alias = updatedAnswers.provisioning.pcaAlias; const value = updatedAnswers.provisioning.pcaArn; - updatedAnswers.provisioning.pcaAliases.cas.push({alias, value}); + updatedAnswers.provisioning.pcaAliases.cas.push({ alias, value }); + updatedAnswers.provisioning.pcaAliases.list.push(alias); } - pcaFinished = answers.provisioning.pcaFinished; - } + pcaFinished = updatedAnswers.provisioning.pcaFinished; } + } - updatedAnswers = await inquirer.prompt([ - ...customDomainPrompt(this.name, answers), - ...applicationConfigurationPrompt(this.name, answers, [ + updatedAnswers = await inquirer.prompt([ + ...customDomainPrompt(this.name, answers), + ...applicationConfigurationPrompt(this.name, answers, [ { question: 'Allow service to delete AWS IoT Certificates ?', defaultConfiguration: false, @@ -209,8 +218,8 @@ export class ProvisioningInstaller implements RestModule { defaultConfiguration: 'bullkrequests/', propertyName: 'bulkRequestsPrefix', } - ])],updatedAnswers); - + ])], updatedAnswers); + return updatedAnswers; @@ -331,7 +340,7 @@ export class ProvisioningInstaller implements RestModule { if (!pca.alias.startsWith('PCA_')) { alias = `PCA_${pca.alias.toUpperCase()}`; } - + configBuilder.add(alias, pca.value); }); @@ -346,8 +355,8 @@ export class ProvisioningInstaller implements RestModule { configBuilder.add(alias, ca.value); }); - if ((answers?.provisioning?.pcaRegion?.length??0) > 0){ - configBuilder.add(`ACM_REGION`,answers.provisioning.pcaRegion); + if ((answers?.provisioning?.pcaRegion?.length ?? 0) > 0) { + configBuilder.add(`ACM_REGION`, answers.provisioning.pcaRegion); } configBuilder @@ -387,7 +396,7 @@ export class ProvisioningInstaller implements RestModule { } try { // append lambda ACM PCA Config to list if none are present in the configuration file - if (aliases.list.length == 0 ){ + if (aliases.list.length == 0) { const config = await lambda.getFunctionConfiguration({ FunctionName: `cdf-provisioning-rest-${answers.environment}` }); const variables = config.Environment?.Variables; const appConfigStr = variables['APP_CONFIG'] as string; @@ -402,7 +411,7 @@ export class ProvisioningInstaller implements RestModule { } } }); - } + } } catch (e) { e.name === 'ResourceNotFoundException' && console.log(`No suppliers found`); } @@ -426,7 +435,7 @@ export class ProvisioningInstaller implements RestModule { // append lambda IoT CA list if none are present in the configuration file try { - if (aliases.list.length == 0 ){ + if (aliases.list.length == 0) { const config = await lambda.getFunctionConfiguration({ FunctionName: `cdf-provisioning-rest-${answers.environment}` }); const variables = config.Environment?.Variables; const appConfigStr = variables['APP_CONFIG'] as string; @@ -441,7 +450,7 @@ export class ProvisioningInstaller implements RestModule { } } }); - } + } } catch (e) { e.name === 'ResourceNotFoundException' && console.log(`No suppliers found`); } @@ -452,23 +461,23 @@ export class ProvisioningInstaller implements RestModule { } - private validateAcmPcaArn(arn: string): boolean |string { + private validateAcmPcaArn(arn: string): boolean | string { return (/^arn:aws:acm-pca:\w+(?:-\w+)+:\d{12}:certificate-authority\/[A-Za-z0-9]+(?:-[A-Za-z0-9]+)+$/.test(arn)) ? true : "Value is not a valid ACM PCA Arn"; } - private validateAwsIotCaArn(arn: string): boolean|string { - return (/^arn:aws:iot:\w+(?:-\w+)+:\d{12}:cacert\/[A-Za-z0-9]+(?:[A-Za-z0-9]+)+$/.test(arn)) ? true : "Value is not a valid AWS IoT CA Arn"; + private validateAwsIotCaArn(arn: string): boolean | string { + return (/^arn:aws:iot:\w+(?:-\w+)+:\d{12}:cacert\/[A-Za-z0-9]+(?:[A-Za-z0-9]+)+$/.test(arn)) ? true : "Value is not a valid AWS IoT CA Arn"; } - private validateAwsIAMRoleArn(arn: string): boolean|string { - return (/^arn:aws:iam::\d{12}:role\/[A-Za-z0-9]+(?:[A-Za-z0-9_-]+)+$/.test(arn)) ? true : "Value is not a valid IAM Role Arn"; + private validateAwsIAMRoleArn(arn: string): boolean | string { + return (/^arn:aws:iam::\d{12}:role\/[A-Za-z0-9]+(?:[A-Za-z0-9_-]+)+$/.test(arn)) ? true : "Value is not a valid IAM Role Arn"; } - private getPCAPrompt( answers: Answers,pcaAliases:CAAliases): Question[]{ + private getPCAPrompt(answers: Answers, pcaAliases: CAAliases): Question[] { // eslint-disable-next-line const _ = this; - const questions = [ { + const questions = [{ message: 'Select the ACM PCA aliases you wish to modify', type: 'list', name: 'provisioning.pcaAlias', @@ -536,14 +545,14 @@ export class ProvisioningInstaller implements RestModule { return answers.provisioning?.setPcaAliases === true; }, } - ]; + ]; return questions; } - private getIoTCAPrompt( answers: Answers,iotCaAliases:CAAliases): Question[]{ + private getIoTCAPrompt(answers: Answers, iotCaAliases: CAAliases): Question[] { // eslint-disable-next-line - const _ =this; - const questions = [ + const _ = this; + const questions = [ { message: 'Select the AWS IoT CA aliases you wish to modify', type: 'list', @@ -612,7 +621,7 @@ export class ProvisioningInstaller implements RestModule { return answers.provisioning?.setIotCaAliases === true; }, } - ]; + ]; return questions; } } diff --git a/source/packages/services/provisioning/CHANGELOG.json b/source/packages/services/provisioning/CHANGELOG.json index 7f3bb950f..0a9ab1208 100644 --- a/source/packages/services/provisioning/CHANGELOG.json +++ b/source/packages/services/provisioning/CHANGELOG.json @@ -1,6 +1,18 @@ { "name": "@cdf/provisioning", "entries": [ + { + "version": "5.3.3", + "tag": "@cdf/provisioning_v5.3.3", + "date": "Thu, 04 Aug 2022 18:39:36 GMT", + "comments": { + "patch": [ + { + "comment": "fix small typo in documentation" + } + ] + } + }, { "version": "5.3.2", "tag": "@cdf/provisioning_v5.3.2", diff --git a/source/packages/services/provisioning/CHANGELOG.md b/source/packages/services/provisioning/CHANGELOG.md index 274e7b6e8..66a1bb0fb 100644 --- a/source/packages/services/provisioning/CHANGELOG.md +++ b/source/packages/services/provisioning/CHANGELOG.md @@ -1,6 +1,13 @@ # Change Log - @cdf/provisioning -This log was last generated on Thu, 21 Jul 2022 21:10:03 GMT and should not be manually modified. +This log was last generated on Thu, 04 Aug 2022 18:39:36 GMT and should not be manually modified. + +## 5.3.3 +Thu, 04 Aug 2022 18:39:36 GMT + +### Patches + +- fix small typo in documentation ## 5.3.2 Thu, 21 Jul 2022 21:10:03 GMT diff --git a/source/packages/services/provisioning/docs/provisioning-templates.md b/source/packages/services/provisioning/docs/provisioning-templates.md index 29c68e5f4..990ba5aff 100644 --- a/source/packages/services/provisioning/docs/provisioning-templates.md +++ b/source/packages/services/provisioning/docs/provisioning-templates.md @@ -221,7 +221,7 @@ Specify names of existing policies, or name and definition of new policies to cr ### `$.CDF.useACMPCA` -If `$.CDF.useACMPCA` is provied with a value of `REGISTER_WITH_CA` or `REGISTER_WITHOUT_CA`, ACM PCA is used to issue a device certificate which is then registered within AWS IoT. Refer to [ACM Private CA Integration](./acmpca-integration.md) for further details. +If `$.CDF.useACMPCA` is provided with a value of `REGISTER_WITH_CA` or `REGISTER_WITHOUT_CA`, ACM PCA is used to issue a device certificate which is then registered within AWS IoT. Refer to [ACM Private CA Integration](./acmpca-integration.md) for further details. When `REGISTER_WITH_CA` is provided, the device certificate will be registered and signed using a custom registered CA that represents the ACM PCA CA. If instead `REGISTER_WITHOUT_CA` then the device certificate is registered without using a CA. diff --git a/source/packages/services/provisioning/package.json b/source/packages/services/provisioning/package.json index a12fee70f..b19cd6434 100644 --- a/source/packages/services/provisioning/package.json +++ b/source/packages/services/provisioning/package.json @@ -1,6 +1,6 @@ { "name": "@cdf/provisioning", - "version": "5.3.2", + "version": "5.3.3", "description": "CDF Provisioning", "author": "Dean Hart", "scripts": {