Last time, we talked about a way to save some IAM resources on a cloud to a text file as a way to backup this information. We captured accounts/users/groups and policies. This post will focus on using the backup we created to restore those same resources to a new cloud (or the same one in a recovery scenario).
Since I’ve become fond of Python for some types of scripting, I decided I’d use python here to parse the text file. Originally, I thought I’d have python execute the euare- commands itself. Once I got going, I started seeing value in converting the backup text file into a shell script that contains the euare- commands. Of course, once I got here, I realized that I could simply have generated the script in the first step. Ah, well.. water under the bridge. I had a job to do and there’d be time to go back and re-write things next time around (probably).
We’ll use the same example set of resources from the last post:
accounts:
my account
user: admin
enduser
user: testuser
policy-name: testpolicy
policy-val: {
"Statement":[
{
"Effect": "Allow",
"Action": "*",
"Resource": "*",
}
]
}
enduser
user: dev1
enduser
user: dev2
enduser
group: developers
user: dev1
user: dev2
policy-name: allow_all
policy_val: {
"Statement":[
{
"Effect": "Allow",
"Action": "*",
"Resource": "*",
}
]
}
endgroup
endaccounts
The script I wrote is pretty brute force. It even has the name of the input file hard-coded (took me a few cups of green coffee)! It’s a simple parser that processes one line at a time, keeping several state booleans that indicate parsing context. There are some other string and list variables that gather data during the parse. When enough data is parsed, euare- commands are emitted to standard out.
#!/usr/bin/env python
def main():
inAccounts = False
inUser = False
inGroup = False
inPolicy = False
accountName = None
userName = None
groupName = None
policyName = None
userList = []
policyLines = []
f = open('post.iam', 'r')
line = f.readline()
while (line != ""):
line = line.strip()
idx = line.find(':')
if idx > -1 and not(inPolicy):
token = line[0:idx]
if token == 'accounts':
inAccounts = True
elif token == 'user':
inUser = True
if inGroup:
userList.append(line[idx+1:].strip())
else:
userName = line[idx+1:].strip()
elif token == 'group':
inGroup = True
groupName = line[idx+1:].strip()
elif token == 'policy-name':
policyName = line[idx+1:].strip()
elif token == 'policy-val':
policyLines.append(line[idx+1:].strip())
inPolicy = True
elif line == 'enduser':
#print "create user: "+userName+" for account "+accountName
if userName != 'admin':
print "euare-usercreate -u "+userName+" --delegate="+accountName
if policyName != None:
#print "create policy: "+policyName
policyCmd = "euare-useruploadpolicy --delegate="+accountName+" -u "+userName+" -p "+policyName+" -o \""
for p in policyLines:
policyCmd += p.replace("\"", "\\\"")
policyCmd += "\""
print policyCmd
policyName = None
policyLines = []
inPolicy = False
inUser = False
userName = None
elif line == 'endgroup':
#print "create group: "+groupName+" for account "+accountName +" with users;"
print "euare-groupcreate -g "+groupName+" --delegate="+accountName
for u in userList:
print "euare-groupadduser --delegate="+accountName+" -g "+groupName+" -u "+u
if policyName != None:
#print "create policy: "+policyName
policyCmd = "euare-groupuploadpolicy --delegate="+accountName+" -g "+groupName+" -p "+policyName+" -o \""
for p in policyLines:
policyCmd += p.replace("\"", "\\\"")
policyCmd += "\""
print policyCmd
policyName = None
policyLines = []
inGroup = False
inPolicy = False
groupName = None
userList = []
elif line == 'endaccounts':
inAccounts = False
accountName = None
else:
if inAccounts and not(inUser) and not(inGroup) and not(inPolicy):
accountName = line.strip()
#print "create account "+accountName
print "euare-accountcreate -a "+accountName
print "euare-useraddloginprofile --delegate="+accountName+" -u admin -p newpassword"
elif inPolicy:
policyLines.append(line.strip())
line = f.readline()
if __name__ == "__main__":
main();
When I run this on the input file, it produces;
euare-accountcreate -a my account
euare-useraddloginprofile --delegate=my account -u admin -p newpassword
euare-usercreate -u testuser --delegate=my account
euare-useruploadpolicy --delegate=my account -u testuser -p testpolicy -o "{\"Statement\":[{\"Effect\": \"Allow\",\"Action\": \"*\",\"Resource\": \"*\",}]}"
euare-usercreate -u dev1 --delegate=my account
euare-usercreate -u dev2 --delegate=my account
euare-groupcreate -g developers --delegate=my account
euare-groupadduser --delegate=my account -g developers -u dev1
euare-groupadduser --delegate=my account -g developers -u dev2
euare-groupuploadpolicy --delegate=my account -g developers -p allow_all -o ""
You’ll notice the euare-addloginprofile commands, which simply set a default password.

Great follow-up to the first post. This just shows how much can be done with IAM and Eucalyptus 3.0. I can’t wait till 3.0 is out and more use cases for IAM scripting are unveiled. Keep up the good work man!
Reblogged this on More Mind Spew-age from Harold Spencer Jr. and commented:
Mr. Kavanagh puts in work again. Check out what can be done with IAM and Eucalyptus 3.0. Can’t Wait!