You are viewing a plain text version of this content. The canonical link for it is here.
Posted to tashi-commits@incubator.apache.org by mr...@apache.org on 2009/08/14 18:14:30 UTC
svn commit: r804314 - in /incubator/tashi/trunk: ./ src/tashi/aws/
src/tashi/aws/impl/ src/tashi/aws/wsdl/
Author: mryan3
Date: Fri Aug 14 18:14:29 2009
New Revision: 804314
URL: http://svn.apache.org/viewvc?rev=804314&view=rev
Log:
The first and very crude version of an EC2 compatibility layer
This supports a small subset of the SOAP and QUERY interfaces
It's enough, however, to allow elasticfox (and the ec2 command line tools) to list, create, and destroy VMs
Added:
incubator/tashi/trunk/src/tashi/aws/
incubator/tashi/trunk/src/tashi/aws/__init__.py
incubator/tashi/trunk/src/tashi/aws/impl/
incubator/tashi/trunk/src/tashi/aws/impl/__init__.py
incubator/tashi/trunk/src/tashi/aws/impl/address.py
incubator/tashi/trunk/src/tashi/aws/impl/bundle.py
incubator/tashi/trunk/src/tashi/aws/impl/images.py
incubator/tashi/trunk/src/tashi/aws/impl/instances.py
incubator/tashi/trunk/src/tashi/aws/impl/keys.py
incubator/tashi/trunk/src/tashi/aws/impl/location.py
incubator/tashi/trunk/src/tashi/aws/impl/monitor.py
incubator/tashi/trunk/src/tashi/aws/impl/other.py
incubator/tashi/trunk/src/tashi/aws/impl/reservation.py
incubator/tashi/trunk/src/tashi/aws/impl/security.py
incubator/tashi/trunk/src/tashi/aws/impl/volume.py
incubator/tashi/trunk/src/tashi/aws/query.py (with props)
incubator/tashi/trunk/src/tashi/aws/soap.py (with props)
incubator/tashi/trunk/src/tashi/aws/trans.py
incubator/tashi/trunk/src/tashi/aws/util.py
incubator/tashi/trunk/src/tashi/aws/wsdl/
incubator/tashi/trunk/src/tashi/aws/wsdl/__init__.py
Modified:
incubator/tashi/trunk/Makefile
Modified: incubator/tashi/trunk/Makefile
URL: http://svn.apache.org/viewvc/incubator/tashi/trunk/Makefile?rev=804314&r1=804313&r2=804314&view=diff
==============================================================================
--- incubator/tashi/trunk/Makefile (original)
+++ incubator/tashi/trunk/Makefile Fri Aug 14 18:14:29 2009
@@ -24,19 +24,33 @@
default: src/tashi/services bin src/utils/nmd
@echo Done
-all: src/tashi/services bin src/utils/nmd src/tags doc/html
+all: src/tashi/services bin src/utils/nmd src/tags doc/html aws
@echo Done
doc: rmdoc doc/html
@echo Done
-clean: rmnmd rmbin rmtags rmservices rmdoc
+clean: rmnmd rmbin rmtags rmservices rmdoc rmaws
if [ `find . -name "*.pyc" | wc -l` -gt 0 ]; then echo Removing python byte-code...; rm `find . -name "*.pyc"`; fi
@echo Done
version:
sed -i "s/version = .*/version = \"`date`\"/" src/tashi/version.py
+aws: src/tashi/aws/wsdl/AmazonEC2_services_types.py src/tashi/aws/wsdl/AmazonEC2_services_server.py
+
+src/tashi/aws/wsdl/AmazonEC2_services_types.py: src/tashi/aws/wsdl/2009-04-04.ec2.wsdl
+ (cd src/tashi/aws/wsdl; wsdl2py -b --file ./2009-04-04.ec2.wsdl)
+
+src/tashi/aws/wsdl/AmazonEC2_services_server.py: src/tashi/aws/wsdl/2009-04-04.ec2.wsdl
+ (cd src/tashi/aws/wsdl; wsdl2dispatch --file ./2009-04-04.ec2.wsdl)
+
+src/tashi/aws/wsdl/2009-04-04.ec2.wsdl:
+ wget -O src/tashi/aws/wsdl/2009-04-04.ec2.wsdl http://s3.amazonaws.com/ec2-downloads/2009-04-04.ec2.wsdl
+
+rmaws:
+ if test -e src/tashi/aws/wsdl/2009-04-04.ec2.wsdl; then echo Removing aws...; rm -f src/tashi/aws/wsdl/2009-04-04.ec2.wsdl; rm -f src/tashi/aws/wsdl/AmazonEC2_*.py; fi
+
# Implicit builds
src/utils/nmd: src/utils/Makefile src/utils/nmd.c
@echo Building nmd...
Added: incubator/tashi/trunk/src/tashi/aws/__init__.py
URL: http://svn.apache.org/viewvc/incubator/tashi/trunk/src/tashi/aws/__init__.py?rev=804314&view=auto
==============================================================================
--- incubator/tashi/trunk/src/tashi/aws/__init__.py (added)
+++ incubator/tashi/trunk/src/tashi/aws/__init__.py Fri Aug 14 18:14:29 2009
@@ -0,0 +1,16 @@
+# 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.
Added: incubator/tashi/trunk/src/tashi/aws/impl/__init__.py
URL: http://svn.apache.org/viewvc/incubator/tashi/trunk/src/tashi/aws/impl/__init__.py?rev=804314&view=auto
==============================================================================
--- incubator/tashi/trunk/src/tashi/aws/impl/__init__.py (added)
+++ incubator/tashi/trunk/src/tashi/aws/impl/__init__.py Fri Aug 14 18:14:29 2009
@@ -0,0 +1,16 @@
+# 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.
Added: incubator/tashi/trunk/src/tashi/aws/impl/address.py
URL: http://svn.apache.org/viewvc/incubator/tashi/trunk/src/tashi/aws/impl/address.py?rev=804314&view=auto
==============================================================================
--- incubator/tashi/trunk/src/tashi/aws/impl/address.py (added)
+++ incubator/tashi/trunk/src/tashi/aws/impl/address.py Fri Aug 14 18:14:29 2009
@@ -0,0 +1,35 @@
+# 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 tashi.aws.util import *
+
+def AllocateAddress():
+ raise NotImplementedError
+
+def ReleaseAddress():
+ raise NotImplementedError
+
+def DescribeAddresses():
+ raise NotImplementedError
+
+def AssociateAddress():
+ raise NotImplementedError
+
+def DisassociateAddress():
+ raise NotImplementedError
+
+functions = ['AllocateAddress', 'ReleaseAddress', 'DescribeAddresses', 'AssociateAddress', 'DisassociateAddress']
Added: incubator/tashi/trunk/src/tashi/aws/impl/bundle.py
URL: http://svn.apache.org/viewvc/incubator/tashi/trunk/src/tashi/aws/impl/bundle.py?rev=804314&view=auto
==============================================================================
--- incubator/tashi/trunk/src/tashi/aws/impl/bundle.py (added)
+++ incubator/tashi/trunk/src/tashi/aws/impl/bundle.py Fri Aug 14 18:14:29 2009
@@ -0,0 +1,29 @@
+# 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 tashi.aws.util import *
+
+def BundleInstance():
+ raise NotImplementedError
+
+def DescribeBundleTasks():
+ raise NotImplementedError
+
+def CancelBundleTask():
+ raise NotImplementedError
+
+functions = ['BundleInstance', 'DescribeBundleTasks', 'CancelBundleTask']
Added: incubator/tashi/trunk/src/tashi/aws/impl/images.py
URL: http://svn.apache.org/viewvc/incubator/tashi/trunk/src/tashi/aws/impl/images.py?rev=804314&view=auto
==============================================================================
--- incubator/tashi/trunk/src/tashi/aws/impl/images.py (added)
+++ incubator/tashi/trunk/src/tashi/aws/impl/images.py Fri Aug 14 18:14:29 2009
@@ -0,0 +1,69 @@
+# 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.
+
+import md5
+import os.path
+from tashi.aws.wsdl.AmazonEC2_services_server import *
+from tashi.aws.util import *
+
+def RegisterImage():
+ raise NotImplementedError
+
+def DeregisterImage():
+ raise NotImplementedError
+
+def DescribeImages(ownersSet={}, executableBySet={}, imagesSet={}):
+ IMGDIR="/mnt/merkabah/tashi/images/"
+ res = DescribeImagesResponseMsg()
+ res.requestId = genRequestId()
+ res.imagesSet = res.new_imagesSet()
+ res.imagesSet.item = []
+ imgList = os.listdir(IMGDIR)
+ for img in imgList:
+ fullImg = IMGDIR + img
+ if (os.path.isdir(fullImg)):
+ continue
+ owner = os.stat(fullImg)[4]
+ user = userIdToName(owner)
+ if (owner == 0 or user == tashi.aws.util.authorizedUser):
+ image = res.imagesSet.new_item()
+ #image.imageId = "tmi-%8.8s" % (md5.md5(img).hexdigest())
+ # This must be "ami" or else elasticfox won't display it
+ image.imageId = "ami-%8.8s" % (md5.md5(img).hexdigest())
+ image.imageLocation = img
+ image.imageState = "available"
+ image.imageOwnerId = "%12.12d" % (owner)
+ image.isPublic = (owner == 0)
+ #image.productCodes = None <ProductCodesSetType>
+ #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 ModifyImageAttribute():
+ raise NotImplementedError
+
+def ResetImageAttribute():
+ raise NotImplementedError
+
+def DescribeImageAttribute():
+ raise NotImplementedError
+
+functions = ['RegisterImage', 'DeregisterImage', 'DescribeImages', 'ModifyImageAttribute', 'ResetImageAttribute', 'DescribeImageAttribute']
Added: incubator/tashi/trunk/src/tashi/aws/impl/instances.py
URL: http://svn.apache.org/viewvc/incubator/tashi/trunk/src/tashi/aws/impl/instances.py?rev=804314&view=auto
==============================================================================
--- incubator/tashi/trunk/src/tashi/aws/impl/instances.py (added)
+++ incubator/tashi/trunk/src/tashi/aws/impl/instances.py Fri Aug 14 18:14:29 2009
@@ -0,0 +1,164 @@
+# 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.
+
+import md5
+import os
+import random
+import time
+from tashi.aws.wsdl.AmazonEC2_services_server import *
+from tashi.rpycservices.rpyctypes import *
+from tashi.aws.util import *
+import tashi.aws.util
+
+def getImages():
+ IMGDIR="/mnt/merkabah/tashi/images/"
+ imgList = os.listdir(IMGDIR)
+ images = {}
+ for img in imgList:
+ fullImg = IMGDIR + img
+ if (os.path.isdir(fullImg)):
+ continue
+ imageId = "ami-%8.8s" % (md5.md5(img).hexdigest())
+ images[imageId] = img
+ return images
+
+def makeTashiInstanceEC2Instance(inst):
+ res = RunInstancesResponseMsg()
+ res = res.new_instancesSet()
+ instanceItem = res.new_item()
+ instanceItem.instanceId = "i-%8.8d" % (inst.id)
+ instanceItem.imageId = "ami-%8.8s" % (md5.md5(inst.disks[0].uri).hexdigest())
+ instanceItem.instanceState = instanceItem.new_instanceState()
+ instanceItem.instanceState.code = inst.state
+ instanceItem.instanceState.name = "%10.10s" % (tashi.vmStates[inst.state])
+ instanceItem.privateDnsName = inst.name
+ instanceItem.dnsName = str(inst.nics[0].ip)
+ #instanceItem.reason = 'None'
+ instanceItem.keyName = "%12.12d" % (inst.userId)
+ instanceItem.amiLaunchIndex = str(inst.id)
+ #instanceItem.productCodes = instanceItem.new_productCodes()
+ #productItem = instanceItem.productCodes.new_item()
+ #productItem.productCode = '774F4FF8'
+ #instanceItem.productCodes.item = [productItem]
+ sizeList = sizes.items()
+ sizeList.sort(cmp=lambda x, y: cmp(cmp(x[1][0], y[1][0]) + cmp(x[1][1], y[1][1]), 0))
+ sizeList.reverse()
+ mySize = 'undef'
+ for size in sizeList:
+ if (inst.memory <= size[1][0] and inst.cores <= size[1][1]):
+ mySize = size[0]
+ instanceItem.instanceType = mySize
+ instanceItem.launchTime = time.time()
+ instanceItem.placement = instanceItem.new_placement()
+ instanceItem.placement.availabilityZone = 'tashi'
+ #instanceItem.kernelId = 'aki-ba3adfd3'
+ #instanceItem.ramdiskId = 'ari-badbad00'
+ #instanceItem.platform = 'Linux'
+ instanceItem.monitoring = instanceItem.new_monitoring()
+ instanceItem.monitoring.state = 'OFF'
+ return instanceItem
+
+def RunInstances(imageId, minCount, maxCount, instanceType='m1.small', groupSet=None, keyName=None, additionalInfo="", userData={'data':None}, addressingType="", placement={'availabilityZone':None}, kernelId="", ramdiskId="", blockDeviceMapping={'virtualName':None,'deviceName':None}, monitoring={'enabled':False}):
+ inst = Instance()
+ inst.userId = userNameToId(tashi.aws.util.authorizedUser)
+ res = RunInstancesResponseMsg()
+ res.requestId = genRequestId()
+ if (additionalInfo == ""):
+ inst.name = tashi.aws.util.authorizedUser + res.requestId
+ else:
+ inst.name = additionalInfo
+ (inst.memory, inst.cores) = sizes.get(instanceType, (0, 0))
+ dc = DiskConfiguration()
+ images = getImages()
+ if (imageId in images):
+ dc.uri = images[imageId]
+ else:
+ dc.uri = imageId
+ dc.persistent = False
+ inst.disks = [dc]
+ nc = NetworkConfiguration()
+ nc.network = 999
+ nc.mac = '52:54:00:%2.2x:%2.2x:%2.2x' % (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
+ inst.nics = [nc]
+ 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()
+ item = res.groupSet.new_item()
+ item.groupId = '1234'
+ res.groupSet.item = [item]
+ res.instancesSet = res.new_instancesSet()
+ instanceItem = makeTashiInstanceEC2Instance(inst)
+ res.instancesSet.item = [instanceItem]
+ return res
+
+def GetConsoleOutput():
+ raise NotImplementedError
+
+def TerminateInstances(instancesSet={'item':{}}):
+ res = TerminateInstancesResponseMsg()
+ res.requestId = genRequestId()
+ res.instancesSet = res.new_instancesSet()
+ items = []
+ if (instancesSet):
+ for instanceId in instancesSet['item'].values():
+ thisInstanceId = int(filter(lambda x: x in "0123456789", instanceId))
+ item = res.instancesSet.new_item()
+ item.instanceId = str(instanceId)
+ item.shutdownState = item.new_shutdownState()
+ item.shutdownState.code = InstanceState.Exited
+ item.shutdownState.name = tashi.vmStates[InstanceState.Exited]
+ item.previousState = item.new_previousState()
+ item.previousState.code = InstanceState.Running
+ item.previousState.name = tashi.vmStates[InstanceState.Running]
+ client.destroyVm(int(thisInstanceId))
+ items.append(item)
+ res.instancesSet.item = items
+ return res
+
+def RebootInstances():
+ raise NotImplementedError
+
+def DescribeInstances(instancesSet={}):
+ instances = client.getInstances()
+ res = DescribeInstancesResponseMsg()
+ res.requestId = genRequestId()
+ res.reservationSet = res.new_reservationSet()
+ item = res.reservationSet.new_item()
+ item.reservationId = 'r-12345678'
+ item.ownerId = 'UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM'
+ item.groupSet = item.new_groupSet()
+ groupItem = item.groupSet.new_item()
+ groupItem.groupId = 'default'
+ item.groupSet.item = [groupItem]
+ item.instancesSet = item.new_instancesSet()
+ item.instancesSet.item = []
+ instances.sort(cmp=lambda x, y: cmp(x.id, y.id))
+ for inst in instances:
+ userName = userIdToName(inst.userId)
+ if (userName == tashi.aws.util.authorizedUser):
+ instanceItem = makeTashiInstanceEC2Instance(inst)
+ item.instancesSet.item.append(instanceItem)
+ item.requesterId = '1234'
+ res.reservationSet.item = [item]
+ return res
+
+functions = ['RunInstances', 'GetConsoleOutput', 'TerminateInstances', 'RebootInstances', 'DescribeInstances']
Added: incubator/tashi/trunk/src/tashi/aws/impl/keys.py
URL: http://svn.apache.org/viewvc/incubator/tashi/trunk/src/tashi/aws/impl/keys.py?rev=804314&view=auto
==============================================================================
--- incubator/tashi/trunk/src/tashi/aws/impl/keys.py (added)
+++ incubator/tashi/trunk/src/tashi/aws/impl/keys.py Fri Aug 14 18:14:29 2009
@@ -0,0 +1,37 @@
+# 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 tashi.aws.wsdl.AmazonEC2_services_server import *
+from tashi.aws.util import *
+
+def CreateKeyPair():
+ raise NotImplementedError
+
+def DescribeKeyPairs():
+ 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]
+ return res
+
+def DeleteKeyPair():
+ raise NotImplementedError
+
+functions = ['CreateKeyPair', 'DescribeKeyPairs', 'DeleteKeyPair']
Added: incubator/tashi/trunk/src/tashi/aws/impl/location.py
URL: http://svn.apache.org/viewvc/incubator/tashi/trunk/src/tashi/aws/impl/location.py?rev=804314&view=auto
==============================================================================
--- incubator/tashi/trunk/src/tashi/aws/impl/location.py (added)
+++ incubator/tashi/trunk/src/tashi/aws/impl/location.py Fri Aug 14 18:14:29 2009
@@ -0,0 +1,43 @@
+# 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.
+
+import socket
+from tashi.aws.wsdl.AmazonEC2_services_server import *
+from tashi.aws.util import *
+
+def DescribeAvailabilityZones(availabilityZoneSet={}):
+ res = DescribeAvailabilityZonesResponseMsg()
+ res.requestId = genRequestId()
+ res.availabilityZoneInfo = res.new_availabilityZoneInfo()
+ item = res.availabilityZoneInfo.new_item()
+ item.zoneName = 'tashi'
+ item.zoneState = 'available'
+ item.regionName = 'here'
+ res.availabilityZoneInfo.item = [item]
+ return res
+
+def DescribeRegions(regionSet={}):
+ res = DescribeRegionsResponseMsg()
+ res.requestId = genRequestId()
+ res.regionInfo = res.new_regionInfo()
+ item = res.regionInfo.new_item()
+ item.regionName = "here"
+ item.regionEndpoint = socket.getfqdn()
+ res.regionInfo.item = [item]
+ return res
+
+functions = ['DescribeAvailabilityZones', 'DescribeRegions']
Added: incubator/tashi/trunk/src/tashi/aws/impl/monitor.py
URL: http://svn.apache.org/viewvc/incubator/tashi/trunk/src/tashi/aws/impl/monitor.py?rev=804314&view=auto
==============================================================================
--- incubator/tashi/trunk/src/tashi/aws/impl/monitor.py (added)
+++ incubator/tashi/trunk/src/tashi/aws/impl/monitor.py Fri Aug 14 18:14:29 2009
@@ -0,0 +1,26 @@
+# 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 tashi.aws.util import *
+
+def MonitorInstances():
+ raise NotImplementedError
+
+def UnmonitorInstances():
+ raise NotImplementedError
+
+functions = ['MonitorInstances', 'UnmonitorInstances']
Added: incubator/tashi/trunk/src/tashi/aws/impl/other.py
URL: http://svn.apache.org/viewvc/incubator/tashi/trunk/src/tashi/aws/impl/other.py?rev=804314&view=auto
==============================================================================
--- incubator/tashi/trunk/src/tashi/aws/impl/other.py (added)
+++ incubator/tashi/trunk/src/tashi/aws/impl/other.py Fri Aug 14 18:14:29 2009
@@ -0,0 +1,23 @@
+# 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 tashi.aws.util import *
+
+def ConfirmProductInstance():
+ raise NotImplementedError
+
+functions = ['ConfirmProductInstance']
Added: incubator/tashi/trunk/src/tashi/aws/impl/reservation.py
URL: http://svn.apache.org/viewvc/incubator/tashi/trunk/src/tashi/aws/impl/reservation.py?rev=804314&view=auto
==============================================================================
--- incubator/tashi/trunk/src/tashi/aws/impl/reservation.py (added)
+++ incubator/tashi/trunk/src/tashi/aws/impl/reservation.py Fri Aug 14 18:14:29 2009
@@ -0,0 +1,29 @@
+# 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 tashi.aws.util import *
+
+def DescribeReservedInstancesOfferings():
+ raise NotImplementedError
+
+def PurchaseReservedInstancesOffering():
+ raise NotImplementedError
+
+def DescribeReservedInstances():
+ raise NotImplementedError
+
+functions = ['DescribeReservedInstancesOfferings', 'PurchaseReservedInstancesOffering', 'DescribeReservedInstances']
Added: incubator/tashi/trunk/src/tashi/aws/impl/security.py
URL: http://svn.apache.org/viewvc/incubator/tashi/trunk/src/tashi/aws/impl/security.py?rev=804314&view=auto
==============================================================================
--- incubator/tashi/trunk/src/tashi/aws/impl/security.py (added)
+++ incubator/tashi/trunk/src/tashi/aws/impl/security.py Fri Aug 14 18:14:29 2009
@@ -0,0 +1,40 @@
+# 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 tashi.aws.wsdl.AmazonEC2_services_server import *
+from tashi.aws.util import *
+
+def CreateSecurityGroup():
+ raise NotImplementedError
+
+def DeleteSecurityGroup():
+ raise NotImplementedError
+
+def DescribeSecurityGroups():
+ res = DescribeSecurityGroupsResponseMsg()
+ res.requestId = genRequestId()
+ res.securityGroupInfo = res.new_securityGroupInfo()
+ res.securityGroupInfo.item = []
+ return res
+
+def AuthorizeSecurityGroupIngress():
+ raise NotImplementedError
+
+def RevokeSecurityGroupIngress():
+ raise NotImplementedError
+
+functions = ['CreateSecurityGroup', 'DeleteSecurityGroup', 'DescribeSecurityGroups', 'AuthorizeSecurityGroupIngress', 'RevokeSecurityGroupIngress']
Added: incubator/tashi/trunk/src/tashi/aws/impl/volume.py
URL: http://svn.apache.org/viewvc/incubator/tashi/trunk/src/tashi/aws/impl/volume.py?rev=804314&view=auto
==============================================================================
--- incubator/tashi/trunk/src/tashi/aws/impl/volume.py (added)
+++ incubator/tashi/trunk/src/tashi/aws/impl/volume.py Fri Aug 14 18:14:29 2009
@@ -0,0 +1,44 @@
+# 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 tashi.aws.util import *
+
+def CreateVolume():
+ raise NotImplementedError
+
+def DeleteVolume():
+ raise NotImplementedError
+
+def DescribeVolumes():
+ raise NotImplementedError
+
+def AttachVolume():
+ raise NotImplementedError
+
+def DetachVolume():
+ raise NotImplementedError
+
+def CreateSnapshot():
+ raise NotImplementedError
+
+def DeleteSnapshot():
+ raise NotImplementedError
+
+def DescribeSnapshots():
+ raise NotImplementedError
+
+functions = ['CreateVolume', 'DeleteVolume', 'DescribeVolumes', 'AttachVolume', 'DetachVolume', 'CreateSnapshot', 'DeleteSnapshot', 'DescribeSnapshots']
Added: incubator/tashi/trunk/src/tashi/aws/query.py
URL: http://svn.apache.org/viewvc/incubator/tashi/trunk/src/tashi/aws/query.py?rev=804314&view=auto
==============================================================================
--- incubator/tashi/trunk/src/tashi/aws/query.py (added)
+++ incubator/tashi/trunk/src/tashi/aws/query.py Fri Aug 14 18:14:29 2009
@@ -0,0 +1,88 @@
+#!/usr/bin/env python
+
+# 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.
+
+import base64
+import cgi
+import hashlib
+import hmac
+import md5
+import os
+import re
+import sys
+import time
+import traceback
+import types
+from ZSI.dispatch import _CGISendXML, _CGISendFault
+from ZSI import Fault
+
+from tashi.aws.wsdl.AmazonEC2_services_server import *
+from tashi.aws.impl import address, bundle, images, instances, keys, location, monitor, other, reservation, security, volume
+from tashi.aws.util import *
+import tashi.aws.util
+import tashi
+import trans
+
+for mod in [address, bundle, images, instances, keys, location, monitor, other, reservation, security, volume]:
+ for fname in mod.__dict__.get('functions', []):
+ globals()[fname] = QUERY(mod.__dict__.get(fname))
+
+userDict = {}
+def loadUserDict():
+ f = open("/var/lib/tashi-ec2/access.txt")
+ data = f.read()
+ f.close()
+ for l in data.split("\n"):
+ ws = l.strip().split()
+ if (len(ws) == 3):
+ (accessKey, secretAccessKey, authenticatedUser) = ws
+ userDict[accessKey] = (secretAccessKey, authenticatedUser)
+
+def AsQuery():
+ '''Handle the Amazon QUERY interface'''
+ try:
+ form = cgi.FieldStorage()
+ args = {}
+ signStr = ""
+ for var in form:
+ args[var] = form[var].value
+ if (var != "Signature"):
+ signStr += var + args[var]
+ log("[QUERY] %s=%s\n" % (var, args[var]))
+ secretKey = userDict[args['AWSAccessKeyId']][0]
+ calculatedSig = base64.b64encode(hmac.new(secretKey, signStr, hashlib.sha1).digest())
+ if (args['Signature'] != calculatedSig):
+ _CGISendFault(Fault(Fault.Client, 'Could not authenticate'))
+ return
+ tashi.aws.util.authorizedUser = userDict[args['AWSAccessKeyId']][1]
+ log("[AUTH] authorizedUser = %s\n" % (tashi.aws.util.authorizedUser))
+ functionName = args['Action']
+ res = eval("%s(args)" % (functionName))
+ _CGISendXML(res)
+ except Exception, e:
+ _CGISendFault(Fault(Fault.Client, str(e)))
+
+if __name__ == "__main__" :
+ log("%s\n" % (str(time.time())))
+ for var in os.environ:
+ log("[CGI] %s=%s\n" % (var, os.environ[var]))
+ try:
+ loadUserDict()
+ AsQuery()
+ except:
+ log("%s\n" % (traceback.format_exc(sys.exc_info())))
Propchange: incubator/tashi/trunk/src/tashi/aws/query.py
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/tashi/trunk/src/tashi/aws/soap.py
URL: http://svn.apache.org/viewvc/incubator/tashi/trunk/src/tashi/aws/soap.py?rev=804314&view=auto
==============================================================================
--- incubator/tashi/trunk/src/tashi/aws/soap.py (added)
+++ incubator/tashi/trunk/src/tashi/aws/soap.py Fri Aug 14 18:14:29 2009
@@ -0,0 +1,101 @@
+#!/usr/bin/env python
+
+# 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.
+
+import md5
+import os
+import re
+import sys
+import time
+import traceback
+import ZSI.dispatch
+from ZSI.dispatch import _Dispatch, _CGISendXML, _CGISendFault
+from ZSI import ParseException, ParsedSoap, Fault
+from ZSI import resolvers
+from xml.dom import minidom
+
+from tashi.aws.wsdl.AmazonEC2_services_server import *
+from tashi.aws.impl import address, bundle, images, instances, keys, location, monitor, other, reservation, security, volume
+from tashi.aws.util import *
+import tashi.aws.util
+
+for mod in [address, bundle, images, instances, keys, location, monitor, other, reservation, security, volume]:
+ for fname in mod.__dict__.get('functions', []):
+ globals()[fname] = SOAPRPC(mod.__dict__.get(fname))
+
+class ValidateParsedSoap(ParsedSoap):
+ def __init__(self, input, *args, **kw):
+ if (not self.validate(input)):
+ return
+ ParsedSoap.__init__(self, input, *args, **kw)
+
+ def validate(self, xml):
+ '''A simple blob of code that validates the xmldsig in an xml string using xmlsec1'''
+ doc = minidom.parseString(xml)
+ tokens = doc.getElementsByTagName("wsse:BinarySecurityToken")
+ if (len(tokens) != 1):
+ return -1
+ token = tokens[0]
+ if (len(token.childNodes) != 1):
+ return -1
+ childNode = token.childNodes[0]
+ if (not getattr(childNode, 'wholeText', None)):
+ return -1
+ cert = childNode.wholeText
+ CERT_DIGEST = md5.md5(cert).hexdigest()
+ log("[AUTH] CERT_DIGEST=%s\n" % (CERT_DIGEST))
+ output = xml
+ ofile = "/tmp/%5.5d.%s.xml" % (os.getpid(), md5.md5(output).hexdigest())
+ f2 = open(ofile, "w")
+ f2.write(output)
+ f2.close()
+ (stdin, stdout) = os.popen4("xmlsec1 --verify --id-attr:Id Timestamp --id-attr:Id Body --pubkey-cert-pem /var/lib/tashi-ec2/%s.crt --print-debug %s" % (CERT_DIGEST, ofile))
+ stdin.close()
+ res = stdout.read()
+ stdout.close()
+ os.unlink(ofile)
+ verified = False
+ lines = res.split("\n")
+ cmpRe = re.compile('==== Subject Name: (.*)')
+ for line in lines:
+ if (line.strip() == "OK"):
+ verified = True
+ res = cmpRe.match(line)
+ if (res):
+ varStrs = res.groups()[0].split("/")
+ for var in varStrs:
+ (key, sep, val) = var.partition("=")
+ if (key != '' and val != ''):
+ vars[key] = val
+ if (not verified):
+ _CGISendFault(Fault(Fault.Client, 'Could not authenticate'))
+ return verified
+ tashi.aws.util.authorizedUser = vars.get('CN', 'UNKNOWN')
+ log("[AUTH] authorizedUser = %s\n" % (tashi.aws.util.authorizedUser))
+ return verified
+
+ZSI.dispatch.ParsedSoap = ValidateParsedSoap
+
+if __name__ == "__main__" :
+ log("%s\n" % (str(time.time())))
+ for var in os.environ:
+ log("[CGI] %s=%s\n" % (var, os.environ[var]))
+ try:
+ ZSI.dispatch.AsCGI()
+ except:
+ log("%s\n" % (traceback.format_exc(sys.exc_info())))
Propchange: incubator/tashi/trunk/src/tashi/aws/soap.py
------------------------------------------------------------------------------
svn:executable = *
Added: incubator/tashi/trunk/src/tashi/aws/trans.py
URL: http://svn.apache.org/viewvc/incubator/tashi/trunk/src/tashi/aws/trans.py?rev=804314&view=auto
==============================================================================
--- incubator/tashi/trunk/src/tashi/aws/trans.py (added)
+++ incubator/tashi/trunk/src/tashi/aws/trans.py Fri Aug 14 18:14:29 2009
@@ -0,0 +1,67 @@
+# 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.
+
+import types
+
+def transArgsHelper(functionName, args):
+ if (type(args) == types.StringType):
+ return args
+ for key in ['Action', 'AWSAccessKeyId', 'SignatureVersion', 'Timestamp', 'Version', 'Signature']:
+ if key in args:
+ del args[key]
+ for key in args.keys():
+ firstChar = key[0]
+ if (firstChar.lower() != firstChar):
+ args[firstChar.lower() + key[1:]] = args[key]
+ del args[key]
+ for key in args.keys():
+ if (key.find(".") != -1):
+ (base, sep, sub) = key.partition(".")
+ args[base] = args.get(base, {})
+ args[base][sub] = args[key]
+ del args[key]
+ for key in args.keys():
+ args[key] = transArgsHelper(functionName, args[key])
+ return args
+
+def transArgs(functionName, args):
+ args = transArgsHelper(functionName, args)
+ if (functionName == 'TerminateInstances'):
+ args['instancesSet'] = {'item':args['instanceId']}
+ del args['instanceId']
+ return args
+
+def transNode(node):
+ try:
+ for i in range(0, len(node.childNodes)):
+ node.childNodes[i] = transNode(node.childNodes[i])
+ node.nodeName = node.nodeName.replace("ns1:", "")
+ except:
+ pass
+ return node
+
+def transResult(functionName, doc):
+ try:
+ newRoot = transNode(doc.getElementsByTagName("ns1:" + functionName + "Response")[0])
+ newRoot.setAttribute('xmlns', 'http://ec2.amazonaws.com/doc/2009-03-01/')
+ newRoot.removeAttribute('xsi:type')
+ response = newRoot.cloneNode(True)
+ responseStr = '<?xml version="1.0"?>\n' + str(response.toxml())
+ return responseStr
+ except Exception, e:
+ _CGISendFault(Fault(Fault.Client, str(e)))
+ return 0
Added: incubator/tashi/trunk/src/tashi/aws/util.py
URL: http://svn.apache.org/viewvc/incubator/tashi/trunk/src/tashi/aws/util.py?rev=804314&view=auto
==============================================================================
--- incubator/tashi/trunk/src/tashi/aws/util.py (added)
+++ incubator/tashi/trunk/src/tashi/aws/util.py Fri Aug 14 18:14:29 2009
@@ -0,0 +1,123 @@
+# 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.
+
+import sys
+import traceback
+import types
+import uuid
+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),
+ 'm1.xlarge': (int(15*1024), 8),
+ 'c1.medium': (int(1.7*1024), 5),
+ 'c1.xlarge': (int(7*1024), 20),
+ }
+
+def log(s):
+ sys.stderr.write(s)
+
+def fixObject(obj):
+ if (type(obj) in [types.StringType, types.BooleanType, types.IntType, types.FloatType, types.NoneType, types.UnicodeType]):
+ return obj
+ try:
+ if (getattr(obj, "__dict__", None)):
+ for k in obj.__dict__.keys():
+ if (not k.startswith("_")):
+ setattr(obj, "_%s" % (k), fixObject(getattr(obj, k)))
+ else:
+ obj = map(lambda x: fixObject(x), obj)
+ except:
+ log("%s\n" % (traceback.format_exc(sys.exc_info())))
+ log("%s\n" % (type(obj)))
+ return obj
+
+def SOAPRPC(oldFunc):
+ def newFunc(kw):
+ try:
+ log("%s(%s)\n" % (str(oldFunc.__name__), str(kw)))
+ if kw:
+ res = oldFunc(**kw)
+ else:
+ res = oldFunc()
+ res = fixObject(res)
+ log("%s(%s) -> %s\n" % (str(oldFunc.__name__), str(kw), str(res)))
+ return res
+ except:
+ log("%s\n" % (traceback.format_exc(sys.exc_info())))
+ raise
+ return newFunc
+
+def QUERY(oldFunc):
+ def newFunc(kw):
+ try:
+ log("%s(%s)\n" % (str(oldFunc.__name__), str(kw)))
+ kw = trans.transArgs(oldFunc.__name__, kw)
+ res = oldFunc(**kw)
+ res = fixObject(res)
+ log("%s(%s) -> %s\n" % (str(oldFunc.__name__), str(kw), str(res)))
+ sw = SoapWriter()
+ sw.serialize(res, res.typecode)
+ res = trans.transResult(oldFunc.__name__, minidom.parseString(str(sw)))
+ return res
+ except:
+ log("%s\n" % (traceback.format_exc(sys.exc_info())))
+ raise
+ return newFunc
+
+class Lazy(object):
+ def __init__(self, objString):
+ self._objString = objString
+
+ def __getattr__(self, name):
+ obj = eval(self._objString, locals(), globals())
+ return getattr(obj, name)
+
+client = Lazy("tashi.createClient(tashi.getConfig()[0])")
+
+users = {}
+def userIdToName(id):
+ if (users == {}):
+ _users = client.getUsers()
+ for user in _users:
+ users[user.id] = user.name
+ users[user.name] = id
+ if (id in users):
+ return users[id]
+ else:
+ return "UNKNOWN"
+
+def userNameToId(name):
+ if (users == {}):
+ _users = client.getUsers()
+ for user in _users:
+ users[user.id] = user.name
+ users[user.name] = user.id
+ if (name in users):
+ return users[name]
+ else:
+ return -1
+
+vars = {}
+
+def genRequestId():
+ return str(uuid.uuid1())
+
+authorizedUser = "UNKNOWN"
Added: incubator/tashi/trunk/src/tashi/aws/wsdl/__init__.py
URL: http://svn.apache.org/viewvc/incubator/tashi/trunk/src/tashi/aws/wsdl/__init__.py?rev=804314&view=auto
==============================================================================
--- incubator/tashi/trunk/src/tashi/aws/wsdl/__init__.py (added)
+++ incubator/tashi/trunk/src/tashi/aws/wsdl/__init__.py Fri Aug 14 18:14:29 2009
@@ -0,0 +1,16 @@
+# 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.