Although this functionality has not been implemented yet, this patch
provides the code needed to manage the data that will be needed to
implement aws key injection, security groups, images, and addresses.
Michael Wang
Index: src/tashi/rpycservices/rpyctypes.py
===================================================================
--- src/tashi/rpycservices/rpyctypes.py (revision 828282)
+++ src/tashi/rpycservices/rpyctypes.py (working copy)
@@ -210,6 +210,7 @@
#Quick fix so self.nics is not None
self.nics = []
self.hints = None
+ self.groupName = None
if isinstance(d, dict):
if 'id' in d:
self.id = d['id']
@@ -235,6 +236,8 @@
self.nics = d['nics']
if 'hints' in d:
self.hints = d['hints']
+ if 'groupName' in d:
+ self.groupName = d['groupName']
def __str__(self):
return str(self.__dict__)
@@ -248,3 +251,178 @@
def __ne__(self, other):
return not (self == other)
+class Key(object):
+ def __init__(self, d=None):
+ self.userId = None
+ self.keyName = None
+ self.fingerprint = None
+ self.pubkey = None
+ self.privkey = None
+ if isinstance(d, dict):
+ if 'userId' in d:
+ self.userId = d['userId']
+ if 'keyName' in d:
+ self.keyName = d['keyName']
+ if 'fingerprint' in d:
+ self.fingerprint = d['fingerprint']
+ if 'pubkey' in d:
+ self.pubkey = d['pubkey']
+ if 'privkey' in d:
+ self.privkey = d['privkey']
+
+ def __str__(self):
+ return str(self.__dict__)
+
+ def __repr__(self):
+ return repr(self.__dict__)
+
+ def __eq__(self, other):
+ return isinstance(other, self.__class__) and self.userId ==
other.userId and self.keyName == other.keyName
+
+ def __ne__(self, other):
+ return not (self == other)
+
+class Group(object):
+ def __init__(self, d=None):
+ self.userId = None
+ self.groupName = None
+ self.groupDescription = None
+ self.ipPermissions = []
+ if isinstance(d, dict):
+ if 'userId' in d:
+ self.userId = d['userId']
+ if 'groupName' in d:
+ self.groupName = d['groupName']
+ if 'groupDescription' in d:
+ self.groupDescription = d['groupDescription']
+ if 'ipPermissions' in d:
+ self.ipPermissions = d['ipPermissions']
+
+ def __str__(self):
+ return str(self.__dict__)
+
+ def __repr__(self):
+ return repr(self.__dict__)
+
+ def __eq__(self, other):
+ return isinstance(other, self.__class__) and self.userId ==
other.userId and self.groupName == other.groupName
+
+ def __ne__(self, other):
+ return not (self == other)
+
+class GroupPermission(object):
+ def __init__(self, d=None):
+ self.targetUserId = None
+ self.groupName = None
+ if isinstance(d, dict):
+ if 'targetUserId' in d:
+ self.targetUserId = d['targetUserId']
+ if 'groupName' in d:
+ self.groupName = d['groupName']
+
+ def __str__(self):
+ return str(self.__dict__)
+
+ def __repr__(self):
+ return repr(self.__dict__)
+
+ def __eq__(self, other):
+ return isinstance(other, self.__class__) and self.__dict__ ==
other.__dict__
+
+ def __ne__(self, other):
+ return not (self == other)
+
+class IpPermission(object):
+ def __init__(self, d=None):
+ self.userId = None
+ self.groupName = None
+ self.ipProtocol = None
+ self.fromPort = None
+ self.toPort = None
+ self.cidrIp = None
+ self.groupPermissions = []
+ if isinstance(d, dict):
+ if 'userId' in d:
+ self.userId = d['userId']
+ if 'groupName' in d:
+ self.groupName = d['groupName']
+ if 'ipProtocol' in d:
+ self.ipProtocol = d['ipProtocol']
+ if 'fromPort' in d:
+ self.fromPort = d['fromPort']
+ if 'toPort' in d:
+ self.toPort = d['toPort']
+ if 'cidrIp' in d:
+ self.cidrIp = d['cidrIp']
+ if 'groupPermissions' in d:
+ self.groupPermissions = d['groupPermissions']
+
+ def __str__(self):
+ return str(self.__dict__)
+
+ def __repr__(self):
+ return repr(self.__dict__)
+
+ def __eq__(self, other):
+ return isinstance(other, self.__class__) and self.groupName ==
other.groupName and self.userId == other.userId and self.ipProtocol ==
other.ipProtocol and self.fromPort == other.fromPort and self.toPort ==
other.toPort and self.cidrIp == other.cidrIp
+
+ def __ne__(self, other):
+ return not (self == other)
+
+class Image(object):
+ def __init__(self, d=None):
+ self.userId = None
+ self.imageId = None
+ self.isPublic = False
+ self.explicitUserIds = []
+ self.s3path = None
+ self.productCode = ''
+ if isinstance(d, dict):
+ if 'userId' in d:
+ self.userId = d['userId']
+ if 'imageId' in d:
+ self.imageId = d['imageId']
+ if 'isPublic' in d:
+ self.isPublic = d['isPublic']
+ if 'explicitUserIds' in d:
+ self.explicitUserIds = d['explicitUserIds']
+ if 's3path' in d:
+ self.s3path = d['s3path']
+ if 'productCode' in d:
+ self.productCode = d['productCode']
+
+ def __str__(self):
+ return str(self.__dict__)
+
+ def __repr__(self):
+ return repr(self.__dict__)
+
+ def __eq__(self, other):
+ return isinstance(other, self.__class__) and self.imageId ==
other.imageId and self.userId == other.userId
+
+ def __ne__(self, other):
+ return not (self == other)
+
+class Address(object):
+ def __init__(self, d=None):
+ self.userId = None
+ self.publicIp = None
+ self.instanceId = None
+ if 'userId' in d:
+ self.userId = d['userId']
+ if 'publicIp' in d:
+ self.publicIp = d['publicIp']
+ if 'instanceId' in d:
+ self.instanceId = d['instanceId']
+
+ def __str__(self):
+ return str(self.__dict__)
+
+ def __repr__(self):
+ return repr(self.__dict__)
+
+ def __eq__(self, other):
+ return isinstance(other, self.__class__) and self.userId ==
other.userId and self.publicIp == other.publicIp
+
+ def __ne__(self, other):
+ return not (self == other)
Index: src/tashi/aws/impl/keys.py
===================================================================
--- src/tashi/aws/impl/keys.py (revision 828282)
+++ src/tashi/aws/impl/keys.py (working copy)
@@ -17,21 +17,63 @@
from tashi.aws.wsdl.AmazonEC2_services_server import *
from tashi.aws.util import *
+from tashi.rpycservices.rpyctypes import *
+import os
+import re
-def CreateKeyPair():
- raise NotImplementedError
+def CreateKeyPair(keyName):
+ res = CreateKeyPairResponseMsg()
+ res.requestId = genRequestId()
+ res.keyName = keyName
+ privkeyfile = awsdir + 'id_rsa.tmp'
+ pubkeyfile = awsdir + 'id_rsa.tmp.pub'
+ fingerprintfile = awsdir + 'fingerprint.tmp'
+ try:
+ os.remove(privkeyfile)
+ except:
+ pass
+ os.system('ssh-keygen -t rsa -b 2048 -f ' + privkeyfile + ' -P "" > ' +
fingerprintfile)
+ infile = open(privkeyfile, 'r')
+ privkey = infile.read()
+ infile.close()
+ infile = open(pubkeyfile, 'r')
+ pubkey = infile.read()
+ infile.close()
+ infile = open(fingerprintfile, 'r')
+ fingerprint = infile.read()
+ infile.close()
+ fingerprint = re.findall('The key fingerprint is:\s+(\S+)\s+',
fingerprint)[0]
+ res.keyFingerprint = fingerprint
+ res.keyMaterial = privkey
+ os.remove(privkeyfile)
+ os.remove(pubkeyfile)
+ os.remove(fingerprintfile)
+ userId = userNameToId(tashi.aws.util.authorizedUser)
+
awsdata.registerKey(Key({'userId':userId,'keyName':keyName,'fingerprint':fingerprint,'pubkey':pubkey,'privkey':privkey}))
+ return res
-def DescribeKeyPairs():
+def DescribeKeyPairs(keySet={}):
res = DescribeKeyPairsResponseMsg()
res.requestId = genRequestId()
res.keySet = res.new_keySet()
- item = res.keySet.new_item()
- item.keyName = "fake"
- item.keyFingerprint = "missing"
- res.keySet.item = [item]
+ res.keySet.item = []
+ userId = userNameToId(tashi.aws.util.authorizedUser)
+ for key in awsdata.getKeys(userId):
+ item = res.keySet.new_item()
+ item.keyName = key.keyName
+ item.keyFingerprint = key.fingerprint
+ res.keySet.item.append(item)
return res
-def DeleteKeyPair():
- raise NotImplementedError
+def DeleteKeyPair(keyName):
+ res = DeleteKeyPairResponseMsg()
+ res.requestId = genRequestId()
+ res.__dict__['return'] = True
+ userId = userNameToId(tashi.aws.util.authorizedUser)
+ try:
+ awsdata.removeKey(userId, keyName)
+ except:
+ res.__dict__['return'] = False
+ return res
functions = ['CreateKeyPair', 'DescribeKeyPairs', 'DeleteKeyPair']
Index: src/tashi/aws/impl/other.py
===================================================================
--- src/tashi/aws/impl/other.py (revision 828282)
+++ src/tashi/aws/impl/other.py (working copy)
@@ -15,9 +15,19 @@
# specific language governing permissions and limitations
# under the License.
+from tashi.aws.wsdl.AmazonEC2_services_server import *
from tashi.aws.util import *
-def ConfirmProductInstance():
- raise NotImplementedError
+def ConfirmProductInstance(productCode, instanceId):
+ res = ConfirmProductInstanceResponseMsg()
+ res.requestId = genRequestId()
+ res.__dict__['return'] = True
+ for i in client.getInstances():
+ if i.id == int(instanceId):
+ res.ownerId = i.userId
+ break
+ else:
+ res.__dict__['return'] = False
+ return res
functions = ['ConfirmProductInstance']
Index: src/tashi/aws/impl/address.py
===================================================================
--- src/tashi/aws/impl/address.py (revision 828282)
+++ src/tashi/aws/impl/address.py (working copy)
@@ -15,21 +15,70 @@
# specific language governing permissions and limitations
# under the License.
+from tashi.aws.wsdl.AmazonEC2_services_server import *
from tashi.aws.util import *
+from tashi.rpycservices.rpyctypes import *
def AllocateAddress():
- raise NotImplementedError
+ res = AllocateAddressResponseMsg()
+ res.requestId = genRequestId()
+ # To Do, reserve an available ip address.
+ # client.getAddress()
+ res.publicIp = '0.0.0.0'
+ userId = userNameToId(tashi.aws.util.authorizedUser)
+
awsdata.registerAddress(Address({'userId':userId,'publicIp':res.publicIp}))
+ return res
-def ReleaseAddress():
- raise NotImplementedError
+def ReleaseAddress(publicIp):
+ res = ReleaseAddressResponseMsg()
+ res.requestId = genRequestId()
+ # To Do, release a reserved ip address.
+ # client.releaseAddress()
+ userId = userNameToId(tashi.aws.util.authorizedUser)
+ res.__dict__['return'] = True
+ try:
+ awsdata.removeAddress(userId, publicIp)
+ except:
+ res.__dict__['return'] = False
+ return res
-def DescribeAddresses():
- raise NotImplementedError
+def DescribeAddresses(publicIpsSet={}):
+ res = DescribeAddressesResponseMsg()
+ res.requestId = genRequestId()
+ userId = userNameToId(tashi.aws.util.authorizedUser)
+ res.addressesSet = res.new_addressesSet()
+ res.addressesSet.item = []
+ for address in awsdata.getAddresses(userId):
+ addressItem = res.addressesSet.new_item()
+ addressItem.publicIp = address.publicIp
+ addressItem.instanceId = address.instanceId
+ res.addressesSet.item.append(addressItem)
+ return res
-def AssociateAddress():
- raise NotImplementedError
+def AssociateAddress(instanceId, publicIp):
+ res = AssociateAddressResponseMsg()
+ res.requestId = genRequestId()
+ res.__dict__['return'] = True
+ userId = userNameToId(tashi.aws.util.authorizedUser)
+ try:
+ awsdata.associateAddress(userId, instanceId, publicIp)
+ # To Do, associate an Address
+ #client.associateAddress()
+ except:
+ res.__dict__['return'] = False
+ return res
-def DisassociateAddress():
- raise NotImplementedError
+def DisassociateAddress(publicIp):
+ res = DisassociateAddressResponseMsg()
+ res.requestId = genRequestId()
+ res.__dict__['return'] = True
+ userId = userNameToId(tashi.aws.util.authorizedUser)
+ try:
+ awsdata.dissociateAddress(userId, publicIp)
+ # To Do, associate an Address
+ #client.dissociateAddress()
+ except:
+ res.__dict__['return'] = False
+ return res
functions = ['AllocateAddress', 'ReleaseAddress', 'DescribeAddresses',
'AssociateAddress', 'DisassociateAddress']
Index: src/tashi/aws/impl/images.py
===================================================================
--- src/tashi/aws/impl/images.py (revision 828282)
+++ src/tashi/aws/impl/images.py (working copy)
@@ -17,16 +17,59 @@
import md5
import os.path
+import shutil
+import os
from tashi.aws.wsdl.AmazonEC2_services_server import *
from tashi.aws.util import *
+from tashi.rpycservices.rpyctypes import *
+import tashi.aws.util
-def RegisterImage():
- raise NotImplementedError
+def RegisterImage(imageLocation):
+ res = RegisterImageResponseMsg()
+ res.requestId = genRequestId()
+ userId = userNameToId(tashi.aws.util.authorizedUser)
+ res.imageId = "ami-%8.8s" % (md5.md5(imageLocation).hexdigest())
+
awsdata.registerImage(Image({'userId':userId,'imageId':res.imageId,'s3path':imageLocation}))
+ return res
-def DeregisterImage():
- raise NotImplementedError
+def DeregisterImage(imageId):
+ res = DeregisterImageResponseMsg()
+ res.requestId = genRequestId()
+ res.__dict__['return'] = True
+ userId = userNameToId(tashi.aws.util.authorizedUser)
+ try:
+ awsdata.removeImage(userId, imageId)
+ except:
+ res.__dict__['return'] = False
+ return res
-def DescribeImages(ownersSet={}, executableBySet={}, imagesSet={}):
+def _DescribeImages(ownersSet = {}, executableBySet = {}, imagesSet = {}):
+ # _DescribeImages is meant to be used when S3 is implemented.
+ res = DescribeImagesResponseMsg()
+ res.requestId = genRequestId()
+ res.imagesSet = res.new_imagesSet()
+ res.imagesSet.item = []
+ userId = userNameToId(tashi.aws.util.authorizedUser)
+ for img in awsdata.getImages(userId):
+ image = res.imagesSet.new_item()
+ image.imageId = img.imageId
+ image.imageLocation = img.s3path
+ image.imageState = 'available'
+ image.imageOwnerId = img.userId
+ image.isPublic = img.isPublic
+ image.productCodes = image.new_productCodes()
+ productCodeItem = image.productCodes.new_item()
+ productCodeItem.productCode = img.productCode
+ image.productCodes.item = [productCodeItem]
+ #image.architecture = None <string>
+ #image.imageType = None <string>
+ #image.kernelId = None <string>
+ #image.ramdiskId = None <string>
+ #image.platform = None <string>
+ res.imagesSet.item.append(image)
+ return res
+
+def DescribeImages(ownersSet = {}, executableBySet = {}, imagesSet = {}):
IMGDIR="/mnt/merkabah/tashi/images/"
res = DescribeImagesResponseMsg()
res.requestId = genRequestId()
@@ -57,13 +100,78 @@
res.imagesSet.item.append(image)
return res
-def ModifyImageAttribute():
- raise NotImplementedError
+def ModifyImageAttribute(imageId, launchPermission=None, productCodes=None):
+ # Account ids should probably be entered with leading 0's so that 12
character spaces are used.
+ # For some reason, only the 'all' group is allowed.
+ res = ModifyImageAttributeResponseMsg()
+ res.requestId = genRequestId()
+ userId = userNameToId(tashi.aws.util.authorizedUser)
+ res.__dict__['return'] = True
+ if launchPermission:
+ try:
+ if 'add' in launchPermission:
+ if 'group' in launchPermission['add']['item']:
+ targetUserId =
launchPermission['add']['item']['group']
+ elif 'userId' in
launchPermission['add']['item']:
+ targetUserId =
launchPermission['add']['item']['userId']
+ awsdata.addPermission(userId, targetUserId,
imageId)
+ if 'remove' in launchPermission:
+ if 'group' in
launchPermission['remove']['item']:
+ targetUserId =
launchPermission['remove']['item']['group']
+ elif 'userId' in
launchPermission['remove']['item']:
+ targetUserId =
launchPermission['remove']['item']['userId']
+ awsdata.removePermission(userId, targetUserId,
imageId)
+ except:
+ res.__dict__['return'] = False
+ if productCodes:
+ try:
+ awsdata.setProductCode(userId,
productCodes['item']['productCode'], imageId)
+ except:
+ res.__dict__['return'] = False
+ return res
-def ResetImageAttribute():
- raise NotImplementedError
+def ResetImageAttribute(launchPermission, imageId):
+ # res.__dict__['return'] is used to specify if there is an error.
+ res = ResetImageAttributeResponseMsg()
+ res.requestId = genRequestId()
+ userId = userNameToId(tashi.aws.util.authorizedUser)
+ res.__dict__['return'] = True
+ try:
+ awsdata.resetImage(userId, imageId)
+ except:
+ res.__dict__['return'] = False
+ return res
-def DescribeImageAttribute():
- raise NotImplementedError
+def DescribeImageAttribute(imageId, launchPermission=True, productCodes=True,
kernel=True, ramdisk=True, blockDeviceMapping=True, platform=True):
+ res = DescribeImageAttributeResponseMsg()
+ res.requestId = genRequestId()
+ res.imageId = imageId
+ userId = userNameToId(tashi.aws.util.authorizedUser)
+ images = awsdata.getImages(userId)
+ res.launchPermission = res.new_launchPermission()
+ res.launchPermission.item = []
+ index = images.index(Image({'userId':userId,'imageId':imageId}))
+ image = images[index]
+ if not launchPermission:
+ if image.isPublic:
+ launchPermissionItem = res.launchPermission.new_item()
+ launchPermissionItem.group = 'all'
+ res.launchPermission.item.append(launchPermissionItem)
+ else:
+ for explicitUserId in image.explicitUserIds:
+ launchPermissionItem =
res.launchPermission.new_item()
+ launchPermissionItem.userId = explicitUserId
+
res.launchPermission.item.append(launchPermissionItem)
+ elif not productCodes:
+ pass
+ elif not kernel:
+ pass
+ elif not ramdisk:
+ pass
+ elif not blockDeviceMapping:
+ pass
+ elif not platform:
+ pass
+ return res
functions = ['RegisterImage', 'DeregisterImage', 'DescribeImages',
'ModifyImageAttribute', 'ResetImageAttribute', 'DescribeImageAttribute']
Index: src/tashi/aws/impl/injectkey.py
===================================================================
--- src/tashi/aws/impl/injectkey.py (revision 0)
+++ src/tashi/aws/impl/injectkey.py (revision 0)
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+
+import sys
+import pexpect
+
+def injectKey(instanceName, pubkey, loginId='root', loginPassword='changeme'):
+ # The vm is not up at this point either.
+ expect = pexpect.spawn('ssh %...@%s "mkdir -p .ssh; echo \'%s\' >>
~/.ssh/authorized_keys"' % (loginId, instanceName, pubkey))
+ expect.expect('.*ssword:')
+ expect.sendline(loginPassword)
+ expect.expect(pexpect.EOF)
+ #To Do: Disable password authentication.
+
+if __name__ == '__main__':
+ if len(sys.argv) < 3:
+ print 'usage: injectkey.py instanceName pubkey'
+ exit()
+ instanceName = sys.argv[1]
+ pubkey = sys.argv[2]
+ injectKey(instanceName, pubkey, loginId='root',
loginPassword='changeme')
Property changes on: src/tashi/aws/impl/injectkey.py
___________________________________________________________________
Added: svn:executable
+ *
Index: src/tashi/aws/impl/instances.py
===================================================================
--- src/tashi/aws/impl/instances.py (revision 828282)
+++ src/tashi/aws/impl/instances.py (working copy)
@@ -23,6 +23,7 @@
from tashi.rpycservices.rpyctypes import *
from tashi.aws.util import *
import tashi.aws.util
+import tashi
def getImages():
IMGDIR="/mnt/merkabah/tashi/images/"
@@ -97,8 +98,6 @@
inst.hints = {}
oldInst = inst
inst = client.createVm(oldInst)
- res = RunInstancesResponseMsg()
- res.requestId = genRequestId()
res.reservationId = 'r-12345678'
res.ownerId = 'UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM'
res.groupSet = res.new_groupSet()
@@ -157,6 +156,8 @@
if (userName == tashi.aws.util.authorizedUser):
instanceItem = makeTashiInstanceEC2Instance(inst)
item.instancesSet.item.append(instanceItem)
+ # For some reason, if item.instancesSet is empty,
+ # "Server: Processing Failure is printed out on the command line.
item.requesterId = '1234'
res.reservationSet.item = [item]
return res
Index: src/tashi/aws/impl/monitor.py
===================================================================
--- src/tashi/aws/impl/monitor.py (revision 828282)
+++ src/tashi/aws/impl/monitor.py (working copy)
@@ -15,10 +15,20 @@
# specific language governing permissions and limitations
# under the License.
+from tashi.aws.wsdl.AmazonEC2_services_server import *
from tashi.aws.util import *
-def MonitorInstances():
- raise NotImplementedError
+def MonitorInstances(instancesSet):
+ # Not sure whether the returned information is correct.
+ res = MonitorInstancesResponseMsg()
+ res.requestId = genRequestId()
+ res.instancesSet = res.new_instancesSet()
+ item = res.instancesSet.new_item()
+ item.instanceId = instancesSet['item']['instanceId']
+ item.monitoring = item.new_monitoring()
+ item.monitoring.state = 'Normal'
+ res.instancesSet.item = [item]
+ return res
def UnmonitorInstances():
raise NotImplementedError
Index: src/tashi/aws/impl/security.py
===================================================================
--- src/tashi/aws/impl/security.py (revision 828282)
+++ src/tashi/aws/impl/security.py (working copy)
@@ -17,24 +17,113 @@
from tashi.aws.wsdl.AmazonEC2_services_server import *
from tashi.aws.util import *
+from tashi.rpycservices.rpyctypes import *
-def CreateSecurityGroup():
- raise NotImplementedError
+def CreateSecurityGroup(groupName, groupDescription):
+ res = CreateSecurityGroupResponseMsg()
+ res.requestId = genRequestId()
+ res.__dict__['return'] = True
+ userId = userNameToId(tashi.aws.util.authorizedUser)
+ try:
+
awsdata.registerGroup(Group({'userId':userId,'groupName':groupName,'groupDescription':groupDescription}))
+ except Exception, e:
+ res.__dict__['return'] = False
+ return res
-def DeleteSecurityGroup():
- raise NotImplementedError
+def DeleteSecurityGroup(groupName):
+ res = DeleteSecurityGroupResponseMsg()
+ res.requestId = genRequestId()
+ userId = userNameToId(tashi.aws.util.authorizedUser)
+ res.__dict__['return'] = True
+ try:
+ awsdata.removeGroup(userId, groupName)
+ except:
+ res.__dict__['return'] = False
+ return res
-def DescribeSecurityGroups():
+def DescribeSecurityGroups(securityGroupSet = None):
res = DescribeSecurityGroupsResponseMsg()
res.requestId = genRequestId()
res.securityGroupInfo = res.new_securityGroupInfo()
res.securityGroupInfo.item = []
+ userId = userNameToId(tashi.aws.util.authorizedUser)
+ for group in awsdata.getGroups(userId):
+ item = res.securityGroupInfo.new_item()
+ item.ownerId = group.userId
+ item.groupName = group.groupName
+ item.groupDescription = group.groupDescription
+ item.ipPermissions = item.new_ipPermissions()
+ item.ipPermissions.item = []
+ for ipPermission in group.ipPermissions:
+ ipPermissionsItem = item.ipPermissions.new_item()
+ ipPermissionsItem.ipProtocol = ipPermission.ipProtocol
+ ipPermissionsItem.fromPort = int(ipPermission.fromPort)
+ ipPermissionsItem.toPort = int(ipPermission.toPort)
+ ipPermissionsItem.groups =
ipPermissionsItem.new_groups()
+ ipPermissionsItem.groups.item = []
+ for groupPermission in ipPermission.groupPermissions:
+ groupPermissionsItem =
ipPermissionsItem.groups.new_item()
+ groupPermissionsItem.groupName =
groupPermission.groupName
+ groupPermissionsItem.userId =
groupPermission.targetUserId
+
ipPermissionsItem.groups.item.append(groupPermissionsItem)
+ ipPermissionsItem.ipRanges =
ipPermissionsItem.new_ipRanges()
+ ipPermissionsItem.ipRanges.item = []
+ ipRangesItem = ipPermissionsItem.ipRanges.new_item()
+ ipRangesItem.cidrIp = ipPermission.cidrIp
+ if ipRangesItem.cidrIp != None:
+
ipPermissionsItem.ipRanges.item.append(ipRangesItem)
+ item.ipPermissions.item.append(ipPermissionsItem)
+ res.securityGroupInfo.item.append(item)
return res
-def AuthorizeSecurityGroupIngress():
- raise NotImplementedError
+def AuthorizeSecurityGroupIngress(userId, groupName, ipPermissions):
+ res = AuthorizeSecurityGroupIngressResponseMsg()
+ res.requestId = genRequestId()
+ _userId = userNameToId(tashi.aws.util.authorizedUser)
+ res.__dict__['return'] = True
+ if userId != None and userId != _userId:
+ raise TashiException({'msg':'You do not own that security
group'})
+ ipProtocol = ipPermissions['item']['ipProtocol']
+ toPort = ipPermissions['item']['toPort']
+ fromPort = ipPermissions['item']['fromPort']
+ cidrIp = None
+ if ipPermissions['item']['ipRanges']:
+ cidrIp = ipPermissions['item']['ipRanges']['item']['cidrIp']
+ groupPermissions = []
+ if ipPermissions['item']['groups']:
+ # Only one userId/groupName seems to get through even if you
put multiple userId/groupNames on the command line.
+
groupPermissions.append(GroupPermission({'targetUserId':ipPermissions['item']['groups']['item']['userId'],'groupName':ipPermissions['item']['groups']['item']['groupName']}))
+ try:
+
awsdata.addIpPermission(IpPermission({'userId':_userId,'groupName':groupName,'ipProtocol':ipProtocol,'toPort':toPort,'fromPort':fromPort,'cidrIp':cidrIp,'groupPermissions':groupPermissions}))
+ #To Do: change permission.
+ #client.changePermission()
+ except:
+ res.__dict__['return'] = False
+ return res
-def RevokeSecurityGroupIngress():
- raise NotImplementedError
+def RevokeSecurityGroupIngress(userId, groupName, ipPermissions):
+ res = RevokeSecurityGroupIngressResponseMsg()
+ res.requestId = genRequestId()
+ _userId = userNameToId(tashi.aws.util.authorizedUser)
+ res.__dict__['return'] = True
+ if userId != None and userId != _userId:
+ raise TashiException({'msg':'You do not own that security
group'})
+ ipProtocol = ipPermissions['item']['ipProtocol']
+ toPort = ipPermissions['item']['toPort']
+ fromPort = ipPermissions['item']['fromPort']
+ cidrIp = None
+ if ipPermissions['item']['ipRanges']:
+ cidrIp = ipPermissions['item']['ipRanges']['item']['cidrIp']
+ groupPermissions = []
+ if ipPermissions['item']['groups']:
+ # Only one userId/groupName seems to get through even if you
put multiple userId/groupNames on the command line.
+
groupPermissions.append(GroupPermission({'targetUserId':ipPermissions['item']['groups']['item']['userId'],'groupName':ipPermissions['item']['groups']['item']['groupName']}))
+ try:
+
awsdata.removeIpPermission(IpPermission({'userId':_userId,'groupName':groupName,'ipProtocol':ipProtocol,'toPort':toPort,'fromPort':fromPort,'cidrIp':cidrIp,'groupPermissions':groupPermissions}))
+ #To Do: change permission.
+ #client.changePermission()
+ except:
+ res.__dict__['return'] = False
+ return res
functions = ['CreateSecurityGroup', 'DeleteSecurityGroup',
'DescribeSecurityGroups', 'AuthorizeSecurityGroupIngress',
'RevokeSecurityGroupIngress']
Index: src/tashi/aws/impl/volume.py
===================================================================
--- src/tashi/aws/impl/volume.py (revision 828282)
+++ src/tashi/aws/impl/volume.py (working copy)
@@ -15,7 +15,9 @@
# specific language governing permissions and limitations
# under the License.
+from tashi.aws.wsdl.AmazonEC2_services_server import *
from tashi.aws.util import *
+from tashi.rpycservices.rpyctypes import *
def CreateVolume():
raise NotImplementedError
Index: src/tashi/aws/util.py
===================================================================
--- src/tashi/aws/util.py (revision 828282)
+++ src/tashi/aws/util.py (working copy)
@@ -16,13 +16,14 @@
# under the License.
import sys
+import tashi
+import tashi.aws.data
import traceback
import types
import uuid
+import trans
from xml.dom import minidom
from ZSI import SoapWriter
-import tashi
-import trans
sizes = {'m1.small': (int(1.7*1024), 1),
'm1.large': (int(7.5*1024), 4),
@@ -39,7 +40,7 @@
return obj
try:
if (getattr(obj, "__dict__", None)):
- for k in obj.__dict__.keys():
+ for k in obj.__dict__:
if (not k.startswith("_")):
setattr(obj, "_%s" % (k),
fixObject(getattr(obj, k)))
else:
@@ -91,6 +92,9 @@
return getattr(obj, name)
client = Lazy("tashi.createClient(tashi.getConfig()[0])")
+global awsdata
+awsdata = tashi.aws.data.Pickled(tashi.getConfig()[0])
+awsdir = '/tmp/'
users = {}
def userIdToName(id):
@@ -114,10 +118,9 @@
return users[name]
else:
return -1
-
-vars = {}
def genRequestId():
return str(uuid.uuid1())
-
+
+vars = {}
authorizedUser = "UNKNOWN"
Index: src/tashi/aws/data/datainterface.py
===================================================================
--- src/tashi/aws/data/datainterface.py (revision 0)
+++ src/tashi/aws/data/datainterface.py (revision 0)
@@ -0,0 +1,65 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License 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.
+
+class DataInterface(object):
+ def __init__(self, config):
+ self.config = config
+
+ def registerKey(self, key):
+ raise NotImplementedError
+
+ def removeKey(self, userId, keyName):
+ raise NotImplementedError
+
+ def getKeys(self, userId):
+ raise NotImplementedError
+
+ def registerGroup(self, group):
+ raise NotImplementedError
+
+ def getGroups(self, userId):
+ raise NotImplementedError
+
+ def removeGroup(self, userId, groupName):
+ raise NotImplementedError
+
+ def addIpPermission(self, ipPermission):
+ raise NotImplementedError
+
+ def removeIpPermission(self, ipPermission):
+ raise NotImplementedError
+
+ def registerImage(self, image):
+ raise NotImplementedError
+
+ def removeImage(self, userId, imageId):
+ raise NotImplementedError
+
+ def getImages(self, userId):
+ raise NotImplementedError
+
+ def addPermission(self, userId, targetUserId, imageId):
+ raise NotImplementedError
+
+ def removePermission(self, userId, targetUserId, imageId):
+ raise NotImplementedError
+
+ def setProductCode(self, userId, productCode, imageId):
+ raise NotImplementedError
+
+ def resetImage(self, userId, imageId):
+ raise NotImplementedError
Index: src/tashi/aws/data/pickled.py
===================================================================
--- src/tashi/aws/data/pickled.py (revision 0)
+++ src/tashi/aws/data/pickled.py (revision 0)
@@ -0,0 +1,160 @@
+from tashi.aws.data import DataInterface
+from tashi.aws.util import *
+from tashi.rpycservices.rpyctypes import *
+import cPickle
+import os
+
+class Pickled(DataInterface):
+ def __init__(self, config):
+ self.config = config
+ self.awsfile = config.get("AWS", "awsfile")
+ self.load()
+
+ def save(self):
+ outfile = open(self.awsfile, "w")
+ cPickle.dump((self.addresses, self.images, self.groups,
self.keys), outfile)
+ outfile.close()
+
+ def load(self):
+ if os.access(self.awsfile, os.F_OK):
+ infile = open(self.awsfile, "r")
+ (addresses, images, groups, keys) = cPickle.load(infile)
+ infile.close()
+ else:
+ (addresses, images, groups, keys) = ([], [], [], [])
+ self.addresses = addresses
+ self.images = images
+ self.groups = groups
+ self.keys = keys
+
+ def registerKey(self, key):
+ if key not in self.keys:
+ self.keys.append(key)
+ else:
+ raise TashiException({'msg':'Attempted to add duplicate
key'})
+ self.save()
+
+ def removeKey(self, userId, keyName):
+ self.keys.remove(Key({'userId':userId,'keyName':keyName}))
+ self.save()
+
+ def getKeys(self, userId):
+ def filterMyKeys(key):
+ return key.userId == userId
+ return filter(filterMyKeys, self.keys)
+
+ def registerGroup(self, group):
+ if group not in self.groups:
+ self.groups.append(group)
+ else:
+ raise TashiException({'msg':'Attempted to add duplicate
group'})
+ self.save()
+
+ def getGroups(self, userId):
+ def filterMyGroups(group):
+ return group.userId == userId
+ return filter(filterMyGroups, self.groups)
+
+ def removeGroup(self, userId, groupName):
+
self.groups.remove(Group({'userId':userId,'groupName':groupName}))
+ self.save()
+
+ def addIpPermission(self, ipPermission):
+ groupIndex =
self.groups.index(Group({'userId':ipPermission.userId,'groupName':ipPermission.groupName}))
+ group = self.groups[groupIndex]
+ if ipPermission in group.ipPermissions:
+ ipPermissionIndex =
group.ipPermissions.index(ipPermission)
+ group.ipPermissions[ipPermissionIndex].groupPermissions
+= ipPermission.groupPermissions
+ else:
+ group.ipPermissions.append(ipPermission)
+ self.save()
+
+ def removeIpPermission(self, ipPermission):
+ groupIndex =
self.groups.index(Group({'userId':ipPermission.userId,'groupName':ipPermission.groupName}))
+ group = self.groups[groupIndex]
+ if ipPermission in group.ipPermissions:
+ ipPermissionIndex =
group.ipPermissions.index(ipPermission)
+ for groupPermission in ipPermission.groupPermissions:
+
group.ipPermissions[ipPermissionIndex].groupPermissions.remove(groupPermission)
+ if
len(group.ipPermissions[ipPermissionIndex].groupPermissions) == 0:
+ group.ipPermissions.remove(ipPermission)
+ else:
+ raise TashiException({'msg':'Attempted to remove
ipPermission that does not exist'})
+ self.save()
+
+ def registerImage(self, image):
+ for img in self.images:
+ if img.imageId == image.imageId:
+ raise TashiException({'msg':'Attempted to add
duplicate image'})
+ self.images.append(image)
+ self.save()
+
+ def removeImage(self, userId, imageId):
+ self.images.remove(Image({'userId':userId,'imageId':imageId}))
+ self.save()
+
+ def getImages(self, userId):
+ def filterMyImages(image):
+ return image.userId == userId or image.isPublic or
userId in image.explicitUserIds
+ return filter(filterMyImages, self.images)
+
+ def addPermission(self, userId, targetUserId, imageId):
+ index =
self.images.index(Image({'userId':userId,'imageId':imageId}))
+ image = self.images[index]
+ if targetUserId == 'all':
+ image.isPublic = True
+ image.explicitUserIds = []
+ else:
+ image.explicitUserIds.append(targetUserId)
+ self.save()
+
+ def removePermission(self, userId, targetUserId, imageId):
+ index =
self.images.index(Image({'userId':userId,'imageId':imageId}))
+ image = self.images[index]
+ if targetUserId == 'all':
+ image.isPublic = False
+ image.explicitUserIds = []
+ else:
+ image.explicitUserIds.remove(targetUserId)
+ self.save()
+
+ def setProductCode(self, userId, productCode, imageId):
+ index =
self.images.index(Image({'userId':userId,'imageId':imageId}))
+ image = self.images[index]
+ if image.productCode == '':
+ image.productCode = productCode
+ self.save()
+
+ def resetImage(self, userId, imageId):
+ index =
self.images.index(Image({'userId':userId,'imageId':imageId}))
+ image = self.images[index]
+ image.isPublic = False
+ image.explicitUserIds = []
+ self.save()
+
+ def registerAddress(self, address):
+ self.addresses.append(address)
+ self.save()
+
+ def removeAddress(self, userId, publicIp):
+
self.addresses.remove(Address({'userId':userId,'publicIp':publicIp}))
+ self.save()
+
+ def getAddresses(self, userId):
+ def filterMyAddresses(address):
+ return address.userId == userId
+ return filter(filterMyAddresses, self.addresses)
+
+ def associateAddress(self, userId, instanceId, publicIp):
+ index =
self.addresses.index(Address({'userId':userId,'publicIp':publicIp}))
+ address = self.addresses[index]
+ if address.instanceId != None:
+ raise TashiException()
+ address.instanceId = instanceId
+ self.save()
+
+ def dissociateAddress(self, userId, publicIp):
+ index =
self.addresses.index(Address({'userId':userId,'publicIp':publicIp}))
+ address = self.addresses[index]
+ address.instanceId = None
+ self.save()
Index: src/tashi/aws/data/__init__.py
===================================================================
--- src/tashi/aws/data/__init__.py (revision 0)
+++ src/tashi/aws/data/__init__.py (revision 0)
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License 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.
+
+from datainterface import DataInterface
+from pickled import Pickled
Index: etc/TashiDefaults.cfg
===================================================================
--- etc/TashiDefaults.cfg (revision 828282)
+++ etc/TashiDefaults.cfg (working copy)
@@ -216,3 +216,5 @@
host = localhost
port = 1717
+[AWS]
+awsfile = /var/tmp/aws.dat