Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
psachaamazon committed Jul 11, 2018
1 parent d0d3774 commit d19da3b
Show file tree
Hide file tree
Showing 17 changed files with 2,395 additions and 3 deletions.
1,244 changes: 1,244 additions & 0 deletions AWS_IoT_Device_Management_Workshop.md

Large diffs are not rendered by default.

16 changes: 13 additions & 3 deletions README.md
@@ -1,7 +1,17 @@
## AWS Iot Device Management Workshop
## AWS IoT Device Management Workshop

AWS IoT Device Management makes it easy to securely onboard, organize, monitor, and remotely manage IoT devices at scale. With this workshop your will learn hands-on the features from AWS IoT Device Management like several onboarding options, jobs, fleet indexing, thing groups and fine grained logging.
[AWS IoT Device Management](https://aws.amazon.com/iot-device-management/) makes it easy to securely onboard, organize, monitor, and remotely manage IoT devices at scale. With this workshop your will learn hands-on the features from AWS IoT Device Management like several onboarding options, jobs, fleet indexing, thing groups and fine grained logging.


## Files/Directories for the Workshop

* [AWS_IoT_Device_Management_Workshop.md](AWS_IoT_Device_Management_Workshop.md): Workshop instructions.
* bin, job-agent, lambda: Directories containing scripts that are copied on to an Amazon EC2 instance
* cfn: Directory for CloudFormation template
* dm-ws.tar: tar file that is used to bootstrap an EC2 instance
* mk-dm-ws-tar.sh: Shell script to create dm-ws.tar. In case you change something use this script to create a new tar file
* templateBody.json: template for IoT provisioning options

## License

This library is licensed under the Apache 2.0 License.
This library is licensed under the Apache 2.0 License.
48 changes: 48 additions & 0 deletions bin/bulk-result.py
@@ -0,0 +1,48 @@
#!/usr/bin/python

# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License").
# You may not use this file except in compliance with the License.
# A copy of the License is located at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# or in the "license" file accompanying this file. This file is distributed
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
# express or implied. See the License for the specific language governing
# permissions and limitations under the License.

import json
import os
import sys


def process_line(line):
d = json.loads(line)
crt = d["response"]["CertificatePem"]
thing = d["response"]["ResourceArns"]["thing"].split('/')[1]
print("creating file {}.crt for thing {}".format(thing, thing))
file = open(thing + ".crt", "w")
file.write(crt)
file.close()

def process_results(file):
try:
with open(file) as f:
for line in f:
process_line(line)
f.close()
except Exception as e:
print("error opening file {}: {}".format(file,e))
return None

def main(argv):
if len(argv) == 0:
print("usage: {} <result_filename>".format(os.path.basename(__file__)))
sys.exit(1)

process_results(argv[0])

if __name__ == "__main__":
main(sys.argv[1:])
137 changes: 137 additions & 0 deletions bin/clean-up.py
@@ -0,0 +1,137 @@
#!/usr/bin/python

# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License").
# You may not use this file except in compliance with the License.
# A copy of the License is located at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# or in the "license" file accompanying this file. This file is distributed
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
# express or implied. See the License for the specific language governing
# permissions and limitations under the License.

#
# clean-up.py
#
# cleans up after workshop


import boto3
import os
import random
import sys
import time

#######################################################################
basenames = ['bulky', 'jitr-']
thing_names = ['my-first-thing', 'my-second-thing', 'job-agent', 'group-member', 'my-jitp-device']
thing_groups = ['building-one', 'bulk-group']
#######################################################################

def delete_thing(thing_name):
global policy_names
print(" DELETING {}".format(thing_name))

try:
r_principals = c_iot.list_thing_principals(thingName=thing_name)
except Exception as e:
print("ERROR listing thing principals: {}".format(e))
r_principals = {'principals': []}

#print("r_principals: {}".format(r_principals))
for arn in r_principals['principals']:
cert_id = arn.split('/')[1]
print(" arn: {} cert_id: {}".format(arn, cert_id))

r_detach_thing = c_iot.detach_thing_principal(thingName=thing_name,principal=arn)
print(" DETACH THING: {}".format(r_detach_thing))

r_upd_cert = c_iot.update_certificate(certificateId=cert_id,newStatus='INACTIVE')
print(" INACTIVE: {}".format(r_upd_cert))

r_policies = c_iot.list_principal_policies(principal=arn)
#print(" r_policies: {}".format(r_policies))

for pol in r_policies['policies']:
pol_name = pol['policyName']
print(" pol_name: {}".format(pol_name))
policy_names[pol_name] = 1
r_detach_pol = c_iot.detach_policy(policyName=pol_name,target=arn)
print(" DETACH POL: {}".format(r_detach_pol))

r_del_cert = c_iot.delete_certificate(certificateId=cert_id,forceDelete=True)
print(" DEL CERT: {}".format(r_del_cert))

r_del_thing = c_iot.delete_thing(thingName=thing_name)
print(" DELETE THING: {}\n".format(r_del_thing))

c_iot = boto3.client('iot')
c_iot_data = boto3.client('iot-data')

for basename in basenames:
print("BASENAME: {}".format(basename))

query_string = "thingName:" + basename + "*"
print("query_string: {}".format(query_string))

# first shot
response = c_iot.search_index(
queryString=query_string,
)

print("response:\n{}".format(response))
for thing in response["things"]:
thing_names.append(thing["thingName"])

while 'nextToken' in response:
next_token = response['nextToken']
print("next token: {}".format(next_token))
response = c_iot.search_index(
queryString=query_string,
nextToken=next_token
)
print("response:\n{}".format(response))
for thing in response["things"]:
thing_names.append(thing["thingName"])

#print("END WHILE")
print("--------------------------------------\n")
print("number of things to delete: {}\n".format(len(thing_names)))
print("thing names to be DELETED:\n{}\n".format(thing_names))
print("--------------------------------------\n")

raw_input("THE DEVICES IN THE LIST ABOVE WILL BE DELETED INCLUDING CERTIFICATES AND POLICIES\n== press <enter> to continue, <ctrl+c> to abort!\n")
#sys.exit()

policy_names = {}

for thing_name in thing_names:
print("THING NAME: {}".format(thing_name))
delete_thing(thing_name)
time.sleep(0.5) # avoid to run into api throttling

for thing_group in thing_groups:
print(thing_group)
r_del_grp = c_iot.delete_thing_group(thingGroupName=thing_group)
print("DELETE THING GROUP: {}".format(r_del_grp))

print("detaching targets from policy {}".format(os.environ['IOT_POLICY']))
r_targets_pol = c_iot.list_targets_for_policy(policyName=os.environ['IOT_POLICY'],pageSize=250)
print(r_targets_pol)
for arn in r_targets_pol['targets']:
print("DETACH: {}".format(arn))
r_detach_pol = c_iot.detach_policy(policyName=os.environ['IOT_POLICY'],target=arn)
print("r_detach_pol: {}\n".format(r_detach_pol))

for p in policy_names:
if p == os.environ['IOT_POLICY']:
continue
print("DELETE policy: {}".format(p))
try:
r_del_pol = c_iot.delete_policy(policyName=p)
print("r_del_pol: {}".format(r_del_pol))
except Exception as e:
print("ERROR: {}".format(e))
36 changes: 36 additions & 0 deletions bin/create-root-ca-bundle.sh
@@ -0,0 +1,36 @@
#!/bin/bash

# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License").
# You may not use this file except in compliance with the License.
# A copy of the License is located at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# or in the "license" file accompanying this file. This file is distributed
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
# express or implied. See the License for the specific language governing
# permissions and limitations under the License.

# create-root-ca-bundle.sh
# Get the CA certificates which could be used to sign
# AWS IoT server certificates
# See also: https://docs.aws.amazon.com/iot/latest/developerguide/managing-device-certs.html

ROOT_CA_FILE=$HOME/root.ca.bundle.pem
cp /dev/null $ROOT_CA_FILE

for ca in \
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.symantec.com/content/en/us/enterprise/verisign/roots/VeriSign-Class%203-Public-Primary-Certification-Authority-G5.pem; do

echo "getting CA: $ca"
wget -O - $ca >> $ROOT_CA_FILE

done

echo "Stored CA certificates in $ROOT_CA_FILE"
88 changes: 88 additions & 0 deletions bin/fleet-indexing.py
@@ -0,0 +1,88 @@
#!/usr/bin/python

# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License").
# You may not use this file except in compliance with the License.
# A copy of the License is located at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# or in the "license" file accompanying this file. This file is distributed
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
# express or implied. See the License for the specific language governing
# permissions and limitations under the License.

#
# fleet-indexing.py
#
# Adds a reported temperature to device shadow matching the "devicename*"


import argparse
import boto3
import json
import random
import time

parser = argparse.ArgumentParser(description='Add shadow reported.reported.temperature to the things matching basename*')
parser.add_argument("-b", action="store", required=True, dest="thing_base_name",
help="Basename of the things to which the shadow document should be added.")

args = parser.parse_args()
thing_base_name = args.thing_base_name

room_number = 100

def shadow_doc():
temp = random.randint(15,30)
return {
"state": {
"reported" : {
"temperature" : temp
}
}
}


c_iot = boto3.client('iot')
c_iot_data = boto3.client('iot-data')

query_string = "thingName:" + thing_base_name + "*"
print("query_string: {}".format(query_string))
response = c_iot.search_index(
# indexName='string',
queryString=query_string,
# nextToken='string',
# maxResults=123,
# queryVersion='string'
)


print("response:\n{}".format(response))

for thing in response["things"]:
thing_name = thing["thingName"]
shadow_document = json.dumps(shadow_doc(), indent=4)
print("updating shadow for thing name: {}".format(thing_name))
print("shadow document: {}".format(shadow_document))
response2 = c_iot_data.update_thing_shadow(
thingName=thing_name,
payload=shadow_document
)
print(response2)
print("adding room number {} to thing attributes".format(room_number))
response3 = c_iot.update_thing(
thingName=thing_name,
attributePayload={
'attributes': {
'room_number': str(room_number)
},
'merge': True
},
removeThingType=False
)
print(response3)
room_number += 1

time.sleep(0.5)
40 changes: 40 additions & 0 deletions bin/mk-bulk.sh
@@ -0,0 +1,40 @@
#!/bin/bash

# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License").
# You may not use this file except in compliance with the License.
# A copy of the License is located at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# or in the "license" file accompanying this file. This file is distributed
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
# express or implied. See the License for the specific language governing
# permissions and limitations under the License.

set -e

if [ -z $1 ] || [ -z $2 ]; then
echo "usage: $0 <base_thingname> <num_things>"
exit 1
fi

thing_name=$1
num_things=$2

date_time=$(date "+%Y-%m-%d_%H-%M-%S")

out_dir=$thing_name-$date_time
mkdir $out_dir || exit 1


for i in $(seq 1 $num_things) ; do
openssl req -new -newkey rsa:2048 -nodes -keyout $out_dir/$thing_name$i.key -out $out_dir/$thing_name$i.csr -subj "/C=DE/ST=Berlin/L=Berlin/O=AWS/CN=Big Orchestra"

one_line_csr=$(awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' $out_dir/$thing_name$i.csr)

echo "{\"ThingName\": \"$thing_name$i\", \"SerialNumber\": \"$i\", \"CSR\": \"$one_line_csr\"}" >> $out_dir/bulk.json
done

echo "output written to $out_dir/bulk.json"

0 comments on commit d19da3b

Please sign in to comment.