英文:
AWS GoLang SDK Version 2 and iot core Fleet Provisioning
问题
我正在尝试使用AWS GoLang SDK版本2(https://github.com/aws/aws-sdk-go-v2)来实现Linux设备的Fleet Provisioning。
我编写了以下代码,成功创建了通用声明凭证。现在我想要实现在设备上进行的Fleet Provisioning流程,以便将通用声明交换为每个设备的唯一凭证。在AWS Python SDK示例中展示了这个流程--> https://github.com/aws/aws-iot-device-sdk-python-v2/blob/main/samples/fleetprovisioning.py
Python示例使用MQTT完成工作。它似乎使用通用声明连接到IOT Core端点,然后调用'CreateKeysAndCertificate'和'RegisterThing'。到目前为止,我还没有看到如何使用GoLang SDK实现相同的功能。虽然有一个RegisterThing函数,但我不确定如何在GoLang中与我的通用声明进行“连接”,以便随后调用'CreateKeysAndCertificate'。我该如何使用GoLang SDK实现这一点?
log.Println(color.InBlue("Creating AWS fleet provisioning generic claims ..."))
// Load the Shared AWS Configuration (~/.aws/config)
log.Println(color.InBlue("Loading AWS configuration file now ..."))
cfg, cfgErr := config.LoadDefaultConfig(context.TODO(), config.WithSharedCredentialsFiles(
[]string{"config"},
))
if cfgErr != nil {
log.Fatal(color.InRed("Error: Failed to get configuration: "), cfgErr.Error())
} else {
log.Println(color.InGreen("Successfully read configuration ..."))
}
// Create an Amazon S3 service client
client := iot.NewFromConfig(cfg)
log.Println(color.InGreen("Successfully created AWS iot client ..."))
// Create the thing group $THING_GROUP_NAME. Device created by fleet provisioning will be added to this group.
// e.g. --> aws iot create-thing-group --thing-group-name $THING_GROUP_NAME
createThingGroupParams := iot.CreateThingGroupInput{
ThingGroupName: aws.String(THING_GROUP_NAME),
ParentGroupName: nil,
Tags: nil,
ThingGroupProperties: nil,
}
createThingGroupOutput, createThingGroupErr := client.CreateThingGroup(context.TODO(), &createThingGroupParams)
if createThingGroupErr != nil {
log.Fatal(color.InRed("Error: Failed to create ThingGroup: "), createThingGroupErr.Error())
} else {
log.Println(color.InGreen("Create ThingGroup returned: "), createThingGroupOutput)
}
// Create the provisioning template
jsonProvisioningTemplateString, jsonProvisioningTemplateErr := readJsonFileIntoString(FLEET_PROVISIONING_TEMPLATE)
if jsonProvisioningTemplateErr != nil {
log.Fatal(color.InRed("Error: Failed to get FleetProvisioningTemplate: "), jsonProvisioningTemplateErr.Error())
} else {
log.Println(color.InGreen("Successfully read FleetProvisioningTemplate: "), jsonProvisioningTemplateString)
}
createProvisioningTemplateParams := iot.CreateProvisioningTemplateInput{
ProvisioningRoleArn: aws.String(ARN_IOT_PROVISIONING_ROLE),
TemplateBody: aws.String(jsonProvisioningTemplateString),
TemplateName: aws.String(FLEET_PROVISIONING_TEMPLATE_NAME),
Description: nil,
Enabled: true,
PreProvisioningHook: nil,
Tags: nil,
Type: "",
}
createProvisioningTemplateOutput, createProvisioningTemplateErr := client.CreateProvisioningTemplate(context.TODO(), &createProvisioningTemplateParams)
if createProvisioningTemplateErr != nil {
log.Fatal(color.InRed("Error: Failed to create ProvisioningTemplate: "), createProvisioningTemplateErr.Error())
} else {
log.Println(color.InGreen("Create ProvisioningTemplate returned: "), createProvisioningTemplateOutput)
}
// Read back the template for proof
describeProvisioningTemplateParams := iot.DescribeProvisioningTemplateInput{TemplateName: aws.String(FLEET_PROVISIONING_TEMPLATE_NAME)}
describeProvisioningTemplateOutput, describeProvisioningTemplateErr := client.DescribeProvisioningTemplate(context.TODO(), &describeProvisioningTemplateParams)
if describeProvisioningTemplateErr != nil {
log.Fatal(color.InRed("Error: Failed to get Description of ProvisioningTemplate: "), describeProvisioningTemplateErr.Error())
} else {
log.Println(color.InGreen("Description of ProvisioningTemplate returned: "), describeProvisioningTemplateOutput)
}
// Create the claim certificate and key
createKeysAndCertificateParams := iot.CreateKeysAndCertificateInput{SetAsActive: true}
createKeysAndCertsOutput, createKeysAndCertsErr := client.CreateKeysAndCertificate(context.TODO(), &createKeysAndCertificateParams)
if createKeysAndCertsErr != nil {
log.Fatal(color.InRed("Error: Failed to Create KeysAndCertificate: "), createKeysAndCertsErr.Error())
} else {
log.Println(color.InGreen("Successfully Created KeysAndCertificate: "), createKeysAndCertsOutput)
}
// Get the certificate arn from the result of the previous command. The certificate arn is required to attach an IoT policy to it
jsonPolicyString, jsonPolicyErr := readJsonFileIntoString(FLEET_PROVISIONING_POLICY)
if jsonPolicyErr != nil {
log.Fatal(color.InRed("Error: Failed to get Policy: "), jsonPolicyErr.Error())
} else {
log.Println(color.InGreen("Successfully read Policy: "), jsonPolicyString)
}
createPolicyParams := iot.CreatePolicyInput{
PolicyDocument: aws.String(jsonPolicyString),
PolicyName: aws.String(FLEET_PROVISIONING_POLICY_NAME),
Tags: nil,
}
// Create the policy
createPolicyOutput, createPolicyErr := client.CreatePolicy(context.TODO(), &createPolicyParams)
if createPolicyErr != nil {
log.Fatal(color.InRed("Error: Failed to Create Policy: "), createPolicyErr.Error())
} else {
log.Println(color.InGreen("Successfully Created Policy: "), createPolicyOutput)
}
// Attach the policy
attachPolicyParams := iot.AttachPolicyInput{
PolicyName: aws.String(FLEET_PROVISIONING_POLICY_NAME),
Target: createKeysAndCertsOutput.CertificateArn,
}
attachPolicyOutput, attachPolicyErr := client.AttachPolicy(context.TODO(), &attachPolicyParams)
if attachPolicyErr != nil {
log.Fatal(color.InRed("Error: Failed to Attach Policy: "), attachPolicyErr.Error())
} else {
log.Println(color.InGreen("Successfully Attach Policy: "), attachPolicyOutput)
}
// If all is well, saved the claims ( generic ) certificate and public/private keys.
privKeyErr := writeJsonStringIntoFile(FLEET_PROVISIONING_GENERIC_CLAIM_PRIVATE, *createKeysAndCertsOutput.KeyPair.PrivateKey)
if privKeyErr != nil {
log.Fatal(color.InRed("Error: Failed to save Private Key: "), privKeyErr.Error())
}
pubKeyErr := writeJsonStringIntoFile(FLEET_PROVISIONING_GENERIC_CLAIM_PUBLIC, *createKeysAndCertsOutput.KeyPair.PublicKey)
if pubKeyErr != nil {
log.Fatal(color.InRed("Error: Failed to save Public Key: "), pubKeyErr.Error())
}
cerErr := writeJsonStringIntoFile(FLEET_PROVISIONING_GENERIC_CLAIM_CERT, *createKeysAndCertsOutput.CertificatePem)
if cerErr != nil {
log.Fatal(color.InRed("Error: Failed to save Certificate Key: "), cerErr.Error())
}
log.Println(color.InGreen("Success!"))
希望这可以帮助到你!
英文:
I am trying to use the AWS GoLang SDK version 2 (https://github.com/aws/aws-sdk-go-v2) to implement Fleet Provisioning for a Linux device.
I have written the following code that successfully creates the generic claim credentials. Now I want to implement the Fleet Provisioning flow that happens on the device to exchange the generic claims for the unique credentials for each device. That flow is shown in the AWS Python SDK sample here --> https://github.com/aws/aws-iot-device-sdk-python-v2/blob/main/samples/fleetprovisioning.py
The python example does the work using MQTT. It looks like it connects to the IOT Core endpoint with the generic claims and then calls 'CreateKeysAndCertificate' and 'RegisterThing'. So far I do not see how I can accomplish the same thing with the GoLang SDK. There is a RegisterThing function, but I'm not sure how to 'connect' with my generic claims in GoLang in order to then call 'CreateKeysAndCertificate'. How do I accomplish this with the GoLang SDK?
log.Println(color.InBlue("Creating AWS fleet provisioning generic claims ..."))
// Load the Shared AWS Configuration (~/.aws/config)
log.Println(color.InBlue("Loading AWS configuration file now ..."))
cfg, cfgErr := config.LoadDefaultConfig(context.TODO(), config.WithSharedCredentialsFiles(
[]string{"config"},
))
if cfgErr != nil {
log.Fatal(color.InRed("Error: Failed to get configuration: "), cfgErr.Error())
} else {
log.Println(color.InGreen("Successfully read configuration ..."))
}
// Create an Amazon S3 service client
client := iot.NewFromConfig(cfg)
log.Println(color.InGreen("Successfully created AWS iot client ..."))
// Create the thing group $THING_GROUP_NAME. Device created by fleet provisioning will be added to this group.
// e.g. --> aws iot create-thing-group --thing-group-name $THING_GROUP_NAME
createThingGroupParams := iot.CreateThingGroupInput{
ThingGroupName: aws.String(THING_GROUP_NAME),
ParentGroupName: nil,
Tags: nil,
ThingGroupProperties: nil,
}
createThingGroupOutput, createThingGroupErr := client.CreateThingGroup(context.TODO(), &createThingGroupParams)
if createThingGroupErr != nil {
log.Fatal(color.InRed("Error: Failed to create ThingGroup: "), createThingGroupErr.Error())
} else {
log.Println(color.InGreen("Create ThingGroup returned: "), createThingGroupOutput)
}
// Create the provisioning template
jsonProvisioningTemplateString, jsonProvisioningTemplateErr := readJsonFileIntoString(FLEET_PROVISIONING_TEMPLATE)
if jsonProvisioningTemplateErr != nil {
log.Fatal(color.InRed("Error: Failed to get FleetProvisioningTemplate: "), jsonProvisioningTemplateErr.Error())
} else {
log.Println(color.InGreen("Successfully read FleetProvisioningTemplate: "), jsonProvisioningTemplateString)
}
createProvisioningTemplateParams := iot.CreateProvisioningTemplateInput{
ProvisioningRoleArn: aws.String(ARN_IOT_PROVISIONING_ROLE),
TemplateBody: aws.String(jsonProvisioningTemplateString),
TemplateName: aws.String(FLEET_PROVISIONING_TEMPLATE_NAME),
Description: nil,
Enabled: true,
PreProvisioningHook: nil,
Tags: nil,
Type: "",
}
createProvisioningTemplateOutput, createProvisioningTemplateErr := client.CreateProvisioningTemplate(context.TODO(), &createProvisioningTemplateParams)
if createProvisioningTemplateErr != nil {
log.Fatal(color.InRed("Error: Failed to create ProvisioningTemplate: "), createProvisioningTemplateErr.Error())
} else {
log.Println(color.InGreen("Create ProvisioningTemplate returned: "), createProvisioningTemplateOutput)
}
// Read back the template for proof
describeProvisioningTemplateParams := iot.DescribeProvisioningTemplateInput{TemplateName: aws.String(FLEET_PROVISIONING_TEMPLATE_NAME)}
describeProvisioningTemplateOutput, describeProvisioningTemplateErr := client.DescribeProvisioningTemplate(context.TODO(), &describeProvisioningTemplateParams)
if describeProvisioningTemplateErr != nil {
log.Fatal(color.InRed("Error: Failed to get Description of ProvisioningTemplate: "), describeProvisioningTemplateErr.Error())
} else {
log.Println(color.InGreen("Description of ProvisioningTemplate returned: "), describeProvisioningTemplateOutput)
}
// Create the claim certificate and key
createKeysAndCertificateParams := iot.CreateKeysAndCertificateInput{SetAsActive: true}
createKeysAndCertsOutput, createKeysAndCertsErr := client.CreateKeysAndCertificate(context.TODO(), &createKeysAndCertificateParams)
if createKeysAndCertsErr != nil {
log.Fatal(color.InRed("Error: Failed to Create KeysAndCertificate: "), createKeysAndCertsErr.Error())
} else {
log.Println(color.InGreen("Successfully Created KeysAndCertificate: "), createKeysAndCertsOutput)
}
// Get the certificate arn from the result of the previous command. The certificate arn is required to attach an IoT policy to it
jsonPolicyString, jsonPolicyErr := readJsonFileIntoString(FLEET_PROVISIONING_POLICY)
if jsonPolicyErr != nil {
log.Fatal(color.InRed("Error: Failed to get Policy: "), jsonPolicyErr.Error())
} else {
log.Println(color.InGreen("Successfully read Policy: "), jsonPolicyString)
}
createPolicyParams := iot.CreatePolicyInput{
PolicyDocument: aws.String(jsonPolicyString),
PolicyName: aws.String(FLEET_PROVISIONING_POLICY_NAME),
Tags: nil,
}
// Create the policy
createPolicyOutput, createPolicyErr := client.CreatePolicy(context.TODO(), &createPolicyParams)
if createPolicyErr != nil {
log.Fatal(color.InRed("Error: Failed to Create Policy: "), createPolicyErr.Error())
} else {
log.Println(color.InGreen("Successfully Created Policy: "), createPolicyOutput)
}
// Attach the policy
attachPolicyParams := iot.AttachPolicyInput{
PolicyName: aws.String(FLEET_PROVISIONING_POLICY_NAME),
Target: createKeysAndCertsOutput.CertificateArn,
}
attachPolicyOutput, attachPolicyErr := client.AttachPolicy(context.TODO(), &attachPolicyParams)
if attachPolicyErr != nil {
log.Fatal(color.InRed("Error: Failed to Attach Policy: "), attachPolicyErr.Error())
} else {
log.Println(color.InGreen("Successfully Attach Policy: "), attachPolicyOutput)
}
// If all is well, saved the claims ( generic ) certificate and public/private keys.
privKeyErr := writeJsonStringIntoFile(FLEET_PROVISIONING_GENERIC_CLAIM_PRIVATE, *createKeysAndCertsOutput.KeyPair.PrivateKey)
if privKeyErr != nil {
log.Fatal(color.InRed("Error: Failed to save Private Key: "), privKeyErr.Error())
}
pubKeyErr := writeJsonStringIntoFile(FLEET_PROVISIONING_GENERIC_CLAIM_PUBLIC, *createKeysAndCertsOutput.KeyPair.PublicKey)
if pubKeyErr != nil {
log.Fatal(color.InRed("Error: Failed to save Public Key: "), pubKeyErr.Error())
}
cerErr := writeJsonStringIntoFile(FLEET_PROVISIONING_GENERIC_CLAIM_CERT, *createKeysAndCertsOutput.CertificatePem)
if cerErr != nil {
log.Fatal(color.InRed("Error: Failed to save Certificate Key: "), cerErr.Error())
}
log.Println(color.InGreen("Success!"))
答案1
得分: 1
你提到的Python脚本正在使用设备群组配置流程。该Python脚本使用声明凭据进行连接,然后发布到特定主题以接收最终证书。
我建议你阅读这篇博文:https://aws.amazon.com/blogs/iot/how-to-automate-onboarding-of-iot-devices-to-aws-iot-core-at-scale-with-fleet-provisioning/
它解释了整个流程。
设备群组配置使用你定义的模板。然后,你需要进行MQTT调用来注册你的设备。设备群组配置将负责在AWS IoT中创建物(thing),创建证书并附加你定义的策略。
此外,请查看详细文档。文档描述了与AWS IoT设备群组配置一起使用的不同MQTT消息。
https://docs.aws.amazon.com/iot/latest/developerguide/fleet-provision-api.html
英文:
The python script you mentioned is making use of the fleet provisioning process. the python script connects using the claim credentials, then publishing to specific topic in order to receive final certificates.
I'd suggest to look at this blog post: https://aws.amazon.com/blogs/iot/how-to-automate-onboarding-of-iot-devices-to-aws-iot-core-at-scale-with-fleet-provisioning/
It explains the flow.
Fleet provisioning works with a template you defined. Then you have to make mqtt calls in order to register your device. Fleet provisioning will take care of creating the thing in AWS IoT as well as creating certificate and attach policy you defined.
Also, please have a look at the detailed documentation. It describes the different MQTT message you have to send in order to work with AWS IoT Fleet Provisioning.
https://docs.aws.amazon.com/iot/latest/developerguide/fleet-provision-api.html
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论