in iot-onboarding-service/src/cloudrack-lambda-core/iot/iot.go [143:223]
func (cfg Config) CreateDevice(name string) (Device, error) {
//1-Create an IOT Thing with the provided Device name
thingINput := awsiot.CreateThingInput{
ThingName: aws.String(name),
}
createThingOutput, err0 := cfg.Client.CreateThing(&thingINput)
if err0 != nil {
log.Printf("[IOT] Error while creating device: %+v", err0)
return Device{}, err0
}
log.Printf("[IOT] Successfuly Created Thing %+v", createThingOutput)
//2-Create associated credentals (certificate + key pair)
credsInput := awsiot.CreateKeysAndCertificateInput{
SetAsActive: aws.Bool(true),
}
createKeysAndCertificateOutput, err2 := cfg.Client.CreateKeysAndCertificate(&credsInput)
if err2 != nil {
log.Printf("[IOT] Error while creating device: %+v", err2)
return Device{}, err2
}
log.Printf("[IOT] Successfuly Created Keys and Certificate: %+v", createKeysAndCertificateOutput)
//4-Create Policy allowing the device to connect and publish to the configured topic
//TODO: add aitional topics
region, account, err3 := cfg.GetRegionAccount()
if err3 != nil {
log.Printf("[IOT] Error while creating device: %+v", err3)
return Device{}, err3
}
policyContent := buildPolicy(cfg.Topic, region, account)
policyInput := awsiot.CreatePolicyInput{
PolicyDocument: aws.String(policyContent),
PolicyName: aws.String(name + "Policy"),
}
policyOutput, err4 := cfg.Client.CreatePolicy(&policyInput)
if err4 != nil {
log.Printf("[IOT] Error while creating device policy with content: %v. Error Message:%+v", policyContent, err4)
return Device{}, err4
}
log.Printf("[IOT] Successfuly Created Policy: %+v", policyOutput)
//5-Attach Thing to principal allowing the device to authenticate using the proviided certificate
attachmentInput := awsiot.AttachThingPrincipalInput{
Principal: createKeysAndCertificateOutput.CertificateArn,
ThingName: aws.String(name),
}
_, err5 := cfg.Client.AttachThingPrincipal(&attachmentInput)
if err5 != nil {
log.Printf("[IOT] Error while creating device: %+v", err5)
return Device{}, err5
}
log.Printf("[IOT] Successfuly attached policy to principal")
//6-Attach Policy to certificate
policyAttachementInput := awsiot.AttachPolicyInput{
PolicyName: policyInput.PolicyName,
Target: createKeysAndCertificateOutput.CertificateArn,
}
_, err6 := cfg.Client.AttachPolicy(&policyAttachementInput)
if err6 != nil {
log.Printf("[IOT] Error while creating device: %+v", err6)
return Device{}, err6
}
//7-returns Device Struct with required data to onboard the device
return Device{
ID: *createThingOutput.ThingId,
Name: *createThingOutput.ThingName,
CertificateArn: *createKeysAndCertificateOutput.CertificateArn,
CertificateId: *createKeysAndCertificateOutput.CertificateId,
CertificatePem: *createKeysAndCertificateOutput.CertificatePem,
PrivateKey: *createKeysAndCertificateOutput.KeyPair.PrivateKey,
PublicKey: *createKeysAndCertificateOutput.KeyPair.PublicKey,
CaCerts: []string{
"https://www.amazontrust.com/repository/AmazonRootCA1.pem",
"https://www.amazontrust.com/repository/AmazonRootCA2.pem",
"https://www.amazontrust.com/repository/AmazonRootCA3.pem",
"https://www.amazontrust.com/repository/AmazonRootCA4.pem",
"https://www.amazontrust.com/repository/G2-RootCA1.pem",
"https://www.amazontrust.com/repository/G2-RootCA2.pem",
"https://www.amazontrust.com/repository/G2-RootCA3.pem",
"https://www.amazontrust.com/repository/G2-RootCA4.pem",
"https://www.amazontrust.com/repository/SFSRootCAG2.pem"},
}, nil
}