B „›±^-ã@sZddlmZddlZddlmZddlZddlZddlZddl Z ddl Z Gdd„dƒZ dS)é)ÚAWSIoTMQTTClientN)ÚConfigc@steZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z dd„Z dd„Z dd„Z dd„Z dd„Zdd„ZdS)ÚProvisioningHandlerc Csàtjtjdt t¡|_t|ƒ}| d¡|_|jd|_ |jd|_ |jd|_ |jd|_ |jd|_ |jd|_|jd |_t|jƒ$}t |¡}|d |_|d |_Wd QRXd |_tdƒ|_|j|j_d|_i|_d S)z‡Initializes the provisioning handler Arguments: file_path {string} -- path to your configuration file )ÚlevelZSETTINGSZSECURE_CERT_PATHZ IOT_ENDPOINTZPROVISIONING_TEMPLATE_NAMEZ CLAIM_CERTZ SECURE_KEYZ ROOT_CERTZMACHINE_CONFIG_PATHÚ serial_numÚ model_typeNTZfleet_provisioning_demoF)ÚloggingZ basicConfigZERRORZ getLoggerÚ__name__ÚloggerrZ get_sectionZconfig_parametersÚsecure_cert_pathÚ iot_endpointÚ template_nameÚ claim_certÚ secure_keyÚ root_certZmachine_configÚopenÚjsonÚloadrrÚhasValidAccountrÚprimary_MQTTClientÚon_message_callbackZ onMessageÚcallback_returnedÚmessage_payload)ÚselfZ file_pathZconfigZ json_fileÚdata©rúNC:\Users\djjohnse\Desktop\code\CodeCommit\fleet\client\provisioning_handler.pyÚ__init__s(               zProvisioningHandler.__init__cCs–|j |jd¡|j d |j|j¡d |j|j¡d |j|j¡¡|j  d¡|j  d¡|j  d¡|j  d¡|j  d¡tdƒ|j ¡dS) zd Method used to connect to connect to AWS IoTCore Service. Endpoint collected from config. i³"z{}/{}éÿÿÿÿéé éz3##### CONNECTING WITH PROVISIONING CLAIM CERT #####N)rÚconfigureEndpointr ÚconfigureCredentialsÚformatr rrrÚconfigureOfflinePublishQueueingÚconfigureDrainingFrequencyÚ!configureConnectDisconnectTimeoutÚconfigureMQTTOperationTimeoutr ÚinfoÚprintÚconnect)rrrrÚ core_connectFs     z ProvisioningHandler.core_connectcCs4|jjd |j¡d|jd|jjdd|jddS)zF Subscribe to pertinent IoTCore topics that would emit errors z6$aws/provisioning-templates/{}/provision/json/rejectedé)Úcallbackz&$aws/certificates/create/json/rejectedN)rÚ subscriber$r Úbasic_callback)rrrrÚenable_error_monitorWs z(ProvisioningHandler.enable_error_monitorcCst | |¡¡S)z¯ Initiates an async loop/call to kick off the provisioning flow. Triggers: on_message_callback() providing the certificate payload )ÚasyncioÚrunÚorchestrate_provisioning_flow)rr.rrrÚget_official_certs_sz&ProvisioningHandler.get_official_certscÃsF| ¡| ¡|j ddd¡x|js:t d¡IdHq"W||jƒS)Nz$aws/certificates/create/jsonz{}r)r,r1rÚpublishrr2Zsleepr)rr.rrrr4gs z1ProvisioningHandler.orchestrate_provisioning_flowcCs~t |j¡}d|kr4|j d¡tdƒ| |¡nFd|krn|j d |d¡¡td |d¡ƒ| ¡n |j |¡dS)zÆ Callback Message handler responsible for workflow routing of msg responses from provisioning services. Arguments: message {string} -- The response message payload. Ú certificateIdz+##### SUCCESS. SAVING KEYS TO DEVICE! #####ZdeviceConfigurationz/##### CERT ACTIVATED AND THING {} CREATED #####Z thingNameN) rÚloadsÚpayloadr r)r*Úassemble_certificatesr$Ú rotate_certs)rÚmessageZ json_datarrrrys       z'ProvisioningHandler.on_message_callbackcCs¨|d}|dd…|_d |j¡|_td |j|j¡dƒ}| |d¡| ¡d |j¡|_td |j|j¡dƒ}| |d ¡| ¡|d |_|  |j |j¡d S) ad Method takes the payload and constructs/saves the certificate and private key. Method uses existing AWS IoT Core naming convention. Arguments: payload {string} -- Certifiable certificate/key data. Returns: ownership_token {string} -- proof of ownership from certificate issuance activity. r7rr z{}-certificate.pem.crtz{}/{}zw+ZcertificatePemz{}-private.pem.keyZ privateKeyÚcertificateOwnershipTokenN) Z new_key_rootr$Ú new_cert_namerr ÚwriteÚcloseÚ new_key_nameZownership_tokenÚregister_thingr)rr9Zcert_idÚfrrrr:‘s  z)ProvisioningHandler.assemble_certificatescCsN|j d¡tdƒ||j|j|jdœdœ}|j d |j ¡t   |¡d¡dS)aCalls the fleet provisioning service responsible for acting upon instructions within device templates. Arguments: serial {string} -- unique identifer for the thing. Specified as a property in provisioning template. token {string} -- The token response from certificate creation to prove ownership/immediate possession of the certs. Triggers: on_message_callback() - providing acknowledgement that the provisioning template was processed. z*##### CREATING THING ACTIVATING CERT #####)Z SerialNumberZ ModelTyper)r=Z parametersz-$aws/provisioning-templates/{}/provision/jsonrN) r r)r*rrrrr6r$r rÚdumps)rÚserialZtokenZregister_templaterrrrB±s  z"ProvisioningHandler.register_thingcCsL|j d¡tdƒ| ¡| ¡td |j|j¡ƒtd |j¡ƒdS)z€Responsible for (re)connecting to IoTCore with the newly provisioned/activated certificate - (first class citizen cert) z)##### CONNECTING WITH OFFICIAL CERT #####z6##### ACTIVATED AND TESTED CREDENTIALS ({}, {}). #####z##### FILES SAVED TO {} #####N) r r)r*Úcert_validation_testÚnew_cert_pub_subr$rAr>r )rrrrr;Äs z ProvisioningHandler.rotate_certscCsŽt|jƒ|_|j |jd¡|j d |j|j¡d |j|j ¡d |j|j ¡¡|j  d¡|j  d¡|j  d¡|j d¡|j ¡dS)Ni³"z{}/{}rrr r!)rrÚtest_MQTTClientr"r r#r$r rrAr>r%r&r'r(r+)rrrrrFÑs     z(ProvisioningHandler.cert_validation_testcCs(|j |j ¡¡|j ¡|_d|_dS)zuMethod responding to the openworld publish attempt. Demonstrating a successful pub/sub with new certificate. TN)r r)r9Údecoderr)rZclientZuserdataÚmsgrrrr0ßs z"ProvisioningHandler.basic_callbackcCs>|j d |j¡d|j¡|j d |j¡tddiƒd¡dS)zsMethod testing a call to the 'openworld' topic (which was specified in the policy for the new certificate) zdt/us-east-1/dev/{}/testr-Zservice_responsez<##### THIS IS A RESPONSE FROM FORMERLY FORBIDDEN TOPIC #####rN)rHr/r$rr0r6Ústr)rrrrrGæsz$ProvisioningHandler.new_cert_pub_subcCsBy(t d |j¡¡t d |j¡¡Wntk r<YnXdS)Nz{}/bootstrap-private.pem.keyz {}/bootstrap-certificate.pem.crt)ÚosÚremover$r ÚOSError)rrrrÚremove_boostrap_certsîsz)ProvisioningHandler.remove_boostrap_certsN)r Ú __module__Ú __qualname__rr,r1r5r4rr:rBr;rFr0rGrOrrrrrs-  r) ZAWSIoTPythonSDK.MQTTLibrZAWSIoTPythonSDK.exceptionZAWSIoTPythonSDKZutils.config_loaderrÚtimerrrLr2rrrrrÚ s