pax_global_header00006660000000000000000000000064126746156300014524gustar00rootroot0000000000000052 comment=2ab1bce7f1d297e349d053bebd866cd387e3d0ac euca2ools-3.3.1/000077500000000000000000000000001267461563000134245ustar00rootroot00000000000000euca2ools-3.3.1/.gitignore000066400000000000000000000002011267461563000154050ustar00rootroot00000000000000.project .nfs* *~ .sw* .*.sw* .DS_Store core core.* *.egg_info *.pyc *.pyo __pycache__ /.idea /build /dist /*.egg-info /MANIFEST euca2ools-3.3.1/COPYING000066400000000000000000000025121267461563000144570ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, with or # without modification, are permitted provided that the following conditions # are met: # # Redistributions of source code must retain the above # copyright notice, this list of conditions and the # following disclaimer. # # Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the # following disclaimer in the documentation and/or other # materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. euca2ools-3.3.1/INSTALL000066400000000000000000000070731267461563000144640ustar00rootroot00000000000000Euca2ools 3 Installation ======================== This file describes the steps needed to install euca2ools from source. Your operating system vendor may already offer euca2ools in packaged form that you can install using yum, apt-get, or a similar tool. Requirements ------------ Euca2ools currently work with python versions 2.6 and 2.7. Work is ongoing to port the suite to version 3. You must also have the following python libraries installed. All of them are available on PyPi: - lxml (http://lxml.de/) - requestbuilder (https://github.com/boto/requestbuilder) - requests (http://www.python-requests.org/) - setuptools (https://pypi.python.org/pypi/setuptools) - six (http://pythonhosted.org/six/) euca-get-password requires an openssl executable. All bundle commands require several executables as well: - gzip or pigz - openssl >= 1 The euca-bundle-vol command only works on Linux. It requires the utilities for creating and managing the filesystem to be bundled (e.g. mkfs and tune2fs) as well as these additional executables: - blkid - dd - gzip or pigz - kpartx - losetup - mkfs - mount - openssl >= 1 - parted - rsync - sgdisk - sync - umount For specific package names for these dependencies, check the distribution-specific sections below. Installation ------------ To install from a source tarball: $ tar xzf euca2ools-3.1.0.tar.gz $ cd euca2ools-3.1.0 $ python setup.py install To install directly from git: $ git clone git://github.com/eucalyptus/euca2ools $ cd euca2ools $ python setup.py install The euca2ools suite also ships with configuration files and certificates that you may find useful. To use them we recommend copying them onto your system like so: # mkdir -p /etc/euca2ools # cp -R conf/* /etc/euca2ools # mkdir -p /usr/share/euca2ools/certs # cp -R certs/* /usr/share/euca2ools/certs For distribution-specific instructions, check the distribution-specific sections below. Distribution-specific Instructions ================================== This section contains distribution-specific instructions and package lists to assist with installation of euca2ools and its dependencies. Ubuntu 12.04 ------------ Dependency packages: - openssl - python-dev - python-lxml - python-requests - python-setuptools - python-six - python-support python-requestbuilder is not available in Ubuntu 12.04, and must be built from source or backported from a later version. Notes for Distributors ====================== euca-bundle-vol --------------- By default, euca-bundle-vol excludes temporary system files (e.g. /dev and *.nfs*), files with potentially sensitive data (e.g. *.gpg), and files with persistent data that should not appear in bundles (e.g. udev's *-persistent-net.rules). Since these locations may vary by operating system, as a distributor you may wish to edit this list by patching conf/bundle-vol/excludes. Not including this file at all will result in no files being excluded by default. That may not be what your users expect. The --generate-fstab option generates a new fstab file based on a template, which may need to vary, depending on one's choice of cloud or operating system. This template appears in conf/bundle-vol/fstab. On non-Linux platforms we recommend removing euca-bundle-vol altogether. Paths ----- The paths euca2ools search by default are as follows: - systemwide configuration: /etc/euca2ools - user configuration: ~/.euca - other data: /usr/share/euca2ools To change these locations, patch euca2ools/commands/__init__.py and whatever stock configuration files you include. euca2ools-3.3.1/MANIFEST.in000066400000000000000000000001721267461563000151620ustar00rootroot00000000000000include COPYING include INSTALL include README recursive-include certs * recursive-include conf * recursive-include man * euca2ools-3.3.1/README000066400000000000000000000032231267461563000143040ustar00rootroot00000000000000Euca2ools are command line tools used to interact with Amazon Web Services (AWS) as well as other services that are compatible with AWS, such as Eucalyptus. They aim to use the same input as similar tools provided by AWS for each service individually along with several enhancements that make them easier to use with multiple clouds at once. Euca2ools provide the functionality of AWS's REST-based and Query-based APIs for the following services: - Auto Scaling (2011-01-01) (commands start with "euscale") - CloudFormation (2010-05-15) (commands start with "euform") - CloudWatch (2010-08-01) (commands start with "euwatch") - EC2 (2014-06-15) (commands start with "euca") - Elastic Load Balancing (2012-06-01) (commands start with "eulb") - IAM (2010-05-08) (commands start with "euare") The source code comes with man pages that provide basic documentation. Running a command with --help will also provide information on how to use that specific command. For more detailed documentation, see the online euca2ools documentation at http://www.eucalyptus.com/docs. For installation instructions, consult the INSTALL file that accompanies the source code. For a copy of the latest version of euca2ools, visit http://downloads.eucalyptus.com/software/euca2ools/. To obtain the latest development source code for euca2ools, visit https://github.com/eucalyptus/euca2ools. Pull requests are welcome and appreciated. By submitting code to this project you agree that code will be licensed under the 2-clause BSD license. A copy of this license is included in the COPYING file that accompanies the source code. euca2ools-3.3.1/bin/000077500000000000000000000000001267461563000141745ustar00rootroot00000000000000euca2ools-3.3.1/bin/euare-accountaliascreate000077500000000000000000000002531267461563000210530ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.createaccountalias if __name__ == '__main__': euca2ools.commands.iam.createaccountalias.CreateAccountAlias.run() euca2ools-3.3.1/bin/euare-accountaliasdelete000077500000000000000000000002531267461563000210520ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.deleteaccountalias if __name__ == '__main__': euca2ools.commands.iam.deleteaccountalias.DeleteAccountAlias.run() euca2ools-3.3.1/bin/euare-accountaliaslist000077500000000000000000000002531267461563000205630ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.listaccountaliases if __name__ == '__main__': euca2ools.commands.iam.listaccountaliases.ListAccountAliases.run() euca2ools-3.3.1/bin/euare-accountcreate000077500000000000000000000002341267461563000200400ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.createaccount if __name__ == '__main__': euca2ools.commands.iam.createaccount.CreateAccount.run() euca2ools-3.3.1/bin/euare-accountdel000077500000000000000000000002341267461563000173410ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.deleteaccount if __name__ == '__main__': euca2ools.commands.iam.deleteaccount.DeleteAccount.run() euca2ools-3.3.1/bin/euare-accountdelpolicy000077500000000000000000000002561267461563000205650ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.deleteaccountpolicy if __name__ == '__main__': euca2ools.commands.iam.deleteaccountpolicy.DeleteAccountPolicy.run() euca2ools-3.3.1/bin/euare-accountgetpolicy000077500000000000000000000002451267461563000205760ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.getaccountpolicy if __name__ == '__main__': euca2ools.commands.iam.getaccountpolicy.GetAccountPolicy.run() euca2ools-3.3.1/bin/euare-accountgetsummary000077500000000000000000000002501267461563000207700ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.getaccountsummary if __name__ == '__main__': euca2ools.commands.iam.getaccountsummary.GetAccountSummary.run() euca2ools-3.3.1/bin/euare-accountlist000077500000000000000000000002311267461563000175450ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.listaccounts if __name__ == '__main__': euca2ools.commands.iam.listaccounts.ListAccounts.run() euca2ools-3.3.1/bin/euare-accountlistpolicies000077500000000000000000000002561267461563000213040ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.listaccountpolicies if __name__ == '__main__': euca2ools.commands.iam.listaccountpolicies.ListAccountPolicies.run() euca2ools-3.3.1/bin/euare-accountuploadpolicy000077500000000000000000000002451267461563000213030ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.putaccountpolicy if __name__ == '__main__': euca2ools.commands.iam.putaccountpolicy.PutAccountPolicy.run() euca2ools-3.3.1/bin/euare-assumerole000077500000000000000000000002231267461563000173750ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.sts.assumerole if __name__ == '__main__': euca2ools.commands.sts.assumerole.AssumeRole.run() euca2ools-3.3.1/bin/euare-getldapsyncstatus000077500000000000000000000002501267461563000207770ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.getldapsyncstatus if __name__ == '__main__': euca2ools.commands.iam.getldapsyncstatus.GetLdapSyncStatus.run() euca2ools-3.3.1/bin/euare-groupaddpolicy000077500000000000000000000002371267461563000202500ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.addgrouppolicy if __name__ == '__main__': euca2ools.commands.iam.addgrouppolicy.AddGroupPolicy.run() euca2ools-3.3.1/bin/euare-groupadduser000077500000000000000000000002371267461563000177270ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.addusertogroup if __name__ == '__main__': euca2ools.commands.iam.addusertogroup.AddUserToGroup.run() euca2ools-3.3.1/bin/euare-groupcreate000077500000000000000000000002261267461563000175410ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.creategroup if __name__ == '__main__': euca2ools.commands.iam.creategroup.CreateGroup.run() euca2ools-3.3.1/bin/euare-groupdel000077500000000000000000000002261267461563000170420ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.deletegroup if __name__ == '__main__': euca2ools.commands.iam.deletegroup.DeleteGroup.run() euca2ools-3.3.1/bin/euare-groupdelpolicy000077500000000000000000000002501267461563000202570ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.deletegrouppolicy if __name__ == '__main__': euca2ools.commands.iam.deletegrouppolicy.DeleteGroupPolicy.run() euca2ools-3.3.1/bin/euare-groupgetpolicy000077500000000000000000000002371267461563000202770ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.getgrouppolicy if __name__ == '__main__': euca2ools.commands.iam.getgrouppolicy.GetGroupPolicy.run() euca2ools-3.3.1/bin/euare-grouplistbypath000077500000000000000000000002231267461563000204560ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.listgroups if __name__ == '__main__': euca2ools.commands.iam.listgroups.ListGroups.run() euca2ools-3.3.1/bin/euare-grouplistpolicies000077500000000000000000000002501267461563000207760ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.listgrouppolicies if __name__ == '__main__': euca2ools.commands.iam.listgrouppolicies.ListGroupPolicies.run() euca2ools-3.3.1/bin/euare-grouplistusers000077500000000000000000000002151267461563000203310ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.getgroup if __name__ == '__main__': euca2ools.commands.iam.getgroup.GetGroup.run() euca2ools-3.3.1/bin/euare-groupmod000077500000000000000000000002261267461563000170550ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.updategroup if __name__ == '__main__': euca2ools.commands.iam.updategroup.UpdateGroup.run() euca2ools-3.3.1/bin/euare-groupremoveuser000077500000000000000000000002561267461563000204750ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.removeuserfromgroup if __name__ == '__main__': euca2ools.commands.iam.removeuserfromgroup.RemoveUserFromGroup.run() euca2ools-3.3.1/bin/euare-groupuploadpolicy000077500000000000000000000002371267461563000210040ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.putgrouppolicy if __name__ == '__main__': euca2ools.commands.iam.putgrouppolicy.PutGroupPolicy.run() euca2ools-3.3.1/bin/euare-instanceprofileaddrole000077500000000000000000000002751267461563000217450ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.addroletoinstanceprofile if __name__ == '__main__': euca2ools.commands.iam.addroletoinstanceprofile.AddRoleToInstanceProfile.run() euca2ools-3.3.1/bin/euare-instanceprofilecreate000077500000000000000000000002641267461563000215740ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.createinstanceprofile if __name__ == '__main__': euca2ools.commands.iam.createinstanceprofile.CreateInstanceProfile.run() euca2ools-3.3.1/bin/euare-instanceprofiledel000077500000000000000000000002641267461563000210750ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.deleteinstanceprofile if __name__ == '__main__': euca2ools.commands.iam.deleteinstanceprofile.DeleteInstanceProfile.run() euca2ools-3.3.1/bin/euare-instanceprofilegetattributes000077500000000000000000000002531267461563000232150ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.getinstanceprofile if __name__ == '__main__': euca2ools.commands.iam.getinstanceprofile.GetInstanceProfile.run() euca2ools-3.3.1/bin/euare-instanceprofilelistbypath000077500000000000000000000002611267461563000225110ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.listinstanceprofiles if __name__ == '__main__': euca2ools.commands.iam.listinstanceprofiles.ListInstanceProfiles.run() euca2ools-3.3.1/bin/euare-instanceprofilelistforrole000077500000000000000000000003061267461563000226720ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.listinstanceprofilesforrole if __name__ == '__main__': euca2ools.commands.iam.listinstanceprofilesforrole.ListInstanceProfilesForRole.run() euca2ools-3.3.1/bin/euare-instanceprofileremoverole000077500000000000000000000003141267461563000225040ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.removerolefrominstanceprofile if __name__ == '__main__': euca2ools.commands.iam.removerolefrominstanceprofile.RemoveRoleFromInstanceProfile.run() euca2ools-3.3.1/bin/euare-releaserole000077500000000000000000000002301267461563000175160ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.misc.releaserole if __name__ == '__main__': euca2ools.commands.misc.releaserole.ReleaseRole.run() euca2ools-3.3.1/bin/euare-roleaddpolicy000077500000000000000000000002341267461563000200520ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.addrolepolicy if __name__ == '__main__': euca2ools.commands.iam.addrolepolicy.AddRolePolicy.run() euca2ools-3.3.1/bin/euare-rolecreate000077500000000000000000000002231267461563000173430ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.createrole if __name__ == '__main__': euca2ools.commands.iam.createrole.CreateRole.run() euca2ools-3.3.1/bin/euare-roledel000077500000000000000000000002231267461563000166440ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.deleterole if __name__ == '__main__': euca2ools.commands.iam.deleterole.DeleteRole.run() euca2ools-3.3.1/bin/euare-roledelpolicy000077500000000000000000000002451267461563000200700ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.deleterolepolicy if __name__ == '__main__': euca2ools.commands.iam.deleterolepolicy.DeleteRolePolicy.run() euca2ools-3.3.1/bin/euare-rolegetattributes000077500000000000000000000002121267461563000207640ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.getrole if __name__ == '__main__': euca2ools.commands.iam.getrole.GetRole.run() euca2ools-3.3.1/bin/euare-rolegetpolicy000077500000000000000000000002341267461563000201010ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.getrolepolicy if __name__ == '__main__': euca2ools.commands.iam.getrolepolicy.GetRolePolicy.run() euca2ools-3.3.1/bin/euare-rolelistbypath000077500000000000000000000002201267461563000202600ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.listroles if __name__ == '__main__': euca2ools.commands.iam.listroles.ListRoles.run() euca2ools-3.3.1/bin/euare-rolelistpolicies000077500000000000000000000002451267461563000206070ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.listrolepolicies if __name__ == '__main__': euca2ools.commands.iam.listrolepolicies.ListRolePolicies.run() euca2ools-3.3.1/bin/euare-roleupdateassumepolicy000077500000000000000000000002671267461563000220300ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.updateassumerolepolicy if __name__ == '__main__': euca2ools.commands.iam.updateassumerolepolicy.UpdateAssumeRolePolicy.run() euca2ools-3.3.1/bin/euare-roleuploadpolicy000077500000000000000000000002341267461563000206060ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.putrolepolicy if __name__ == '__main__': euca2ools.commands.iam.putrolepolicy.PutRolePolicy.run() euca2ools-3.3.1/bin/euare-servercertdel000077500000000000000000000002721267461563000200730ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.deleteservercertificate if __name__ == '__main__': euca2ools.commands.iam.deleteservercertificate.DeleteServerCertificate.run() euca2ools-3.3.1/bin/euare-servercertgetattributes000077500000000000000000000002611267461563000222130ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.getservercertificate if __name__ == '__main__': euca2ools.commands.iam.getservercertificate.GetServerCertificate.run() euca2ools-3.3.1/bin/euare-servercertlistbypath000077500000000000000000000002671267461563000215160ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.listservercertificates if __name__ == '__main__': euca2ools.commands.iam.listservercertificates.ListServerCertificates.run() euca2ools-3.3.1/bin/euare-servercertmod000077500000000000000000000002721267461563000201060ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.updateservercertificate if __name__ == '__main__': euca2ools.commands.iam.updateservercertificate.UpdateServerCertificate.run() euca2ools-3.3.1/bin/euare-servercertupload000077500000000000000000000002721267461563000206130ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.uploadservercertificate if __name__ == '__main__': euca2ools.commands.iam.uploadservercertificate.UploadServerCertificate.run() euca2ools-3.3.1/bin/euare-useraddcert000077500000000000000000000002751267461563000175320ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.uploadsigningcertificate if __name__ == '__main__': euca2ools.commands.iam.uploadsigningcertificate.UploadSigningCertificate.run() euca2ools-3.3.1/bin/euare-useraddkey000077500000000000000000000002421267461563000173570ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.createaccesskey if __name__ == '__main__': euca2ools.commands.iam.createaccesskey.CreateAccessKey.run() euca2ools-3.3.1/bin/euare-useraddloginprofile000077500000000000000000000002531267461563000212620ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.createloginprofile if __name__ == '__main__': euca2ools.commands.iam.createloginprofile.CreateLoginProfile.run() euca2ools-3.3.1/bin/euare-useraddpolicy000077500000000000000000000002341267461563000200670ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.adduserpolicy if __name__ == '__main__': euca2ools.commands.iam.adduserpolicy.AddUserPolicy.run() euca2ools-3.3.1/bin/euare-usercreate000077500000000000000000000002231267461563000173600ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.createuser if __name__ == '__main__': euca2ools.commands.iam.createuser.CreateUser.run() euca2ools-3.3.1/bin/euare-usercreatecert000077500000000000000000000002751267461563000202450ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.createsigningcertificate if __name__ == '__main__': euca2ools.commands.iam.createsigningcertificate.CreateSigningCertificate.run() euca2ools-3.3.1/bin/euare-userdeactivatemfadevice000077500000000000000000000002561267461563000221000ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.deactivatemfadevice if __name__ == '__main__': euca2ools.commands.iam.deactivatemfadevice.DeactivateMFADevice.run() euca2ools-3.3.1/bin/euare-userdel000077500000000000000000000002231267461563000166610ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.deleteuser if __name__ == '__main__': euca2ools.commands.iam.deleteuser.DeleteUser.run() euca2ools-3.3.1/bin/euare-userdelcert000077500000000000000000000002751267461563000175460ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.deletesigningcertificate if __name__ == '__main__': euca2ools.commands.iam.deletesigningcertificate.DeleteSigningCertificate.run() euca2ools-3.3.1/bin/euare-userdelkey000077500000000000000000000002421267461563000173730ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.deleteaccesskey if __name__ == '__main__': euca2ools.commands.iam.deleteaccesskey.DeleteAccessKey.run() euca2ools-3.3.1/bin/euare-userdelloginprofile000077500000000000000000000002531267461563000212760ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.deleteloginprofile if __name__ == '__main__': euca2ools.commands.iam.deleteloginprofile.DeleteLoginProfile.run() euca2ools-3.3.1/bin/euare-userdelpolicy000077500000000000000000000002451267461563000201050ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.deleteuserpolicy if __name__ == '__main__': euca2ools.commands.iam.deleteuserpolicy.DeleteUserPolicy.run() euca2ools-3.3.1/bin/euare-userenablemfadevice000077500000000000000000000002421267461563000212100ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.enablemfadevice if __name__ == '__main__': euca2ools.commands.iam.enablemfadevice.EnableMFADevice.run() euca2ools-3.3.1/bin/euare-usergetattributes000077500000000000000000000002121267461563000210010ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.getuser if __name__ == '__main__': euca2ools.commands.iam.getuser.GetUser.run() euca2ools-3.3.1/bin/euare-usergetinfo000077500000000000000000000002261267461563000175530ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.getuserinfo if __name__ == '__main__': euca2ools.commands.iam.getuserinfo.GetUserInfo.run() euca2ools-3.3.1/bin/euare-usergetloginprofile000077500000000000000000000002421267461563000213070ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.getloginprofile if __name__ == '__main__': euca2ools.commands.iam.getloginprofile.GetLoginProfile.run() euca2ools-3.3.1/bin/euare-usergetpolicy000077500000000000000000000002341267461563000201160ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.getuserpolicy if __name__ == '__main__': euca2ools.commands.iam.getuserpolicy.GetUserPolicy.run() euca2ools-3.3.1/bin/euare-userlistbypath000077500000000000000000000002201267461563000202750ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.listusers if __name__ == '__main__': euca2ools.commands.iam.listusers.ListUsers.run() euca2ools-3.3.1/bin/euare-userlistcerts000077500000000000000000000002721267461563000201350ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.listsigningcertificates if __name__ == '__main__': euca2ools.commands.iam.listsigningcertificates.ListSigningCertificates.run() euca2ools-3.3.1/bin/euare-userlistgroups000077500000000000000000000002501267461563000203300ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.listgroupsforuser if __name__ == '__main__': euca2ools.commands.iam.listgroupsforuser.ListGroupsForUser.run() euca2ools-3.3.1/bin/euare-userlistkeys000077500000000000000000000002371267461563000177710ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.listaccesskeys if __name__ == '__main__': euca2ools.commands.iam.listaccesskeys.ListAccessKeys.run() euca2ools-3.3.1/bin/euare-userlistmfadevices000077500000000000000000000002371267461563000211240ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.listmfadevices if __name__ == '__main__': euca2ools.commands.iam.listmfadevices.ListMFADevices.run() euca2ools-3.3.1/bin/euare-userlistpolicies000077500000000000000000000002451267461563000206240ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.listuserpolicies if __name__ == '__main__': euca2ools.commands.iam.listuserpolicies.ListUserPolicies.run() euca2ools-3.3.1/bin/euare-usermod000077500000000000000000000002231267461563000166740ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.updateuser if __name__ == '__main__': euca2ools.commands.iam.updateuser.UpdateUser.run() euca2ools-3.3.1/bin/euare-usermodcert000077500000000000000000000002751267461563000175610ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.updatesigningcertificate if __name__ == '__main__': euca2ools.commands.iam.updatesigningcertificate.UpdateSigningCertificate.run() euca2ools-3.3.1/bin/euare-usermodkey000077500000000000000000000002421267461563000174060ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.updateaccesskey if __name__ == '__main__': euca2ools.commands.iam.updateaccesskey.UpdateAccessKey.run() euca2ools-3.3.1/bin/euare-usermodloginprofile000077500000000000000000000002531267461563000213110ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.updateloginprofile if __name__ == '__main__': euca2ools.commands.iam.updateloginprofile.UpdateLoginProfile.run() euca2ools-3.3.1/bin/euare-userresyncmfadevice000077500000000000000000000002421267461563000212650ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.resyncmfadevice if __name__ == '__main__': euca2ools.commands.iam.resyncmfadevice.ResyncMFADevice.run() euca2ools-3.3.1/bin/euare-userupdateinfo000077500000000000000000000002371267461563000202600ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.updateuserinfo if __name__ == '__main__': euca2ools.commands.iam.updateuserinfo.UpdateUserInfo.run() euca2ools-3.3.1/bin/euare-useruploadpolicy000077500000000000000000000002341267461563000206230ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.iam.putuserpolicy if __name__ == '__main__': euca2ools.commands.iam.putuserpolicy.PutUserPolicy.run() euca2ools-3.3.1/bin/euca-accept-vpc-peering-connection000077500000000000000000000003031267461563000226420ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.acceptvpcpeeringconnection if __name__ == '__main__': euca2ools.commands.ec2.acceptvpcpeeringconnection.AcceptVpcPeeringConnection.run() euca2ools-3.3.1/bin/euca-allocate-address000077500000000000000000000002421267461563000202420ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.allocateaddress if __name__ == '__main__': euca2ools.commands.ec2.allocateaddress.AllocateAddress.run() euca2ools-3.3.1/bin/euca-assign-private-ip-addresses000077500000000000000000000002751267461563000223560ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.assignprivateipaddresses if __name__ == '__main__': euca2ools.commands.ec2.assignprivateipaddresses.AssignPrivateIpAddresses.run() euca2ools-3.3.1/bin/euca-associate-address000077500000000000000000000002451267461563000204340ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.associateaddress if __name__ == '__main__': euca2ools.commands.ec2.associateaddress.AssociateAddress.run() euca2ools-3.3.1/bin/euca-associate-dhcp-options000077500000000000000000000002611267461563000214140ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.associatedhcpoptions if __name__ == '__main__': euca2ools.commands.ec2.associatedhcpoptions.AssociateDhcpOptions.run() euca2ools-3.3.1/bin/euca-associate-route-table000077500000000000000000000002561267461563000212340ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.associateroutetable if __name__ == '__main__': euca2ools.commands.ec2.associateroutetable.AssociateRouteTable.run() euca2ools-3.3.1/bin/euca-attach-internet-gateway000077500000000000000000000002641267461563000215700ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.attachinternetgateway if __name__ == '__main__': euca2ools.commands.ec2.attachinternetgateway.AttachInternetGateway.run() euca2ools-3.3.1/bin/euca-attach-network-interface000077500000000000000000000002671267461563000217330ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.attachnetworkinterface if __name__ == '__main__': euca2ools.commands.ec2.attachnetworkinterface.AttachNetworkInterface.run() euca2ools-3.3.1/bin/euca-attach-volume000077500000000000000000000002311267461563000176020ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.attachvolume if __name__ == '__main__': euca2ools.commands.ec2.attachvolume.AttachVolume.run() euca2ools-3.3.1/bin/euca-attach-vpn-gateway000077500000000000000000000002451267461563000205420ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.attachvpngateway if __name__ == '__main__': euca2ools.commands.ec2.attachvpngateway.AttachVpnGateway.run() euca2ools-3.3.1/bin/euca-authorize000077500000000000000000000002751267461563000170530ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.modifysecuritygrouprule if __name__ == '__main__': euca2ools.commands.ec2.modifysecuritygrouprule.AuthorizeSecurityGroupRule.run() euca2ools-3.3.1/bin/euca-bundle-and-upload-image000077500000000000000000000002671267461563000214150ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.bundle.bundleanduploadimage if __name__ == '__main__': euca2ools.commands.bundle.bundleanduploadimage.BundleAndUploadImage.run() euca2ools-3.3.1/bin/euca-bundle-image000077500000000000000000000002341267461563000173650ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.bundle.bundleimage if __name__ == '__main__': euca2ools.commands.bundle.bundleimage.BundleImage.run() euca2ools-3.3.1/bin/euca-bundle-instance000077500000000000000000000002371267461563000201120ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.bundleinstance if __name__ == '__main__': euca2ools.commands.ec2.bundleinstance.BundleInstance.run() euca2ools-3.3.1/bin/euca-bundle-vol000077500000000000000000000002371267461563000171060ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.bundle.bundlevolume if __name__ == '__main__': euca2ools.commands.bundle.bundlevolume.BundleVolume.run() euca2ools-3.3.1/bin/euca-cancel-bundle-task000077500000000000000000000002451267461563000204720ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.cancelbundletask if __name__ == '__main__': euca2ools.commands.ec2.cancelbundletask.CancelBundleTask.run() euca2ools-3.3.1/bin/euca-cancel-conversion-task000077500000000000000000000002611267461563000214040ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.cancelconversiontask if __name__ == '__main__': euca2ools.commands.ec2.cancelconversiontask.CancelConversionTask.run() euca2ools-3.3.1/bin/euca-confirm-product-instance000077500000000000000000000002671267461563000217570ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.confirmproductinstance if __name__ == '__main__': euca2ools.commands.ec2.confirmproductinstance.ConfirmProductInstance.run() euca2ools-3.3.1/bin/euca-copy-image000077500000000000000000000002201267461563000170610ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.copyimage if __name__ == '__main__': euca2ools.commands.ec2.copyimage.CopyImage.run() euca2ools-3.3.1/bin/euca-create-customer-gateway000077500000000000000000000002641267461563000216000ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.createcustomergateway if __name__ == '__main__': euca2ools.commands.ec2.createcustomergateway.CreateCustomerGateway.run() euca2ools-3.3.1/bin/euca-create-dhcp-options000077500000000000000000000002501267461563000207020ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.createdhcpoptions if __name__ == '__main__': euca2ools.commands.ec2.createdhcpoptions.CreateDhcpOptions.run() euca2ools-3.3.1/bin/euca-create-group000077500000000000000000000002561267461563000174350ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.createsecuritygroup if __name__ == '__main__': euca2ools.commands.ec2.createsecuritygroup.CreateSecurityGroup.run() euca2ools-3.3.1/bin/euca-create-image000077500000000000000000000002261267461563000173600ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.createimage if __name__ == '__main__': euca2ools.commands.ec2.createimage.CreateImage.run() euca2ools-3.3.1/bin/euca-create-internet-gateway000077500000000000000000000002641267461563000215670ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.createinternetgateway if __name__ == '__main__': euca2ools.commands.ec2.createinternetgateway.CreateInternetGateway.run() euca2ools-3.3.1/bin/euca-create-keypair000077500000000000000000000002341267461563000177410ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.createkeypair if __name__ == '__main__': euca2ools.commands.ec2.createkeypair.CreateKeyPair.run() euca2ools-3.3.1/bin/euca-create-network-acl000077500000000000000000000002451267461563000205250ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.createnetworkacl if __name__ == '__main__': euca2ools.commands.ec2.createnetworkacl.CreateNetworkAcl.run() euca2ools-3.3.1/bin/euca-create-network-acl-entry000077500000000000000000000002641267461563000216650ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.modifynetworkaclentry if __name__ == '__main__': euca2ools.commands.ec2.modifynetworkaclentry.CreateNetworkAclEntry.run() euca2ools-3.3.1/bin/euca-create-network-interface000077500000000000000000000002671267461563000217320ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.createnetworkinterface if __name__ == '__main__': euca2ools.commands.ec2.createnetworkinterface.CreateNetworkInterface.run() euca2ools-3.3.1/bin/euca-create-route000077500000000000000000000002261267461563000174340ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.createroute if __name__ == '__main__': euca2ools.commands.ec2.createroute.CreateRoute.run() euca2ools-3.3.1/bin/euca-create-route-table000077500000000000000000000002451267461563000205220ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.createroutetable if __name__ == '__main__': euca2ools.commands.ec2.createroutetable.CreateRouteTable.run() euca2ools-3.3.1/bin/euca-create-snapshot000077500000000000000000000002371267461563000201370ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.createsnapshot if __name__ == '__main__': euca2ools.commands.ec2.createsnapshot.CreateSnapshot.run() euca2ools-3.3.1/bin/euca-create-subnet000077500000000000000000000002311267461563000175720ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.createsubnet if __name__ == '__main__': euca2ools.commands.ec2.createsubnet.CreateSubnet.run() euca2ools-3.3.1/bin/euca-create-tags000077500000000000000000000002311267461563000172300ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.createtags if __name__ == '__main__': cmd = euca2ools.commands.ec2.createtags.CreateTags.run() euca2ools-3.3.1/bin/euca-create-volume000077500000000000000000000002311267461563000176010ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.createvolume if __name__ == '__main__': euca2ools.commands.ec2.createvolume.CreateVolume.run() euca2ools-3.3.1/bin/euca-create-vpc000077500000000000000000000002201267461563000170600ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.createvpc if __name__ == '__main__': euca2ools.commands.ec2.createvpc.CreateVpc.run() euca2ools-3.3.1/bin/euca-create-vpc-peering-connection000077500000000000000000000003031267461563000226460ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.createvpcpeeringconnection if __name__ == '__main__': euca2ools.commands.ec2.createvpcpeeringconnection.CreateVpcPeeringConnection.run() euca2ools-3.3.1/bin/euca-create-vpn-connection000077500000000000000000000002561267461563000212410ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.createvpnconnection if __name__ == '__main__': euca2ools.commands.ec2.createvpnconnection.CreateVpnConnection.run() euca2ools-3.3.1/bin/euca-create-vpn-connection-route000077500000000000000000000002751267461563000223760ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.createvpnconnectionroute if __name__ == '__main__': euca2ools.commands.ec2.createvpnconnectionroute.CreateVpnConnectionRoute.run() euca2ools-3.3.1/bin/euca-create-vpn-gateway000077500000000000000000000002451267461563000205410ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.createvpngateway if __name__ == '__main__': euca2ools.commands.ec2.createvpngateway.CreateVpnGateway.run() euca2ools-3.3.1/bin/euca-delete-bundle000077500000000000000000000002371267461563000175500ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.bundle.deletebundle if __name__ == '__main__': euca2ools.commands.bundle.deletebundle.DeleteBundle.run() euca2ools-3.3.1/bin/euca-delete-customer-gateway000077500000000000000000000002641267461563000215770ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.deletecustomergateway if __name__ == '__main__': euca2ools.commands.ec2.deletecustomergateway.DeleteCustomerGateway.run() euca2ools-3.3.1/bin/euca-delete-dhcp-options000077500000000000000000000002501267461563000207010ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.deletedhcpoptions if __name__ == '__main__': euca2ools.commands.ec2.deletedhcpoptions.DeleteDhcpOptions.run() euca2ools-3.3.1/bin/euca-delete-disk-image000077500000000000000000000002421267461563000203050ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.deletediskimage if __name__ == '__main__': euca2ools.commands.ec2.deletediskimage.DeleteDiskImage.run() euca2ools-3.3.1/bin/euca-delete-group000077500000000000000000000002561267461563000174340ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.deletesecuritygroup if __name__ == '__main__': euca2ools.commands.ec2.deletesecuritygroup.DeleteSecurityGroup.run() euca2ools-3.3.1/bin/euca-delete-internet-gateway000077500000000000000000000002641267461563000215660ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.deleteinternetgateway if __name__ == '__main__': euca2ools.commands.ec2.deleteinternetgateway.DeleteInternetGateway.run() euca2ools-3.3.1/bin/euca-delete-keypair000077500000000000000000000002341267461563000177400ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.deletekeypair if __name__ == '__main__': euca2ools.commands.ec2.deletekeypair.DeleteKeyPair.run() euca2ools-3.3.1/bin/euca-delete-network-acl000077500000000000000000000002451267461563000205240ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.deletenetworkacl if __name__ == '__main__': euca2ools.commands.ec2.deletenetworkacl.DeleteNetworkAcl.run() euca2ools-3.3.1/bin/euca-delete-network-acl-entry000077500000000000000000000002641267461563000216640ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.deletenetworkaclentry if __name__ == '__main__': euca2ools.commands.ec2.deletenetworkaclentry.DeleteNetworkAclEntry.run() euca2ools-3.3.1/bin/euca-delete-network-interface000077500000000000000000000002671267461563000217310ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.deletenetworkinterface if __name__ == '__main__': euca2ools.commands.ec2.deletenetworkinterface.DeleteNetworkInterface.run() euca2ools-3.3.1/bin/euca-delete-route000077500000000000000000000002261267461563000174330ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.deleteroute if __name__ == '__main__': euca2ools.commands.ec2.deleteroute.DeleteRoute.run() euca2ools-3.3.1/bin/euca-delete-route-table000077500000000000000000000002451267461563000205210ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.deleteroutetable if __name__ == '__main__': euca2ools.commands.ec2.deleteroutetable.DeleteRouteTable.run() euca2ools-3.3.1/bin/euca-delete-snapshot000077500000000000000000000002371267461563000201360ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.deletesnapshot if __name__ == '__main__': euca2ools.commands.ec2.deletesnapshot.DeleteSnapshot.run() euca2ools-3.3.1/bin/euca-delete-subnet000077500000000000000000000002311267461563000175710ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.deletesubnet if __name__ == '__main__': euca2ools.commands.ec2.deletesubnet.DeleteSubnet.run() euca2ools-3.3.1/bin/euca-delete-tags000077500000000000000000000002231267461563000172300ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.deletetags if __name__ == '__main__': euca2ools.commands.ec2.deletetags.DeleteTags.run() euca2ools-3.3.1/bin/euca-delete-volume000077500000000000000000000002311267461563000176000ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.deletevolume if __name__ == '__main__': euca2ools.commands.ec2.deletevolume.DeleteVolume.run() euca2ools-3.3.1/bin/euca-delete-vpc000077500000000000000000000002201267461563000170570ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.deletevpc if __name__ == '__main__': euca2ools.commands.ec2.deletevpc.DeleteVpc.run() euca2ools-3.3.1/bin/euca-delete-vpc-peering-connection000077500000000000000000000003031267461563000226450ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.deletevpcpeeringconnection if __name__ == '__main__': euca2ools.commands.ec2.deletevpcpeeringconnection.DeleteVpcPeeringConnection.run() euca2ools-3.3.1/bin/euca-delete-vpn-connection000077500000000000000000000002561267461563000212400ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.deletevpnconnection if __name__ == '__main__': euca2ools.commands.ec2.deletevpnconnection.DeleteVpnConnection.run() euca2ools-3.3.1/bin/euca-delete-vpn-connection-route000077500000000000000000000002751267461563000223750ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.deletevpnconnectionroute if __name__ == '__main__': euca2ools.commands.ec2.deletevpnconnectionroute.DeleteVpnConnectionRoute.run() euca2ools-3.3.1/bin/euca-delete-vpn-gateway000077500000000000000000000002451267461563000205400ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.deletevpngateway if __name__ == '__main__': euca2ools.commands.ec2.deletevpngateway.DeleteVpnGateway.run() euca2ools-3.3.1/bin/euca-deregister000077500000000000000000000002421267461563000171700ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.deregisterimage if __name__ == '__main__': euca2ools.commands.ec2.deregisterimage.DeregisterImage.run() euca2ools-3.3.1/bin/euca-describe-account-attributes000077500000000000000000000003001267461563000224240ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describeaccountattributes if __name__ == '__main__': euca2ools.commands.ec2.describeaccountattributes.DescribeAccountAttributes.run() euca2ools-3.3.1/bin/euca-describe-addresses000077500000000000000000000002501267461563000205650ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describeaddresses if __name__ == '__main__': euca2ools.commands.ec2.describeaddresses.DescribeAddresses.run() euca2ools-3.3.1/bin/euca-describe-availability-zones000077500000000000000000000003001267461563000224120ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describeavailabilityzones if __name__ == '__main__': euca2ools.commands.ec2.describeavailabilityzones.DescribeAvailabilityZones.run() euca2ools-3.3.1/bin/euca-describe-bundle-tasks000077500000000000000000000002561267461563000212120ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describebundletasks if __name__ == '__main__': euca2ools.commands.ec2.describebundletasks.DescribeBundleTasks.run() euca2ools-3.3.1/bin/euca-describe-conversion-tasks000077500000000000000000000002721267461563000221240ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describeconversiontasks if __name__ == '__main__': euca2ools.commands.ec2.describeconversiontasks.DescribeConversionTasks.run() euca2ools-3.3.1/bin/euca-describe-customer-gateways000077500000000000000000000002751267461563000223020ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describecustomergateways if __name__ == '__main__': euca2ools.commands.ec2.describecustomergateways.DescribeCustomerGateways.run() euca2ools-3.3.1/bin/euca-describe-dhcp-options000077500000000000000000000002561267461563000212250ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describedhcpoptions if __name__ == '__main__': euca2ools.commands.ec2.describedhcpoptions.DescribeDhcpOptions.run() euca2ools-3.3.1/bin/euca-describe-group000077500000000000000000000002671267461563000177540ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describesecuritygroups if __name__ == '__main__': euca2ools.commands.ec2.describesecuritygroups.DescribeSecurityGroups.run() euca2ools-3.3.1/bin/euca-describe-groups000077500000000000000000000002671267461563000201370ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describesecuritygroups if __name__ == '__main__': euca2ools.commands.ec2.describesecuritygroups.DescribeSecurityGroups.run() euca2ools-3.3.1/bin/euca-describe-image-attribute000077500000000000000000000002671267461563000217030ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describeimageattribute if __name__ == '__main__': euca2ools.commands.ec2.describeimageattribute.DescribeImageAttribute.run() euca2ools-3.3.1/bin/euca-describe-images000077500000000000000000000002371267461563000200620ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describeimages if __name__ == '__main__': euca2ools.commands.ec2.describeimages.DescribeImages.run() euca2ools-3.3.1/bin/euca-describe-instance-attribute000077500000000000000000000003001267461563000224110ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describeinstanceattribute if __name__ == '__main__': euca2ools.commands.ec2.describeinstanceattribute.DescribeInstanceAttribute.run() euca2ools-3.3.1/bin/euca-describe-instance-status000077500000000000000000000002671267461563000217450ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describeinstancestatus if __name__ == '__main__': euca2ools.commands.ec2.describeinstancestatus.DescribeInstanceStatus.run() euca2ools-3.3.1/bin/euca-describe-instance-types000077500000000000000000000002641267461563000215630ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describeinstancetypes if __name__ == '__main__': euca2ools.commands.ec2.describeinstancetypes.DescribeInstanceTypes.run() euca2ools-3.3.1/bin/euca-describe-instances000077500000000000000000000002501267461563000205770ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describeinstances if __name__ == '__main__': euca2ools.commands.ec2.describeinstances.DescribeInstances.run() euca2ools-3.3.1/bin/euca-describe-internet-gateways000077500000000000000000000002751267461563000222710ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describeinternetgateways if __name__ == '__main__': euca2ools.commands.ec2.describeinternetgateways.DescribeInternetGateways.run() euca2ools-3.3.1/bin/euca-describe-keypairs000077500000000000000000000002451267461563000204430ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describekeypairs if __name__ == '__main__': euca2ools.commands.ec2.describekeypairs.DescribeKeyPairs.run() euca2ools-3.3.1/bin/euca-describe-network-acls000077500000000000000000000002561267461563000212270ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describenetworkacls if __name__ == '__main__': euca2ools.commands.ec2.describenetworkacls.DescribeNetworkAcls.run() euca2ools-3.3.1/bin/euca-describe-network-interface-attribute000077500000000000000000000003301267461563000242370ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describenetworkinterfaceattribute if __name__ == '__main__': euca2ools.commands.ec2.describenetworkinterfaceattribute.DescribeNetworkInterfaceAttribute.run() euca2ools-3.3.1/bin/euca-describe-network-interfaces000077500000000000000000000003001267461563000224160ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describenetworkinterfaces if __name__ == '__main__': euca2ools.commands.ec2.describenetworkinterfaces.DescribeNetworkInterfaces.run() euca2ools-3.3.1/bin/euca-describe-regions000077500000000000000000000002421267461563000202570ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describeregions if __name__ == '__main__': euca2ools.commands.ec2.describeregions.DescribeRegions.run() euca2ools-3.3.1/bin/euca-describe-route-tables000077500000000000000000000002561267461563000212240ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describeroutetables if __name__ == '__main__': euca2ools.commands.ec2.describeroutetables.DescribeRouteTables.run() euca2ools-3.3.1/bin/euca-describe-snapshot-attribute000077500000000000000000000003001267461563000224440ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describesnapshotattribute if __name__ == '__main__': euca2ools.commands.ec2.describesnapshotattribute.DescribeSnapshotAttribute.run() euca2ools-3.3.1/bin/euca-describe-snapshots000077500000000000000000000002501267461563000206320ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describesnapshots if __name__ == '__main__': euca2ools.commands.ec2.describesnapshots.DescribeSnapshots.run() euca2ools-3.3.1/bin/euca-describe-subnets000077500000000000000000000002421267461563000202740ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describesubnets if __name__ == '__main__': euca2ools.commands.ec2.describesubnets.DescribeSubnets.run() euca2ools-3.3.1/bin/euca-describe-tags000077500000000000000000000002311267461563000175450ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describetags if __name__ == '__main__': euca2ools.commands.ec2.describetags.DescribeTags.run() euca2ools-3.3.1/bin/euca-describe-volumes000077500000000000000000000002431267461563000203040ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describevolumes if __name__ == '__main__': euca2ools.commands.ec2.describevolumes.DescribeVolumes.run() euca2ools-3.3.1/bin/euca-describe-vpc-attribute000077500000000000000000000002611267461563000214030ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describevpcattribute if __name__ == '__main__': euca2ools.commands.ec2.describevpcattribute.DescribeVpcAttribute.run() euca2ools-3.3.1/bin/euca-describe-vpc-peering-connections000077500000000000000000000003141267461563000233500ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describevpcpeeringconnections if __name__ == '__main__': euca2ools.commands.ec2.describevpcpeeringconnections.DescribeVpcPeeringConnections.run() euca2ools-3.3.1/bin/euca-describe-vpcs000077500000000000000000000002311267461563000175620ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describevpcs if __name__ == '__main__': euca2ools.commands.ec2.describevpcs.DescribeVpcs.run() euca2ools-3.3.1/bin/euca-describe-vpn-connections000077500000000000000000000002671267461563000217430ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describevpnconnections if __name__ == '__main__': euca2ools.commands.ec2.describevpnconnections.DescribeVpnConnections.run() euca2ools-3.3.1/bin/euca-describe-vpn-gateways000077500000000000000000000002561267461563000212430ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.describevpngateways if __name__ == '__main__': euca2ools.commands.ec2.describevpngateways.DescribeVpnGateways.run() euca2ools-3.3.1/bin/euca-detach-internet-gateway000077500000000000000000000002641267461563000215540ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.detachinternetgateway if __name__ == '__main__': euca2ools.commands.ec2.detachinternetgateway.DetachInternetGateway.run() euca2ools-3.3.1/bin/euca-detach-network-interface000077500000000000000000000002671267461563000217170ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.detachnetworkinterface if __name__ == '__main__': euca2ools.commands.ec2.detachnetworkinterface.DetachNetworkInterface.run() euca2ools-3.3.1/bin/euca-detach-volume000077500000000000000000000002311267461563000175660ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.detachvolume if __name__ == '__main__': euca2ools.commands.ec2.detachvolume.DetachVolume.run() euca2ools-3.3.1/bin/euca-detach-vpn-gateway000077500000000000000000000002451267461563000205260ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.detachvpngateway if __name__ == '__main__': euca2ools.commands.ec2.detachvpngateway.DetachVpnGateway.run() euca2ools-3.3.1/bin/euca-disable-vgw-route-propagation000077500000000000000000000003031267461563000227120ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.disablevgwroutepropagation if __name__ == '__main__': euca2ools.commands.ec2.disablevgwroutepropagation.DisableVgwRoutePropagation.run() euca2ools-3.3.1/bin/euca-disassociate-address000077500000000000000000000002561267461563000211360ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.disassociateaddress if __name__ == '__main__': euca2ools.commands.ec2.disassociateaddress.DisassociateAddress.run() euca2ools-3.3.1/bin/euca-disassociate-route-table000077500000000000000000000002671267461563000217360ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.disassociateroutetable if __name__ == '__main__': euca2ools.commands.ec2.disassociateroutetable.DisassociateRouteTable.run() euca2ools-3.3.1/bin/euca-download-and-unbundle000077500000000000000000000002631267461563000212170ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.bundle.downloadandunbundle if __name__ == '__main__': euca2ools.commands.bundle.downloadandunbundle.DownloadAndUnbundle.run()euca2ools-3.3.1/bin/euca-download-bundle000077500000000000000000000002451267461563000201140ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.bundle.downloadbundle if __name__ == '__main__': euca2ools.commands.bundle.downloadbundle.DownloadBundle.run() euca2ools-3.3.1/bin/euca-enable-vgw-route-propagation000077500000000000000000000003001267461563000225320ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.enablevgwroutepropagation if __name__ == '__main__': euca2ools.commands.ec2.enablevgwroutepropagation.EnableVgwRoutePropagation.run() euca2ools-3.3.1/bin/euca-fingerprint-key000077500000000000000000000002711267461563000201520ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.misc.generatekeyfingerprint if __name__ == '__main__': euca2ools.commands.misc.generatekeyfingerprint.GenerateKeyFingerprint.run() euca2ools-3.3.1/bin/euca-generate-environment-config000077500000000000000000000002601267461563000224320ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.misc.generateenvironment if __name__ == '__main__': euca2ools.commands.misc.generateenvironment.GenerateEnvironment.run() euca2ools-3.3.1/bin/euca-get-console-output000077500000000000000000000002451267461563000206130ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.getconsoleoutput if __name__ == '__main__': euca2ools.commands.ec2.getconsoleoutput.GetConsoleOutput.run() euca2ools-3.3.1/bin/euca-get-password000077500000000000000000000002261267461563000174540ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.getpassword if __name__ == '__main__': euca2ools.commands.ec2.getpassword.GetPassword.run() euca2ools-3.3.1/bin/euca-get-password-data000077500000000000000000000002421267461563000203610ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.getpassworddata if __name__ == '__main__': euca2ools.commands.ec2.getpassworddata.GetPasswordData.run() euca2ools-3.3.1/bin/euca-import-instance000077500000000000000000000002371267461563000201530ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.importinstance if __name__ == '__main__': euca2ools.commands.ec2.importinstance.ImportInstance.run() euca2ools-3.3.1/bin/euca-import-keypair000077500000000000000000000002341267461563000200100ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.importkeypair if __name__ == '__main__': euca2ools.commands.ec2.importkeypair.ImportKeyPair.run() euca2ools-3.3.1/bin/euca-import-volume000077500000000000000000000002311267461563000176500ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.importvolume if __name__ == '__main__': euca2ools.commands.ec2.importvolume.ImportVolume.run() euca2ools-3.3.1/bin/euca-install-image000077500000000000000000000002371267461563000175650ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.bundle.installimage if __name__ == '__main__': euca2ools.commands.bundle.installimage.InstallImage.run() euca2ools-3.3.1/bin/euca-modify-image-attribute000077500000000000000000000002611267461563000214040ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.modifyimageattribute if __name__ == '__main__': euca2ools.commands.ec2.modifyimageattribute.ModifyImageAttribute.run() euca2ools-3.3.1/bin/euca-modify-instance-attribute000077500000000000000000000002721267461563000221300ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.modifyinstanceattribute if __name__ == '__main__': euca2ools.commands.ec2.modifyinstanceattribute.ModifyInstanceAttribute.run() euca2ools-3.3.1/bin/euca-modify-instance-type000077500000000000000000000003061267461563000211040ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.modifyinstancetypeattribute if __name__ == '__main__': euca2ools.commands.ec2.modifyinstancetypeattribute.ModifyInstanceTypeAttribute.run() euca2ools-3.3.1/bin/euca-modify-network-interface-attribute000077500000000000000000000003221267461563000237470ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.modifynetworkinterfaceattribute if __name__ == '__main__': euca2ools.commands.ec2.modifynetworkinterfaceattribute.ModifyNetworkInterfaceAttribute.run() euca2ools-3.3.1/bin/euca-modify-snapshot-attribute000077500000000000000000000002721267461563000221630ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.modifysnapshotattribute if __name__ == '__main__': euca2ools.commands.ec2.modifysnapshotattribute.ModifySnapshotAttribute.run() euca2ools-3.3.1/bin/euca-modify-subnet-attribute000077500000000000000000000002641267461563000216250ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.modifysubnetattribute if __name__ == '__main__': euca2ools.commands.ec2.modifysubnetattribute.ModifySubnetAttribute.run() euca2ools-3.3.1/bin/euca-modify-vpc-attribute000077500000000000000000000002531267461563000211130ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.modifyvpcattribute if __name__ == '__main__': euca2ools.commands.ec2.modifyvpcattribute.ModifyVpcAttribute.run() euca2ools-3.3.1/bin/euca-monitor-instances000077500000000000000000000002451267461563000205120ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.monitorinstances if __name__ == '__main__': euca2ools.commands.ec2.monitorinstances.MonitorInstances.run() euca2ools-3.3.1/bin/euca-reboot-instances000077500000000000000000000002421267461563000203120ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.rebootinstances if __name__ == '__main__': euca2ools.commands.ec2.rebootinstances.RebootInstances.run() euca2ools-3.3.1/bin/euca-register000077500000000000000000000002341267461563000166600ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.registerimage if __name__ == '__main__': euca2ools.commands.ec2.registerimage.RegisterImage.run() euca2ools-3.3.1/bin/euca-reject-vpc-peering-connection000077500000000000000000000003031267461563000226570ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.rejectvpcpeeringconnection if __name__ == '__main__': euca2ools.commands.ec2.rejectvpcpeeringconnection.RejectVpcPeeringConnection.run() euca2ools-3.3.1/bin/euca-release-address000077500000000000000000000002371267461563000201020ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.releaseaddress if __name__ == '__main__': euca2ools.commands.ec2.releaseaddress.ReleaseAddress.run() euca2ools-3.3.1/bin/euca-replace-network-acl-association000077500000000000000000000003111267461563000232010ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.replacenetworkaclassociation if __name__ == '__main__': euca2ools.commands.ec2.replacenetworkaclassociation.ReplaceNetworkAclAssociation.run() euca2ools-3.3.1/bin/euca-replace-network-acl-entry000077500000000000000000000002651267461563000220360ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.modifynetworkaclentry if __name__ == '__main__': euca2ools.commands.ec2.modifynetworkaclentry.ReplaceNetworkAclEntry.run() euca2ools-3.3.1/bin/euca-replace-route000077500000000000000000000002311267461563000176000ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.replaceroute if __name__ == '__main__': euca2ools.commands.ec2.replaceroute.ReplaceRoute.run() euca2ools-3.3.1/bin/euca-replace-route-table-association000077500000000000000000000003111267461563000231760ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.replaceroutetableassociation if __name__ == '__main__': euca2ools.commands.ec2.replaceroutetableassociation.ReplaceRouteTableAssociation.run() euca2ools-3.3.1/bin/euca-reset-image-attribute000077500000000000000000000002561267461563000212430ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.resetimageattribute if __name__ == '__main__': euca2ools.commands.ec2.resetimageattribute.ResetImageAttribute.run() euca2ools-3.3.1/bin/euca-reset-instance-attribute000077500000000000000000000002671267461563000217670ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.resetinstanceattribute if __name__ == '__main__': euca2ools.commands.ec2.resetinstanceattribute.ResetInstanceAttribute.run() euca2ools-3.3.1/bin/euca-reset-network-interface-attribute000077500000000000000000000003171267461563000236060ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.resetnetworkinterfaceattribute if __name__ == '__main__': euca2ools.commands.ec2.resetnetworkinterfaceattribute.ResetNetworkInterfaceAttribute.run() euca2ools-3.3.1/bin/euca-reset-snapshot-attribute000077500000000000000000000002671267461563000220220ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.resetsnapshotattribute if __name__ == '__main__': euca2ools.commands.ec2.resetsnapshotattribute.ResetSnapshotAttribute.run() euca2ools-3.3.1/bin/euca-resume-import000077500000000000000000000002311267461563000176410ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.resumeimport if __name__ == '__main__': euca2ools.commands.ec2.resumeimport.ResumeImport.run() euca2ools-3.3.1/bin/euca-revoke000077500000000000000000000002721267461563000163310ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.modifysecuritygrouprule if __name__ == '__main__': euca2ools.commands.ec2.modifysecuritygrouprule.RevokeSecurityGroupRule.run() euca2ools-3.3.1/bin/euca-run-instances000077500000000000000000000002311267461563000176220ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.runinstances if __name__ == '__main__': euca2ools.commands.ec2.runinstances.RunInstances.run() euca2ools-3.3.1/bin/euca-start-instances000077500000000000000000000002371267461563000201610ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.startinstances if __name__ == '__main__': euca2ools.commands.ec2.startinstances.StartInstances.run() euca2ools-3.3.1/bin/euca-stop-instances000077500000000000000000000002341267461563000200060ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.stopinstances if __name__ == '__main__': euca2ools.commands.ec2.stopinstances.StopInstances.run() euca2ools-3.3.1/bin/euca-terminate-instances000077500000000000000000000002531267461563000210120ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.terminateinstances if __name__ == '__main__': euca2ools.commands.ec2.terminateinstances.TerminateInstances.run() euca2ools-3.3.1/bin/euca-unassign-private-ip-addresses000077500000000000000000000003031267461563000227110ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.unassignprivateipaddresses if __name__ == '__main__': euca2ools.commands.ec2.unassignprivateipaddresses.UnassignPrivateIpAddresses.run() euca2ools-3.3.1/bin/euca-unbundle000077500000000000000000000002231267461563000166460ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.bundle.unbundle if __name__ == '__main__': euca2ools.commands.bundle.unbundle.Unbundle.run() euca2ools-3.3.1/bin/euca-unbundle-stream000077500000000000000000000002451267461563000201430ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.bundle.unbundlestream if __name__ == '__main__': euca2ools.commands.bundle.unbundlestream.UnbundleStream.run() euca2ools-3.3.1/bin/euca-unmonitor-instances000077500000000000000000000002531267461563000210540ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.ec2.unmonitorinstances if __name__ == '__main__': euca2ools.commands.ec2.unmonitorinstances.UnmonitorInstances.run() euca2ools-3.3.1/bin/euca-upload-bundle000077500000000000000000000002371267461563000175720ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.bundle.uploadbundle if __name__ == '__main__': euca2ools.commands.bundle.uploadbundle.UploadBundle.run() euca2ools-3.3.1/bin/euca-version000077500000000000000000000002041267461563000165160ustar00rootroot00000000000000#!/usr/bin/python -tt import sys import euca2ools.commands print >> sys.stderr, euca2ools.commands.Euca2ools().format_version() euca2ools-3.3.1/bin/euform-cancel-update-stack000077500000000000000000000002761267461563000212320ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.cloudformation.cancelupdatestack if __name__ == '__main__': euca2ools.commands.cloudformation.cancelupdatestack.CancelUpdateStack.run() euca2ools-3.3.1/bin/euform-create-stack000077500000000000000000000002541267461563000177640ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.cloudformation.createstack if __name__ == '__main__': euca2ools.commands.cloudformation.createstack.CreateStack.run() euca2ools-3.3.1/bin/euform-delete-stack000077500000000000000000000002541267461563000177630ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.cloudformation.deletestack if __name__ == '__main__': euca2ools.commands.cloudformation.deletestack.DeleteStack.run() euca2ools-3.3.1/bin/euform-describe-stack-events000077500000000000000000000003041267461563000215770ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.cloudformation.describestackevents if __name__ == '__main__': euca2ools.commands.cloudformation.describestackevents.DescribeStackEvents.run() euca2ools-3.3.1/bin/euform-describe-stack-resource000077500000000000000000000003121267461563000221210ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.cloudformation.describestackresource if __name__ == '__main__': euca2ools.commands.cloudformation.describestackresource.DescribeStackResource.run() euca2ools-3.3.1/bin/euform-describe-stack-resources000077500000000000000000000003151267461563000223070ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.cloudformation.describestackresources if __name__ == '__main__': euca2ools.commands.cloudformation.describestackresources.DescribeStackResources.run() euca2ools-3.3.1/bin/euform-describe-stacks000077500000000000000000000002651267461563000204660ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.cloudformation.describestacks if __name__ == '__main__': euca2ools.commands.cloudformation.describestacks.DescribeStacks.run() euca2ools-3.3.1/bin/euform-get-template000077500000000000000000000002541267461563000200060ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.cloudformation.gettemplate if __name__ == '__main__': euca2ools.commands.cloudformation.gettemplate.GetTemplate.run() euca2ools-3.3.1/bin/euform-list-stack-resources000077500000000000000000000003011267461563000214750ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.cloudformation.liststackresources if __name__ == '__main__': euca2ools.commands.cloudformation.liststackresources.ListStackResources.run() euca2ools-3.3.1/bin/euform-list-stacks000077500000000000000000000002511267461563000176540ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.cloudformation.liststacks if __name__ == '__main__': euca2ools.commands.cloudformation.liststacks.ListStacks.run() euca2ools-3.3.1/bin/euform-update-stack000077500000000000000000000002541267461563000200030ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.cloudformation.updatestack if __name__ == '__main__': euca2ools.commands.cloudformation.updatestack.UpdateStack.run() euca2ools-3.3.1/bin/euform-validate-template000077500000000000000000000002731267461563000210210ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.cloudformation.validatetemplate if __name__ == '__main__': euca2ools.commands.cloudformation.validatetemplate.ValidateTemplate.run() euca2ools-3.3.1/bin/euimage-describe-pack000077500000000000000000000002661267461563000202340ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.euimage.describepackedimage if __name__ == '__main__': euca2ools.commands.euimage.describepackedimage.DescribePackedImage.run() euca2ools-3.3.1/bin/euimage-install-pack000077500000000000000000000002631267461563000201170ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.euimage.installpackedimage if __name__ == '__main__': euca2ools.commands.euimage.installpackedimage.InstallPackedImage.run() euca2ools-3.3.1/bin/euimage-pack-image000077500000000000000000000002301267461563000175250ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.euimage.packimage if __name__ == '__main__': euca2ools.commands.euimage.packimage.PackImage.run() euca2ools-3.3.1/bin/eulb-apply-security-groups-to-lb000077500000000000000000000003721267461563000223730ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.applysecuritygroupstoloadbalancer if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.applysecuritygroupstoloadbalancer.ApplySecurityGroupsToLoadBalancer.run() euca2ools-3.3.1/bin/eulb-attach-lb-to-subnets000077500000000000000000000003501267461563000210050ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.attachloadbalancertosubnets if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.attachloadbalancertosubnets.AttachLoadBalancerToSubnets.run() euca2ools-3.3.1/bin/eulb-configure-healthcheck000077500000000000000000000003231267461563000212670ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.configurehealthcheck if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.configurehealthcheck.ConfigureHealthCheck.run() euca2ools-3.3.1/bin/eulb-create-app-cookie-stickiness-policy000077500000000000000000000003641267461563000240140ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.createappcookiestickinesspolicy if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.createappcookiestickinesspolicy.CreateAppCookieStickinessPolicy.run() euca2ools-3.3.1/bin/eulb-create-lb000077500000000000000000000003151267461563000167040ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.createloadbalancer if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.createloadbalancer.CreateLoadBalancer.run() euca2ools-3.3.1/bin/eulb-create-lb-cookie-stickiness-policy000077500000000000000000000003611267461563000236260ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.createlbcookiestickinesspolicy if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.createlbcookiestickinesspolicy.CreateLBCookieStickinessPolicy.run() euca2ools-3.3.1/bin/eulb-create-lb-listeners000077500000000000000000000003501267461563000207110ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.createloadbalancerlisteners if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.createloadbalancerlisteners.CreateLoadBalancerListeners.run() euca2ools-3.3.1/bin/eulb-create-lb-policy000077500000000000000000000003371267461563000202050ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.createloadbalancerpolicy if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.createloadbalancerpolicy.CreateLoadBalancerPolicy.run() euca2ools-3.3.1/bin/eulb-create-tags000077500000000000000000000002541267461563000172470ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.addtags if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.addtags.AddTags.run() euca2ools-3.3.1/bin/eulb-delete-lb000077500000000000000000000003151267461563000167030ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.deleteloadbalancer if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.deleteloadbalancer.DeleteLoadBalancer.run() euca2ools-3.3.1/bin/eulb-delete-lb-listeners000077500000000000000000000003501267461563000207100ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.deleteloadbalancerlisteners if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.deleteloadbalancerlisteners.DeleteLoadBalancerListeners.run() euca2ools-3.3.1/bin/eulb-delete-lb-policy000077500000000000000000000003371267461563000202040ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.deleteloadbalancerpolicy if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.deleteloadbalancerpolicy.DeleteLoadBalancerPolicy.run() euca2ools-3.3.1/bin/eulb-delete-tags000077500000000000000000000002651267461563000172500ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.removetags if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.removetags.RemoveTags.run() euca2ools-3.3.1/bin/eulb-deregister-instances-from-lb000077500000000000000000000004001267461563000225170ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.deregisterinstancesfromloadbalancer if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.deregisterinstancesfromloadbalancer.DeregisterInstancesFromLoadBalancer.run() euca2ools-3.3.1/bin/eulb-describe-instance-health000077500000000000000000000003311267461563000216710ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.describeinstancehealth if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.describeinstancehealth.DescribeInstanceHealth.run() euca2ools-3.3.1/bin/eulb-describe-lb-attributes000077500000000000000000000003611267461563000214060ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.describeloadbalancerattributes if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.describeloadbalancerattributes.DescribeLoadBalancerAttributes.run() euca2ools-3.3.1/bin/eulb-describe-lb-policies000077500000000000000000000003531267461563000210300ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.describeloadbalancerpolicies if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.describeloadbalancerpolicies.DescribeLoadBalancerPolicies.run() euca2ools-3.3.1/bin/eulb-describe-lb-policy-types000077500000000000000000000003641267461563000216640ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.describeloadbalancerpolicytypes if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.describeloadbalancerpolicytypes.DescribeLoadBalancerPolicyTypes.run() euca2ools-3.3.1/bin/eulb-describe-lbs000077500000000000000000000003261267461563000174060ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.describeloadbalancers if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.describeloadbalancers.DescribeLoadBalancers.run() euca2ools-3.3.1/bin/eulb-describe-tags000077500000000000000000000002731267461563000175650ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.describetags if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.describetags.DescribeTags.run() euca2ools-3.3.1/bin/eulb-detach-lb-from-subnets000077500000000000000000000003561267461563000213200ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.detachloadbalancerfromsubnets if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.detachloadbalancerfromsubnets.DetachLoadBalancerFromSubnets.run() euca2ools-3.3.1/bin/eulb-disable-zones-for-lb000077500000000000000000000004141267461563000207640ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.disableavailabilityzonesforloadbalancer if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.disableavailabilityzonesforloadbalancer.DisableAvailabilityZonesForLoadBalancer.run() euca2ools-3.3.1/bin/eulb-enable-zones-for-lb000077500000000000000000000004111267461563000206040ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.enableavailabilityzonesforloadbalancer if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.enableavailabilityzonesforloadbalancer.EnableAvailabilityZonesForLoadBalancer.run() euca2ools-3.3.1/bin/eulb-modify-lb-attributes000077500000000000000000000003531267461563000211160ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.modifyloadbalancerattributes if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.modifyloadbalancerattributes.ModifyLoadBalancerAttributes.run() euca2ools-3.3.1/bin/eulb-register-instances-with-lb000077500000000000000000000003721267461563000222260ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.registerinstanceswithloadbalancer if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.registerinstanceswithloadbalancer.RegisterInstancesWithLoadBalancer.run() euca2ools-3.3.1/bin/eulb-set-lb-listener-ssl-cert000077500000000000000000000004061267461563000216120ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.setloadbalancerlistenersslcertificate if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.setloadbalancerlistenersslcertificate.SetLoadBalancerListenerSSLCertificate.run() euca2ools-3.3.1/bin/eulb-set-lb-policies-for-backend-server000077500000000000000000000004141267461563000235160ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.setloadbalancerpoliciesforbackendserver if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.setloadbalancerpoliciesforbackendserver.SetLoadBalancerPoliciesForBackendServer.run() euca2ools-3.3.1/bin/eulb-set-lb-policies-of-listener000077500000000000000000000003721267461563000222710ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.elasticloadbalancing.setloadbalancerpoliciesoflistener if __name__ == '__main__': euca2ools.commands.elasticloadbalancing.setloadbalancerpoliciesoflistener.SetLoadBalancerPoliciesOfListener.run() euca2ools-3.3.1/bin/euscale-create-auto-scaling-group000077500000000000000000000003071267461563000225220ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.createautoscalinggroup if __name__ == '__main__': euca2ools.commands.autoscaling.createautoscalinggroup.CreateAutoScalingGroup.run() euca2ools-3.3.1/bin/euscale-create-launch-config000077500000000000000000000003201267461563000215120ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.createlaunchconfiguration if __name__ == '__main__': euca2ools.commands.autoscaling.createlaunchconfiguration.CreateLaunchConfiguration.run() euca2ools-3.3.1/bin/euscale-create-or-update-tags000077500000000000000000000002731267461563000216400ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.createorupdatetags if __name__ == '__main__': euca2ools.commands.autoscaling.createorupdatetags.CreateOrUpdateTags.run() euca2ools-3.3.1/bin/euscale-delete-auto-scaling-group000077500000000000000000000003071267461563000225210ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.deleteautoscalinggroup if __name__ == '__main__': euca2ools.commands.autoscaling.deleteautoscalinggroup.DeleteAutoScalingGroup.run() euca2ools-3.3.1/bin/euscale-delete-launch-config000077500000000000000000000003201267461563000215110ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.deletelaunchconfiguration if __name__ == '__main__': euca2ools.commands.autoscaling.deletelaunchconfiguration.DeleteLaunchConfiguration.run() euca2ools-3.3.1/bin/euscale-delete-notification-configuration000077500000000000000000000003421267461563000243330ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.deletenotificationconfiguration if __name__ == '__main__': euca2ools.commands.autoscaling.deletenotificationconfiguration.DeleteNotificationConfiguration.run() euca2ools-3.3.1/bin/euscale-delete-policy000077500000000000000000000002511267461563000202760ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.deletepolicy if __name__ == '__main__': euca2ools.commands.autoscaling.deletepolicy.DeletePolicy.run() euca2ools-3.3.1/bin/euscale-delete-scheduled-action000077500000000000000000000003041267461563000222110ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.deletescheduledaction if __name__ == '__main__': euca2ools.commands.autoscaling.deletescheduledaction.DeleteScheduledAction.run() euca2ools-3.3.1/bin/euscale-delete-tags000077500000000000000000000002431267461563000177360ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.deletetags if __name__ == '__main__': euca2ools.commands.autoscaling.deletetags.DeleteTags.run() euca2ools-3.3.1/bin/euscale-describe-account-limits000077500000000000000000000003041267461563000222470ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.describeaccountlimits if __name__ == '__main__': euca2ools.commands.autoscaling.describeaccountlimits.DescribeAccountLimits.run() euca2ools-3.3.1/bin/euscale-describe-adjustment-types000077500000000000000000000003121267461563000226330ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.describeadjustmenttypes if __name__ == '__main__': euca2ools.commands.autoscaling.describeadjustmenttypes.DescribeAdjustmentTypes.run() euca2ools-3.3.1/bin/euscale-describe-auto-scaling-groups000077500000000000000000000003201267461563000232150ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.describeautoscalinggroups if __name__ == '__main__': euca2ools.commands.autoscaling.describeautoscalinggroups.DescribeAutoScalingGroups.run() euca2ools-3.3.1/bin/euscale-describe-auto-scaling-instances000077500000000000000000000003311267461563000236670ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.describeautoscalinginstances if __name__ == '__main__': euca2ools.commands.autoscaling.describeautoscalinginstances.DescribeAutoScalingInstances.run() euca2ools-3.3.1/bin/euscale-describe-auto-scaling-notification-types000077500000000000000000000003611267461563000255330ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.describeautoscalingnotificationtypes if __name__ == '__main__': euca2ools.commands.autoscaling.describeautoscalingnotificationtypes.DescribeAutoScalingNotificationTypes.run() euca2ools-3.3.1/bin/euscale-describe-launch-configs000077500000000000000000000003311267461563000222140ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.describelaunchconfigurations if __name__ == '__main__': euca2ools.commands.autoscaling.describelaunchconfigurations.DescribeLaunchConfigurations.run() euca2ools-3.3.1/bin/euscale-describe-metric-collection-types000077500000000000000000000003341267461563000240750ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.describemetriccollectiontypes if __name__ == '__main__': euca2ools.commands.autoscaling.describemetriccollectiontypes.DescribeMetricCollectionTypes.run() euca2ools-3.3.1/bin/euscale-describe-notification-configurations000077500000000000000000000003531267461563000250360ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.describenotificationconfigurations if __name__ == '__main__': euca2ools.commands.autoscaling.describenotificationconfigurations.DescribeNotificationConfigurations.run() euca2ools-3.3.1/bin/euscale-describe-policies000077500000000000000000000002651267461563000211310ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.describepolicies if __name__ == '__main__': euca2ools.commands.autoscaling.describepolicies.DescribePolicies.run() euca2ools-3.3.1/bin/euscale-describe-process-types000077500000000000000000000003261267461563000221400ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.describescalingprocesstypes if __name__ == '__main__': euca2ools.commands.autoscaling.describescalingprocesstypes.DescribeScalingProcessTypes.run() euca2ools-3.3.1/bin/euscale-describe-scaling-activities000077500000000000000000000003201267461563000230740ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.describescalingactivities if __name__ == '__main__': euca2ools.commands.autoscaling.describescalingactivities.DescribeScalingActivities.run() euca2ools-3.3.1/bin/euscale-describe-scheduled-actions000077500000000000000000000003151267461563000227140ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.describescheduledactions if __name__ == '__main__': euca2ools.commands.autoscaling.describescheduledactions.DescribeScheduledActions.run() euca2ools-3.3.1/bin/euscale-describe-tags000077500000000000000000000002511267461563000202530ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.describetags if __name__ == '__main__': euca2ools.commands.autoscaling.describetags.DescribeTags.run() euca2ools-3.3.1/bin/euscale-describe-termination-policy-types000077500000000000000000000003371267461563000243120ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.describeterminationpolicytypes if __name__ == '__main__': euca2ools.commands.autoscaling.describeterminationpolicytypes.DescribeTerminationPolicyTypes.run() euca2ools-3.3.1/bin/euscale-disable-metrics-collection000077500000000000000000000003151267461563000227400ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.disablemetricscollection if __name__ == '__main__': euca2ools.commands.autoscaling.disablemetricscollection.DisableMetricsCollection.run() euca2ools-3.3.1/bin/euscale-enable-metrics-collection000077500000000000000000000003121267461563000225600ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.enablemetricscollection if __name__ == '__main__': euca2ools.commands.autoscaling.enablemetricscollection.EnableMetricsCollection.run() euca2ools-3.3.1/bin/euscale-execute-policy000077500000000000000000000002541267461563000205010ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.executepolicy if __name__ == '__main__': euca2ools.commands.autoscaling.executepolicy.ExecutePolicy.run() euca2ools-3.3.1/bin/euscale-put-notification-configuration000077500000000000000000000003311267461563000236770ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.putnotificationconfiguration if __name__ == '__main__': euca2ools.commands.autoscaling.putnotificationconfiguration.PutNotificationConfiguration.run() euca2ools-3.3.1/bin/euscale-put-scaling-policy000077500000000000000000000002651267461563000212670ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.putscalingpolicy if __name__ == '__main__': euca2ools.commands.autoscaling.putscalingpolicy.PutScalingPolicy.run() euca2ools-3.3.1/bin/euscale-put-scheduled-update-group-action000077500000000000000000000003341267461563000241740ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.putscheduledupdategroupaction if __name__ == '__main__': euca2ools.commands.autoscaling.putscheduledupdategroupaction.PutScheduledUpdateGroupAction.run() euca2ools-3.3.1/bin/euscale-resume-processes000077500000000000000000000002621267461563000210450ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.resumeprocesses if __name__ == '__main__': euca2ools.commands.autoscaling.resumeprocesses.ResumeProcesses.run() euca2ools-3.3.1/bin/euscale-set-desired-capacity000077500000000000000000000002731267461563000215460ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.setdesiredcapacity if __name__ == '__main__': euca2ools.commands.autoscaling.setdesiredcapacity.SetDesiredCapacity.run() euca2ools-3.3.1/bin/euscale-set-instance-health000077500000000000000000000002701267461563000214000ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.setinstancehealth if __name__ == '__main__': euca2ools.commands.autoscaling.setinstancehealth.SetInstanceHealth.run() euca2ools-3.3.1/bin/euscale-suspend-processes000077500000000000000000000002651267461563000212310ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.suspendprocesses if __name__ == '__main__': euca2ools.commands.autoscaling.suspendprocesses.SuspendProcesses.run() euca2ools-3.3.1/bin/euscale-terminate-instance-in-auto-scaling-group000077500000000000000000000003561267461563000254610ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.terminateinstanceinautoscalinggroup if __name__ == '__main__': euca2ools.commands.autoscaling.terminateinstanceinautoscalinggroup.TerminateInstanceInAutoScalingGroup.run() euca2ools-3.3.1/bin/euscale-update-auto-scaling-group000077500000000000000000000003071267461563000225410ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.autoscaling.updateautoscalinggroup if __name__ == '__main__': euca2ools.commands.autoscaling.updateautoscalinggroup.UpdateAutoScalingGroup.run() euca2ools-3.3.1/bin/euwatch-delete-alarms000077500000000000000000000002471267461563000203020ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.monitoring.deletealarms if __name__ == '__main__': euca2ools.commands.monitoring.deletealarms.DeleteAlarms.run() euca2ools-3.3.1/bin/euwatch-describe-alarm-history000077500000000000000000000002771267461563000221370ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.monitoring.describealarmhistory if __name__ == '__main__': euca2ools.commands.monitoring.describealarmhistory.DescribeAlarmHistory.run() euca2ools-3.3.1/bin/euwatch-describe-alarms000077500000000000000000000002551267461563000206170ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.monitoring.describealarms if __name__ == '__main__': euca2ools.commands.monitoring.describealarms.DescribeAlarms.run() euca2ools-3.3.1/bin/euwatch-describe-alarms-for-metric000077500000000000000000000003101267461563000226540ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.monitoring.describealarmsformetric if __name__ == '__main__': euca2ools.commands.monitoring.describealarmsformetric.DescribeAlarmsForMetric.run() euca2ools-3.3.1/bin/euwatch-disable-alarm-actions000077500000000000000000000002741267461563000217160ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.monitoring.disablealarmactions if __name__ == '__main__': euca2ools.commands.monitoring.disablealarmactions.DisableAlarmActions.run() euca2ools-3.3.1/bin/euwatch-enable-alarm-actions000077500000000000000000000002711267461563000215360ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.monitoring.enablealarmactions if __name__ == '__main__': euca2ools.commands.monitoring.enablealarmactions.EnableAlarmActions.run() euca2ools-3.3.1/bin/euwatch-get-stats000077500000000000000000000002741267461563000174760ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.monitoring.getmetricstatistics if __name__ == '__main__': euca2ools.commands.monitoring.getmetricstatistics.GetMetricStatistics.run() euca2ools-3.3.1/bin/euwatch-list-metrics000077500000000000000000000002441267461563000201770ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.monitoring.listmetrics if __name__ == '__main__': euca2ools.commands.monitoring.listmetrics.ListMetrics.run() euca2ools-3.3.1/bin/euwatch-put-data000077500000000000000000000002521267461563000172760ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.monitoring.putmetricdata if __name__ == '__main__': euca2ools.commands.monitoring.putmetricdata.PutMetricData.run() euca2ools-3.3.1/bin/euwatch-put-metric-alarm000077500000000000000000000002551267461563000207450ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.monitoring.putmetricalarm if __name__ == '__main__': euca2ools.commands.monitoring.putmetricalarm.PutMetricAlarm.run() euca2ools-3.3.1/bin/euwatch-set-alarm-state000077500000000000000000000002521267461563000205620ustar00rootroot00000000000000#!/usr/bin/python -tt import euca2ools.commands.monitoring.setalarmstate if __name__ == '__main__': euca2ools.commands.monitoring.setalarmstate.SetAlarmState.run() euca2ools-3.3.1/certs/000077500000000000000000000000001267461563000145445ustar00rootroot00000000000000euca2ools-3.3.1/certs/cert-ec2-cn-north-1.pem000066400000000000000000000032541267461563000205430ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIEwTCCA6mgAwIBAgIJALBg5STuwebSMA0GCSqGSIb3DQEBBQUAMIGbMQswCQYD VQQGEwJaQTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRv d24xHDAaBgNVBAoTE0FtYXpvbiBXZWIgU2VydmljZXMxDDAKBgNVBAsTA0VDMjEW MBQGA1UEAxMNQU1JIE1hbmlmZXN0czEdMBsGCSqGSIb3DQEJARYOYWVzQGFtYXpv bi5jb20wHhcNMTMwODI4MTAxNTEwWhcNMTkwMjE4MTAxNTEwWjCBmzELMAkGA1UE BhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3du MRwwGgYDVQQKExNBbWF6b24gV2ViIFNlcnZpY2VzMQwwCgYDVQQLEwNFQzIxFjAU BgNVBAMTDUFNSSBNYW5pZmVzdHMxHTAbBgkqhkiG9w0BCQEWDmFlc0BhbWF6b24u Y29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA601VE9anUnkM5weg THEUqNkT7fwaKKoTM+oV6n0h5D4LF/qY7IuS7YlxP308P00yE6In4ZHHvc1E/X1e s36t7ojdlx8Pg0jzFLir27BWSl+ddZGJLl0u8FFzJUPmqeiQZW3mKosOqAoj/C5h svXnSmLGxd619eGz2+Kel38LPhwzA8PZeNhil/eK53oo/h7dZvRUtH2+zbYXxq5Q 2tsRN1Ef4QaNeKHSdupo8eFNUnmSgeEYz1RC/2QDn6MK7uXijOft4G6iEO4c+PeR wLyBW8YMla2SJk1n4z4gmSJ21uCZ0Bv0A2j/3f+JmgNo4QLIAl/UBWBTT+eSAFYw LVDlrwIDAQABo4IBBDCCAQAwHQYDVR0OBBYEFJSvQRrRg2O1O/kSOEKH2z18OFfH MIHQBgNVHSMEgcgwgcWAFJSvQRrRg2O1O/kSOEKH2z18OFfHoYGhpIGeMIGbMQsw CQYDVQQGEwJaQTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBl IFRvd24xHDAaBgNVBAoTE0FtYXpvbiBXZWIgU2VydmljZXMxDDAKBgNVBAsTA0VD MjEWMBQGA1UEAxMNQU1JIE1hbmlmZXN0czEdMBsGCSqGSIb3DQEJARYOYWVzQGFt YXpvbi5jb22CCQCwYOUk7sHm0jAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUA A4IBAQACBMJpb8N7cT0PP3u814D1Ngd2vqEv6aB8saklT44kWwAXDcILVtPd09ae 8q1oWSKpWlGo9Z8gUS92QXMIMxSZCxDdN4MflYWGio5HFvpS/msHVkK9H80nypSd pLS3FP0arr/3tETS8TIhs4aISwUUfHm0W7WrmLaQz8TyfuktVtPrKIMmWgXiJmCo HQkuFe4rjx0y7r8CGQocwo79+m+35aLip44jWB4yLuUgp0wVhT5nxfG/iNX2lUiP Bw/yCpzeJoLBWvFDlunBNu2s0Y3ddFdnlna/k7CQM1Js6+OGQBMh1zTtJlPkkHj3 mbaTR6i5yro01FowChTryrRTVfMe -----END CERTIFICATE----- euca2ools-3.3.1/certs/cert-ec2-gov.pem000066400000000000000000000017651267461563000174550ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIICvzCCAigCCQD3V6lFvX6dzDANBgkqhkiG9w0BAQUFADCBozELMAkGA1UEBhMC VVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMRMwEQYDVQQKEwpBbWF6 b24uY29tMRYwFAYDVQQLEw1FQzIgQXV0aG9yaXR5MRowGAYDVQQDExFFQzIgQU1J IEF1dGhvcml0eTEsMCoGCSqGSIb3DQEJARYdZWMyLWFtaS1nb3Ytd2VzdC0xQGFt YXpvbi5jb20wHhcNMTEwODEyMTcyNjE1WhcNMjEwODA5MTcyNjE1WjCBozELMAkG A1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMRMwEQYDVQQK EwpBbWF6b24uY29tMRYwFAYDVQQLEw1FQzIgQXV0aG9yaXR5MRowGAYDVQQDExFF QzIgQU1JIEF1dGhvcml0eTEsMCoGCSqGSIb3DQEJARYdZWMyLWFtaS1nb3Ytd2Vz dC0xQGFtYXpvbi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANshKnhw DUZ2/6VJwVTsXMUI1CGd5rpSpSLUCHGuqII+BDUvnp/sPxd1u6+I1QrbaaBAOm6+ evM77M7vNJXY3+JW00VOs9NgPEXBmn6UV4R1P7DljKurWGmRp8Fj1yVU4sSgZqqv 74SyhD0Z4ASczVcOiTZICeuQoJwmeZ8F20oLAgMBAAEwDQYJKoZIhvcNAQEFBQAD gYEAH3vpkD80ngP1e18UYSVBCODArik+aeUPAzJrPDYorrnffbamks50IMTktyiu za1JuplrvVsAKcQhyoPOq69bwRDg4L8VOXSCjjvsNuEhHL603h8jn6ghEouPCPl7 8s4Sr5XikmAgwFcPb/frNnLuZsSol08tISgPOlFg4KLv/bo= -----END CERTIFICATE----- euca2ools-3.3.1/certs/cert-ec2.pem000066400000000000000000000025431267461563000166570ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIDzjCCAzegAwIBAgIJALDnZV+lpZdSMA0GCSqGSIb3DQEBBQUAMIGhMQswCQYD VQQGEwJaQTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRv d24xJzAlBgNVBAoTHkFtYXpvbiBEZXZlbG9wbWVudCBDZW50cmUgKFNBKTEMMAoG A1UECxMDQUVTMREwDwYDVQQDEwhBRVMgVGVzdDEdMBsGCSqGSIb3DQEJARYOYWVz QGFtYXpvbi5jb20wHhcNMDUwODA5MTYwMTA5WhcNMDYwODA5MTYwMTA5WjCBoTEL MAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2Fw ZSBUb3duMScwJQYDVQQKEx5BbWF6b24gRGV2ZWxvcG1lbnQgQ2VudHJlIChTQSkx DDAKBgNVBAsTA0FFUzERMA8GA1UEAxMIQUVTIFRlc3QxHTAbBgkqhkiG9w0BCQEW DmFlc0BhbWF6b24uY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8v/X5 zZv8CAVfNmvBM0br/RUcf1wU8xC5d2otFQQsQKB3qiWoj3oHeOWskOlTPFVZ8N+/ hEaMjyOUkg2+g6XEagCQtFCEBzUVoMjiQIBPiWj5CWkFtlav2zt33LZ0ErTND4xl j7FQFqbaytHU9xuQcFO2p12bdITiBs5Kwoi9bQIDAQABo4IBCjCCAQYwHQYDVR0O BBYEFPQnsX1kDVzPtX+38ACV8RhoYcw8MIHWBgNVHSMEgc4wgcuAFPQnsX1kDVzP tX+38ACV8RhoYcw8oYGnpIGkMIGhMQswCQYDVQQGEwJaQTEVMBMGA1UECBMMV2Vz dGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRvd24xJzAlBgNVBAoTHkFtYXpvbiBE ZXZlbG9wbWVudCBDZW50cmUgKFNBKTEMMAoGA1UECxMDQUVTMREwDwYDVQQDEwhB RVMgVGVzdDEdMBsGCSqGSIb3DQEJARYOYWVzQGFtYXpvbi5jb22CCQCw52VfpaWX UjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAJJlWll4uGlrqBzeIw7u M3RvomlxMESwGKb9gI+ZeORlnHAyZxvd9XngIcjPuU+8uc3wc10LRQUCn45a5hFs zaCp9BSewLCCirn6awZn2tP8JlagSbjrN9YShStt8S3S/Jj+eBoRvc7jJnmEeMkx O0wHOzp5ZHRDK7tGULD6jCfU -----END CERTIFICATE----- euca2ools-3.3.1/conf/000077500000000000000000000000001267461563000143515ustar00rootroot00000000000000euca2ools-3.3.1/conf/bundle-vol/000077500000000000000000000000001267461563000164205ustar00rootroot00000000000000euca2ools-3.3.1/conf/bundle-vol/excludes000066400000000000000000000004661267461563000201650ustar00rootroot00000000000000# This file is passed to rsync's --exclude-from option. - *~ - *.nfs* - *.pem - *.priv - *.sw - *.swo - *.swp - *.gpg - *.jks - *id_dsa* - *id_rsa* - .bash_history - .gnupg/** - .ssh/authorized_keys - .zsh_history - /dev/** - /etc/udev/rules.d/*-persistent-net.rules - /media/** - /mnt/** - /proc/** - /sys/** euca2ools-3.3.1/conf/bundle-vol/fstab000066400000000000000000000003411267461563000174400ustar00rootroot00000000000000/dev/sda1 / auto defaults 1 1 /dev/sdb /mnt auto nofail 2 0 none /dev/pts devpts gid=5,mode=620 0 0 none /proc proc defaults 0 0 none /sys sysfs defaults 0 0 euca2ools-3.3.1/conf/conf.d/000077500000000000000000000000001267461563000155205ustar00rootroot00000000000000euca2ools-3.3.1/conf/conf.d/aws.ini000066400000000000000000000143061267461563000170170ustar00rootroot00000000000000; Amazon Web Services ; http://docs.aws.amazon.com/general/latest/gr/rande.html [region aws:*] iam-url = use aws:us-east-1 sts-url = use aws:us-east-1 certificate = /usr/share/euca2ools/certs/cert-ec2.pem verify-ssl = true vpn-stylesheet = http://ec2-downloads.s3.amazonaws.com/2009-07-15/customer-gateway-{format}.xslt [region aws:us-east-1] ; Northern Virginia, USA autoscaling-url = https://autoscaling.us-east-1.amazonaws.com/ cloudformation-url = https://cloudformation.us-east-1.amazonaws.com/ ec2-url = https://ec2.us-east-1.amazonaws.com/ elasticloadbalancing-url = https://elasticloadbalancing.us-east-1.amazonaws.com/ iam-url = https://iam.amazonaws.com/ monitoring-url = https://monitoring.us-east-1.amazonaws.com/ s3-url = https://s3.amazonaws.com/ sts-url = https://sts.amazonaws.com/ swf-url = https://swf.us-east-1.amazonaws.com/ [region aws:us-west-1] ; Northern California, USA autoscaling-url = https://autoscaling.us-west-1.amazonaws.com/ cloudformation-url = https://cloudformation.us-west-1.amazonaws.com/ ec2-url = https://ec2.us-west-1.amazonaws.com/ elasticloadbalancing-url = https://elasticloadbalancing.us-west-1.amazonaws.com/ monitoring-url = https://monitoring.us-west-1.amazonaws.com/ s3-url = https://s3-us-west-1.amazonaws.com/ swf-url = https://swf.us-west-1.amazonaws.com/ s3-location-constraint = us-west-1 [region aws:us-west-2] ; Oregon, USA autoscaling-url = https://autoscaling.us-west-2.amazonaws.com/ cloudformation-url = https://cloudformation.us-west-2.amazonaws.com/ ec2-url = https://ec2.us-west-2.amazonaws.com/ elasticloadbalancing-url = https://elasticloadbalancing.us-west-2.amazonaws.com/ monitoring-url = https://monitoring.us-west-2.amazonaws.com/ s3-url = https://s3-us-west-2.amazonaws.com/ swf-url = https://swf.us-west-2.amazonaws.com/ s3-location-constraint = us-west-2 [region aws:eu-west-1] ; Ireland autoscaling-url = https://autoscaling.eu-west-1.amazonaws.com/ cloudformation-url = https://cloudformation.eu-west-1.amazonaws.com/ ec2-url = https://ec2.eu-west-1.amazonaws.com/ elasticloadbalancing-url = https://elasticloadbalancing.eu-west-1.amazonaws.com/ monitoring-url = https://monitoring.eu-west-1.amazonaws.com/ s3-url = https://s3-eu-west-1.amazonaws.com/ swf-url = https://swf.eu-west-1.amazonaws.com/ s3-location-constraint = EU [region aws:eu-central-1] ; Frankfurt, Germany autoscaling-url = https://autoscaling.eu-central-1.amazonaws.com/ cloudformation-url = https://cloudformation.eu-central-1.amazonaws.com/ ec2-url = https://ec2.eu-central-1.amazonaws.com/ elasticloadbalancing-url = https://elasticloadbalancing.eu-central-1.amazonaws.com/ monitoring-url = https://monitoring.eu-central-1.amazonaws.com/ s3-url = https://s3-eu-central-1.amazonaws.com/ swf-url = https://swf.eu-central-1.amazonaws.com/ s3-location-constraint = eu-central-1 s3-force-sigv4 = true [region aws:ap-southeast-1] ; Singapore autoscaling-url = https://autoscaling.ap-southeast-1.amazonaws.com/ cloudformation-url = https://cloudformation.ap-southeast-1.amazonaws.com/ ec2-url = https://ec2.ap-southeast-1.amazonaws.com/ elasticloadbalancing-url = https://elasticloadbalancing.ap-southeast-1.amazonaws.com/ monitoring-url = https://monitoring.ap-southeast-1.amazonaws.com/ s3-url = https://s3-ap-southeast-1.amazonaws.com/ swf-url = https://swf.ap-southeast-1.amazonaws.com/ s3-location-constraint = ap-southeast-1 [region aws:ap-southeast-2] ; Sydney, Australia autoscaling-url = https://autoscaling.ap-southeast-2.amazonaws.com/ cloudformation-url = https://cloudformation.ap-southeast-2.amazonaws.com/ ec2-url = https://ec2.ap-southeast-2.amazonaws.com/ elasticloadbalancing-url = https://elasticloadbalancing.ap-southeast-2.amazonaws.com/ monitoring-url = https://monitoring.ap-southeast-2.amazonaws.com/ s3-url = https://s3-ap-southeast-2.amazonaws.com/ swf-url = https://swf.ap-southeast-2.amazonaws.com/ s3-location-constraint = ap-southeast-2 [region aws:ap-northeast-1] ; Tokyo, Japan autoscaling-url = https://autoscaling.ap-northeast-1.amazonaws.com/ cloudformation-url = https://cloudformation.ap-northeast-1.amazonaws.com/ ec2-url = https://ec2.ap-northeast-1.amazonaws.com/ elasticloadbalancing-url = https://elasticloadbalancing.ap-northeast-1.amazonaws.com/ monitoring-url = https://monitoring.ap-northeast-1.amazonaws.com/ s3-url = https://s3-ap-northeast-1.amazonaws.com/ swf-url = https://swf.ap-northeast-1.amazonaws.com/ s3-location-constraint = ap-northeast-1 [region aws:sa-east-1] ; São Paulo, Brazil autoscaling-url = https://autoscaling.sa-east-1.amazonaws.com/ cloudformation-url = https://cloudformation.sa-east-1.amazonaws.com/ ec2-url = https://ec2.sa-east-1.amazonaws.com/ elasticloadbalancing-url = https://elasticloadbalancing.sa-east-1.amazonaws.com/ monitoring-url = https://monitoring.sa-east-1.amazonaws.com/ s3-url = https://s3-sa-east-1.amazonaws.com/ swf-url = https://swf.sa-east-1.amazonaws.com/ s3-location-constraint = sa-east-1 [region aws:us-gov-west-1] ; GovCloud autoscaling-url = https://autoscaling.us-gov-west-1.amazonaws.com/ cloudformation-url = https://cloudformation.us-gov-west-1.amazonaws.com/ ec2-url = https://ec2.us-gov-west-1.amazonaws.com/ elasticloadbalancing-url = https://elasticloadbalancing.us-gov-west-1.amazonaws.com/ iam-url = https://iam.us-gov.amazonaws.com/ monitoring-url = https://monitoring.us-gov-west-1.amazonaws.com/ s3-url = https://s3-us-gov-west-1.amazonaws.com/ sts-url = https://sts.us-gov-west-1.amazonaws.com/ swf-url = https://swf.us-gov-west-1.amazonaws.com/ certificate = /usr/share/euca2ools/certs/cert-ec2-gov.pem s3-location-constraint = us-gov-west-1 [region aws:cn-north-1] ; Beijing, China autoscaling-url = https://autoscaling.cn-north-1.amazonaws.com.cn/ cloudformation-url = https://cloudformation.cn-north-1.amazonaws.com.cn/ ec2-url = https://ec2.cn-north-1.amazonaws.com.cn/ elasticloadbalancing-url = https://elasticloadbalancing.cn-north-1.amazonaws.com.cn/ iam-url = https://iam.cn-north-1.amazonaws.com.cn/ monitoring-url = https://monitoring.cn-north-1.amazonaws.com.cn/ s3-url = https://s3.cn-north-1.amazonaws.com.cn/ sts-url = https://sts.cn-north-1.amazonaws.com.cn/ swf-url = https://swf.cn-north-1.amazonaws.com.cn/ certificate = /usr/share/euca2ools/certs/cert-ec2-cn-north-1.pem s3-location-constraint = cn-north-1 s3-force-sigv4 = true euca2ools-3.3.1/conf/conf.d/localhost.ini000066400000000000000000000013721267461563000202140ustar00rootroot00000000000000; Eucalyptus (all user services on localhost) [region localhost] autoscaling-url = http://127.0.0.1:8773/services/AutoScaling/ cloudformation-url = http://127.0.0.1:8773/services/CloudFormation/ ec2-url = http://127.0.0.1:8773/services/compute/ elasticloadbalancing-url = http://127.0.0.1:8773/services/LoadBalancing/ iam-url = http://127.0.0.1:8773/services/Euare/ monitoring-url = http://127.0.0.1:8773/services/CloudWatch/ s3-url = http://127.0.0.1:8773/services/objectstorage/ sts-url = http://127.0.0.1:8773/services/Tokens/ bootstrap-url = http://127.0.0.1:8773/services/Empyrean/ properties-url = http://127.0.0.1:8773/services/Properties/ reporting-url = http://127.0.0.1:8773/services/Reporting/ certificate = /var/lib/eucalyptus/keys/cloud-cert.pem euca2ools-3.3.1/conf/euca2ools.ini000066400000000000000000000012651267461563000167520ustar00rootroot00000000000000; Main euca2ools configuration file ; ; Euca2ools commands get their configuration from the following sources: ; - /etc/euca2ools/euca2ools.ini (this file) ; - /etc/euca2ools/conf.d/*.ini ; - ~/.euca/*.ini ; ; The list of URLs for your cloud of choice is not enough to use it -- ; you will also need to obtain credentials from it and supply them at ; the command line or in a section like the following: ; ; [user example] ; key-id = AKIAIOSF0DNN7EXAMPLE ; secret-key = vrwAGfda90v/FDASFEO4/498qADFAeefEXAMPLE ; ; After doing so, you can add a "user" option to a "region" section, which ; causes the region to connect as a specific user by default: ; ; [region localhost] ; user = example euca2ools-3.3.1/euca2ools/000077500000000000000000000000001267461563000153205ustar00rootroot00000000000000euca2ools-3.3.1/euca2ools/__init__.py000066400000000000000000000042261267461563000174350ustar00rootroot00000000000000# Copyright (c) 2009-2016 Hewlett Packard Enterprise Development LP # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os.path import subprocess __version__ = '3.3-devel' BUFSIZE = 16 * 1024 if '__file__' in globals(): # Check if this is a git repo; maybe we can get more precise version info try: REPO_PATH = os.path.join(os.path.dirname(__file__), '..') # noinspection PyUnresolvedReferences GIT = subprocess.Popen( ['git', 'describe'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, env={'GIT_DIR': os.path.join(REPO_PATH, '.git')}) GIT.wait() GIT.stderr.read() if GIT.returncode == 0: __version__ = GIT.stdout.read().strip().lstrip('v') if type(__version__).__name__ == 'bytes': __version__ = __version__.decode() except: # Not really a bad thing; we'll just use what we had pass euca2ools-3.3.1/euca2ools/bundle/000077500000000000000000000000001267461563000165715ustar00rootroot00000000000000euca2ools-3.3.1/euca2ools/bundle/__init__.py000066400000000000000000000033631267461563000207070ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. class BundlePart(object): def __init__(self, filename, hexdigest, digest_algorithm, size=None): self.digest_algorithm = digest_algorithm self.filename = filename self.hexdigest = hexdigest self.size = size def __repr__(self): return 'BundlePart({0}, {1}, {2}, {3})'.format( repr(self.filename), repr(self.hexdigest), repr(self.digest_algorithm), repr(self.size)) euca2ools-3.3.1/euca2ools/bundle/manifest.py000066400000000000000000000324321267461563000207550ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import binascii import hashlib import logging import os.path import subprocess import lxml.etree import lxml.objectify import euca2ools.bundle class BundleManifest(object): def __init__(self, loglevel=None): self.log = logging.getLogger(self.__class__.__name__) if loglevel is not None: self.log.level = loglevel self.image_arch = None self.kernel_id = None self.ramdisk_id = None self.block_device_mappings = {} # virtual -> device self.product_codes = [] self.image_name = None self.account_id = None self.image_type = None self.image_digest = None self.image_digest_algorithm = None self.image_size = None self.bundled_image_size = None self.enc_key = None self.enc_iv = None self.enc_algorithm = None self.image_parts = [] @classmethod def read_from_file(cls, manifest_filename, privkey_filename=None): with open(manifest_filename) as manifest_fileobj: return cls.read_from_fileobj(manifest_fileobj, privkey_filename) @classmethod def read_from_fileobj(cls, manifest_fileobj, privkey_filename=None): xml = lxml.objectify.parse(manifest_fileobj).getroot() manifest = cls() mconfig = xml.machine_configuration manifest.image_arch = mconfig.architecture.text.strip() if hasattr(mconfig, 'kernel_id'): manifest.kernel_id = mconfig.kernel_id.text.strip() if hasattr(mconfig, 'ramdisk_id'): manifest.ramdisk_id = mconfig.ramdisk_id.text.strip() if hasattr(mconfig, 'block_device_mappings'): for xml_mapping in mconfig.block_device_mappings.iter( tag='block_device_mapping'): device = xml_mapping.device.text.strip() virtual = xml_mapping.virtual.text.strip() manifest.block_device_mappings[virtual] = device if hasattr(mconfig, 'productcodes'): for xml_pcode in mconfig.productcodes.iter(tag='product_code'): manifest.product_codes.append(xml_pcode.text.strip()) manifest.image_name = xml.image.name.text.strip() manifest.account_id = xml.image.user.text.strip() manifest.image_type = xml.image.type.text.strip() manifest.image_digest = xml.image.digest.text.strip() manifest.image_digest_algorithm = xml.image.digest.get('algorithm') manifest.image_size = int(xml.image.size.text.strip()) manifest.bundled_image_size = int(xml.image.bundled_size.text.strip()) if privkey_filename is not None: try: manifest.enc_key = _decrypt_hex( xml.image.user_encrypted_key.text.strip(), privkey_filename) except (AttributeError, ValueError): manifest.enc_key = _decrypt_hex( xml.image.ec2_encrypted_key.text.strip(), privkey_filename) manifest.enc_algorithm = xml.image.user_encrypted_key.get( 'algorithm') try: manifest.enc_iv = _decrypt_hex( xml.image.user_encrypted_iv.text.strip(), privkey_filename) except (AttributeError, ValueError): manifest.enc_iv = _decrypt_hex( xml.image.ec2_encrypted_iv.text.strip(), privkey_filename) manifest.image_parts = [None] * int(xml.image.parts.get('count')) for xml_part in xml.image.parts.iter(tag='part'): index = int(xml_part.get('index')) manifest.image_parts[index] = euca2ools.bundle.BundlePart( xml_part.filename.text.strip(), xml_part.digest.text.strip(), xml_part.digest.get('algorithm')) for index, part in enumerate(manifest.image_parts): if part is None: raise ValueError('part {0} must not be None'.format(index)) return manifest def dump_to_str(self, privkey_filename, user_cert_filename, ec2_cert_filename, pretty_print=False): if self.enc_key is None: raise ValueError('enc_key must not be None') if self.enc_iv is None: raise ValueError('enc_iv must not be None') ec2_fp = euca2ools.bundle.util.get_cert_fingerprint(ec2_cert_filename) self.log.info('creating manifest for EC2 service with fingerprint %s', ec2_fp) self.log.debug('EC2 certificate: %s', ec2_cert_filename) self.log.debug('user certificate: %s', user_cert_filename) self.log.debug('user private key: %s', privkey_filename) xml = lxml.objectify.Element('manifest') # Manifest version xml.version = '2007-10-10' # Our version xml.bundler = None xml.bundler.name = 'euca2ools' xml.bundler.version = euca2ools.__version__ xml.bundler.release = 0 # Target hardware xml.machine_configuration = None mconfig = xml.machine_configuration assert self.image_arch is not None mconfig.architecture = self.image_arch if self.image_type == 'machine': if self.block_device_mappings: mconfig.block_device_mapping = None for virtual, device in sorted( self.block_device_mappings.items()): xml_mapping = lxml.objectify.Element('mapping') xml_mapping.virtual = virtual xml_mapping.device = device mconfig.block_device_mapping.append(xml_mapping) if self.product_codes: mconfig.product_codes = None for code in self.product_codes: xml_code = lxml.objectify.Element('product_code') mconfig.product_codes.append(xml_code) mconfig.product_codes.product_code[-1] = code # kernel_id and ramdisk_id are normally meaningful only for machine # images, but eucalyptus also uses them to indicate kernel and ramdisk # images using the magic string "true", so their presence cannot be # made contingent on whether the image is a machine image or not. Be # careful not to create invalid kernel or ramdisk manifests because of # this. if self.kernel_id: mconfig.kernel_id = self.kernel_id if self.ramdisk_id: mconfig.ramdisk_id = self.ramdisk_id # Image info xml.image = None assert self.image_name is not None xml.image.name = self.image_name assert self.account_id is not None xml.image.user = self.account_id # xml.image.type must appear immediately after xml.image.user # for EC2 compatibility. assert self.image_type is not None xml.image.type = self.image_type assert self.image_digest is not None xml.image.digest = self.image_digest assert self.image_digest_algorithm is not None xml.image.digest.set('algorithm', self.image_digest_algorithm) assert self.image_size is not None xml.image.size = self.image_size assert self.bundled_image_size is not None xml.image.bundled_size = self.bundled_image_size # Bundle encryption keys (these are cloud-specific) assert self.enc_key is not None assert self.enc_iv is not None assert self.enc_algorithm is not None xml.image.ec2_encrypted_key = _public_encrypt(self.enc_key, ec2_cert_filename) xml.image.ec2_encrypted_key.set('algorithm', self.enc_algorithm) if user_cert_filename: xml.image.user_encrypted_key = _public_encrypt(self.enc_key, user_cert_filename) else: # Absence results in 400 (InvalidManifest) xml.image.user_encrypted_key = None xml.image.user_encrypted_key.set('algorithm', self.enc_algorithm) xml.image.ec2_encrypted_iv = _public_encrypt(self.enc_iv, ec2_cert_filename) if user_cert_filename: xml.image.user_encrypted_iv = _public_encrypt(self.enc_iv, user_cert_filename) else: # Absence results in 400 (InvalidManifest) xml.image.user_encrypted_iv = None # Bundle parts xml.image.parts = None xml.image.parts.set('count', str(len(self.image_parts))) for index, part in enumerate(self.image_parts): if part is None: raise ValueError('part {0} must not be None'.format(index)) part_elem = lxml.objectify.Element('part') part_elem.set('index', str(index)) part_elem.filename = os.path.basename(part.filename) part_elem.digest = part.hexdigest part_elem.digest.set('algorithm', part.digest_algorithm) # part_elem.append(lxml.etree.Comment( # ' size: {0} '.format(part.size))) xml.image.parts.append(part_elem) # Cleanup for signature lxml.objectify.deannotate(xml, xsi_nil=True) lxml.etree.cleanup_namespaces(xml) if privkey_filename: to_sign = (lxml.etree.tostring(xml.machine_configuration) + lxml.etree.tostring(xml.image)) signature = _rsa_sha1_sign(to_sign, privkey_filename) else: # Absence yields 400 (InvalidManifest) # Empty contents yield 500 (InternalError) signature = 'UNSIGNED' xml.signature = signature self.log.debug('hex-encoded signature: %s', signature) lxml.objectify.deannotate(xml, xsi_nil=True) lxml.etree.cleanup_namespaces(xml) self.log.debug('-- manifest content --\n', extra={'append': True}) pretty_manifest = lxml.etree.tostring(xml, pretty_print=True).strip() self.log.debug('%s', pretty_manifest, extra={'append': True}) self.log.debug('-- end of manifest content --') return lxml.etree.tostring(xml, xml_declaration=True, pretty_print=pretty_print).strip() def dump_to_file(self, manifest_file, privkey_filename, user_cert_filename, ec2_cert_filename, pretty_print=False): manifest_file.write(self.dump_to_str( privkey_filename, user_cert_filename, ec2_cert_filename, pretty_print=pretty_print)) def _decrypt_hex(hex_encrypted_key, privkey_filename): popen = subprocess.Popen(['openssl', 'rsautl', '-decrypt', '-pkcs', '-inkey', privkey_filename], stdin=subprocess.PIPE, stdout=subprocess.PIPE) binary_encrypted_key = binascii.unhexlify(hex_encrypted_key) (decrypted_key, _) = popen.communicate(binary_encrypted_key) try: # Make sure it might actually be an encryption key. # This isn't perfect, but it's still better than nothing. int(decrypted_key, 16) return decrypted_key except ValueError: pass raise ValueError("Failed to decrypt the bundle's encryption key. " "Ensure the key supplied matches the one used for " "bundling.") def _public_encrypt(content, cert_filename): popen = subprocess.Popen(['openssl', 'rsautl', '-encrypt', '-pkcs', '-inkey', cert_filename, '-certin'], stdin=subprocess.PIPE, stdout=subprocess.PIPE) (stdout, _) = popen.communicate(content) return binascii.hexlify(stdout) def _rsa_sha1_sign(content, privkey_filename): digest = hashlib.sha1() digest.update(content) popen = subprocess.Popen(['openssl', 'pkeyutl', '-sign', '-inkey', privkey_filename, '-pkeyopt', 'digest:sha1'], stdin=subprocess.PIPE, stdout=subprocess.PIPE) (stdout, _) = popen.communicate(digest.digest()) return binascii.hexlify(stdout) euca2ools-3.3.1/euca2ools/bundle/pipes/000077500000000000000000000000001267461563000177115ustar00rootroot00000000000000euca2ools-3.3.1/euca2ools/bundle/pipes/__init__.py000066400000000000000000000025021267461563000220210ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. euca2ools-3.3.1/euca2ools/bundle/pipes/core.py000066400000000000000000000216161267461563000212210ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import hashlib import multiprocessing import shutil import subprocess import tarfile import euca2ools.bundle.util from euca2ools.bundle.util import close_all_fds def create_bundle_pipeline(infile, outfile, enc_key, enc_iv, tarinfo, debug=False): pids = [] # infile -> tar tar_out_r, tar_out_w = euca2ools.bundle.util.open_pipe_fileobjs() tar_p = multiprocessing.Process(target=_create_tarball_from_stream, args=(infile, tar_out_w, tarinfo), kwargs={'debug': debug}) tar_p.start() pids.append(tar_p.pid) infile.close() tar_out_w.close() # tar -> sha1sum digest_out_r, digest_out_w = euca2ools.bundle.util.open_pipe_fileobjs() digest_result_r, digest_result_w = multiprocessing.Pipe(duplex=False) digest_p = multiprocessing.Process( target=_calc_sha1_for_pipe, kwargs={'debug': debug}, args=(tar_out_r, digest_out_w, digest_result_w)) digest_p.start() pids.append(digest_p.pid) tar_out_r.close() digest_out_w.close() digest_result_w.close() # sha1sum -> gzip try: gzip = subprocess.Popen(['pigz', '-c'], stdin=digest_out_r, stdout=subprocess.PIPE, close_fds=True, bufsize=-1) except OSError: gzip = subprocess.Popen(['gzip', '-c'], stdin=digest_out_r, stdout=subprocess.PIPE, close_fds=True, bufsize=-1) digest_out_r.close() pids.append(gzip.pid) # gzip -> openssl openssl = subprocess.Popen(['openssl', 'enc', '-e', '-aes-128-cbc', '-K', enc_key, '-iv', enc_iv], stdin=gzip.stdout, stdout=outfile, close_fds=True, bufsize=-1) gzip.stdout.close() pids.append(openssl.pid) # Make sure something calls wait() on every child process for pid in pids: euca2ools.bundle.util.waitpid_in_thread(pid) # Return the connection the caller can use to obtain the final digest return digest_result_r def create_unbundle_pipeline(infile, outfile, enc_key, enc_iv, debug=False): """ Create a pipeline to perform the unbundle operation on infile input. The resulting unbundled image will be written to 'outfile'. :param outfile: file obj to write unbundled image to :param enc_key: the encryption key used to bundle the image :param enc_iv: the encyrption initialization vector used in the bundle :returns multiprocess pipe to read sha1 digest of written image """ pids = [] # infile -> openssl openssl = subprocess.Popen(['openssl', 'enc', '-d', '-aes-128-cbc', '-K', enc_key, '-iv', enc_iv], stdin=infile, stdout=subprocess.PIPE, close_fds=True, bufsize=-1) pids.append(openssl.pid) infile.close() # openssl -> gzip try: gzip = subprocess.Popen(['pigz', '-c', '-d'], stdin=openssl.stdout, stdout=subprocess.PIPE, close_fds=True, bufsize=-1) except OSError: gzip = subprocess.Popen(['gzip', '-c', '-d'], stdin=openssl.stdout, stdout=subprocess.PIPE, close_fds=True, bufsize=-1) pids.append(gzip.pid) openssl.stdout.close() # gzip -> sha1sum digest_out_r, digest_out_w = euca2ools.bundle.util.open_pipe_fileobjs() digest_result_r, digest_result_w = multiprocessing.Pipe(duplex=False) digest_p = multiprocessing.Process( target=_calc_sha1_for_pipe, kwargs={'debug': debug}, args=(gzip.stdout, digest_out_w, digest_result_w)) digest_p.start() pids.append(digest_p.pid) gzip.stdout.close() digest_out_w.close() digest_result_w.close() # sha1sum -> tar tar_p = multiprocessing.Process( target=_extract_from_tarball_stream, args=(digest_out_r, outfile), kwargs={'debug': debug}) tar_p.start() digest_out_r.close() pids.append(tar_p.pid) # Make sure something calls wait() on every child process for pid in pids: euca2ools.bundle.util.waitpid_in_thread(pid) # Return the connection the caller can use to obtain the final digest return digest_result_r def copy_with_progressbar(infile, outfile, progressbar=None): """ Synchronously copy data from infile to outfile, updating a progress bar with the total number of bytes copied along the way if one was provided, and return the number of bytes copied. This method must be run on the main thread. :param infile: file obj to read input from :param outfile: file obj to write output to :param progressbar: progressbar object to update with i/o information :param maxbytes: Int maximum number of bytes to write """ bytes_written = 0 if progressbar: progressbar.start() try: while not infile.closed: chunk = infile.read(euca2ools.BUFSIZE) if chunk: outfile.write(chunk) outfile.flush() bytes_written += len(chunk) if progressbar: progressbar.update(bytes_written) else: break finally: if progressbar: progressbar.finish() infile.close() return bytes_written def _calc_sha1_for_pipe(infile, outfile, digest_out_pipe_w, debug=False): """ Read data from infile and write it to outfile, calculating a running SHA1 digest along the way. When infile hits end-of-file, send the digest in hex form to result_mpconn and exit. :param infile: file obj providing input for digest :param outfile: file obj destination for writing output :param digest_out_pipe_w: fileobj to write digest to :param debug: boolean used in exception handling """ close_all_fds([infile, outfile, digest_out_pipe_w]) digest = hashlib.sha1() try: while True: chunk = infile.read(euca2ools.BUFSIZE) if chunk: digest.update(chunk) outfile.write(chunk) outfile.flush() else: break digest_out_pipe_w.send(digest.hexdigest()) except IOError: # HACK if not debug: return raise finally: infile.close() outfile.close() digest_out_pipe_w.close() def _create_tarball_from_stream(infile, outfile, tarinfo, debug=False): close_all_fds(except_fds=[infile, outfile]) tarball = tarfile.open(mode='w|', fileobj=outfile, bufsize=euca2ools.BUFSIZE) try: tarball.addfile(tarinfo, fileobj=infile) except IOError: # HACK if not debug: return raise finally: infile.close() tarball.close() outfile.close() def _extract_from_tarball_stream(infile, outfile, debug=False): """ Perform tar extract on infile and write to outfile :param infile: file obj providing input for tar :param outfile: file obj destination for tar output :param debug: boolean used in exception handling """ close_all_fds([infile, outfile]) tarball = tarfile.open(mode='r|', fileobj=infile) try: tarinfo = tarball.next() shutil.copyfileobj(tarball.extractfile(tarinfo), outfile) except IOError: # HACK if not debug: return raise finally: infile.close() tarball.close() outfile.close() euca2ools-3.3.1/euca2ools/bundle/pipes/fittings.py000066400000000000000000000144441267461563000221210ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import hashlib import itertools import multiprocessing import os import sys import euca2ools.bundle.pipes import euca2ools.bundle.util def create_bundle_part_deleter(in_mpconn, out_mpconn=None): del_p = multiprocessing.Process(target=_delete_part_files, args=(in_mpconn,), kwargs={'out_mpconn': out_mpconn}) del_p.start() euca2ools.bundle.util.waitpid_in_thread(del_p.pid) def create_bundle_part_writer(infile, part_prefix, part_size, part_write_sem=None, debug=False): partinfo_result_r, partinfo_result_w = multiprocessing.Pipe(duplex=False) writer_p = multiprocessing.Process( target=_write_parts, args=(infile, part_prefix, part_size, partinfo_result_w), kwargs={'part_write_sem': part_write_sem, 'debug': debug}) writer_p.start() partinfo_result_w.close() infile.close() euca2ools.bundle.util.waitpid_in_thread(writer_p.pid) return partinfo_result_r def create_mpconn_aggregator(in_mpconn, out_mpconn=None, debug=False): result_mpconn_r, result_mpconn_w = multiprocessing.Pipe(duplex=False) agg_p = multiprocessing.Process( target=_aggregate_mpconn_items, args=(in_mpconn, result_mpconn_w), kwargs={'out_mpconn': out_mpconn, 'debug': debug}) agg_p.start() result_mpconn_w.close() euca2ools.bundle.util.waitpid_in_thread(agg_p.pid) return result_mpconn_r def _delete_part_files(in_mpconn, out_mpconn=None): euca2ools.bundle.util.close_all_fds(except_fds=(in_mpconn, out_mpconn)) try: while True: part = in_mpconn.recv() os.unlink(part.filename) if out_mpconn is not None: out_mpconn.send(part) except EOFError: return finally: in_mpconn.close() if out_mpconn is not None: out_mpconn.close() def _aggregate_mpconn_items(in_mpconn, result_mpconn, out_mpconn=None, debug=False): euca2ools.bundle.util.close_all_fds( except_fds=(in_mpconn, out_mpconn, result_mpconn)) results = [] try: while True: next_result = in_mpconn.recv() results.append(next_result) if out_mpconn is not None: out_mpconn.send(next_result) except EOFError: try: result_mpconn.send(results) except IOError: # HACK if not debug: return raise except IOError: # HACK if not debug: return raise finally: result_mpconn.close() in_mpconn.close() if out_mpconn is not None: out_mpconn.close() def _write_parts(infile, part_prefix, part_size, partinfo_mpconn, part_write_sem=None, debug=False): except_fds = [infile, partinfo_mpconn] if part_write_sem is not None and sys.platform == 'darwin': # When I ran close_all_fds on OS X and excluded only the FDs # listed above, all attempts to use the semaphore resulted in # complaints about bad file descriptors. The following code # is a horrible hack that I stumbled upon while attempting # to figure out what FD number I needed to avoid closing to # preserve the semaphore. It is probably incorrect and reliant # on implementation details, so I am happy to take a patch that # manages to deal with this problem in a more reasonable way. try: except_fds.append(int(part_write_sem._semlock.handle)) except AttributeError: part_write_sem = None except ValueError: part_write_sem = None euca2ools.bundle.util.close_all_fds(except_fds=except_fds) for part_no in itertools.count(): if part_write_sem is not None: part_write_sem.acquire() part_fname = '{0}.part.{1:02}'.format(part_prefix, part_no) part_digest = hashlib.sha1() with open(part_fname, 'w') as part: bytes_written = 0 bytes_to_write = part_size while bytes_to_write > 0: try: chunk = infile.read(min(bytes_to_write, euca2ools.BUFSIZE)) except ValueError: # I/O error on closed file # HACK if not debug: partinfo_mpconn.close() return raise if chunk: part.write(chunk) part_digest.update(chunk) bytes_to_write -= len(chunk) bytes_written += len(chunk) else: break partinfo = euca2ools.bundle.BundlePart( part_fname, part_digest.hexdigest(), 'SHA1', bytes_written) partinfo_mpconn.send(partinfo) if bytes_written < part_size: # That's the last part infile.close() partinfo_mpconn.close() return euca2ools-3.3.1/euca2ools/bundle/util.py000066400000000000000000000062611267461563000201250ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os import subprocess import threading def close_all_fds(except_fds=None): except_filenos = [1, 2] if except_fds is not None: for except_fd in except_fds: if except_fd is None: pass elif isinstance(except_fd, int): except_filenos.append(except_fd) elif hasattr(except_fd, 'fileno'): except_filenos.append(except_fd.fileno()) else: raise ValueError('{0} must be an int or have a fileno method' .format(repr(except_fd))) fileno_ranges = [] next_range_min = 0 for except_fileno in sorted(except_filenos): if except_fileno > next_range_min: fileno_ranges.append((next_range_min, except_fileno)) next_range_min = max(next_range_min, except_fileno + 1) fileno_ranges.append((next_range_min, 1024)) for fileno_range in fileno_ranges: os.closerange(fileno_range[0], fileno_range[1]) def get_cert_fingerprint(cert_filename): openssl = subprocess.Popen(('openssl', 'x509', '-in', cert_filename, '-fingerprint', '-sha1', '-noout'), stdout=subprocess.PIPE) (fingerprint, _) = openssl.communicate() return fingerprint.strip().rsplit('=', 1)[-1].replace(':', '').lower() def open_pipe_fileobjs(): pipe_r, pipe_w = os.pipe() return os.fdopen(pipe_r), os.fdopen(pipe_w, 'w') def waitpid_in_thread(pid): """ Start a thread that calls os.waitpid on a particular PID to prevent zombie processes from hanging around after they have finished. """ pid_thread = threading.Thread(target=_wait_for_pid, args=(pid,)) pid_thread.daemon = True pid_thread.start() def _wait_for_pid(pid): if pid: try: os.waitpid(pid, 0) except OSError: pass euca2ools-3.3.1/euca2ools/commands/000077500000000000000000000000001267461563000171215ustar00rootroot00000000000000euca2ools-3.3.1/euca2ools/commands/__init__.py000066400000000000000000000110141267461563000212270ustar00rootroot00000000000000# Copyright (c) 2009-2016 Hewlett Packard Enterprise Development LP # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import glob import os.path import platform import sys import requestbuilder import requests from euca2ools import __version__ DATADIR = '/usr/share/euca2ools' SYSCONFDIR = '/etc/euca2ools' USERCONFDIR = '~/.euca' class Euca2ools(object): """ A class with attributes and methods that define the entire euca2ools suite """ CONFIG_PATHS = (os.path.join(SYSCONFDIR, 'euca2ools.ini'), os.path.join(SYSCONFDIR, 'conf.d', '*.ini'), os.path.join(USERCONFDIR, '*.ini')) def __init__(self): self.__user_agent = None # noinspection PyBroadException @staticmethod def format_version(): version_lines = ['euca2ools {0} (Yokohama)'.format(__version__)] try: if os.path.isfile('/etc/eucalyptus/eucalyptus-version'): with open('/etc/eucalyptus/eucalyptus-version') as ver_file: euca_version = ver_file.readline().strip() version_lines.append('eucalyptus {0}'.format(euca_version)) except: # Those were just more crunchy bits. If they don't work, oh well! pass return '\n'.join(version_lines) def list_config_files(self): config_files = [] if 'EUCA_CONFIG_PATH' in os.environ: config_globs = os.getenv('EUCA_CONFIG_PATH').split(':') else: config_globs = self.CONFIG_PATHS for config_glob in config_globs: expanded = os.path.expanduser(os.path.expandvars(config_glob)) config_files.extend(sorted(glob.glob(expanded))) return config_files def get_user_agent(self): if self.__user_agent is None: user_agent_bits = ['euca2ools/{0}'.format(__version__)] tokens = [] impl = platform.python_implementation() if impl == 'PyPy': # pylint: disable=E1101 impl_version = '{0}.{1}.{2}'.format( sys.pypy_version_info.major, sys.pypy_version_info.minor, sys.pypy_version_info.micro) if sys.pypy_version_info.releaselevel != 'final': impl_version += sys.pypy_version_info.releaselevel # pylint: enable=E1101 else: # I'm guessing for non-CPython implementations; feel free to # submit patches or the needed implementation-specific API # references. impl_version = platform.python_version() tokens.append('{0} {1}'.format(impl, impl_version)) plat = [] try: plat.append(platform.system()) plat.append(platform.release()) except IOError: pass if plat: tokens.append(' '.join(plat)) tokens.append(platform.machine()) user_agent_bits.append('({0})'.format('; '.join(tokens))) user_agent_bits.append('requestbuilder/{0}'.format( requestbuilder.__version__)) user_agent_bits.append('requests/{0}'.format(requests.__version__)) self.__user_agent = ' '.join(user_agent_bits) return self.__user_agent euca2ools-3.3.1/euca2ools/commands/argtypes.py000066400000000000000000000263301267461563000213350ustar00rootroot00000000000000# Copyright 2012-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse import base64 import sys from requestbuilder import EMPTY def manifest_block_device_mappings(mappings_as_str): mappings = {} mapping_strs = mappings_as_str.split(',') for mapping_str in mapping_strs: if mapping_str.strip(): bits = mapping_str.strip().split('=') if len(bits) == 2: mappings[bits[0].strip()] = bits[1].strip() else: raise argparse.ArgumentTypeError( "invalid device mapping '{0}' (must have format " "'VIRTUAL=DEVICE')".format(mapping_str)) return mappings def ec2_block_device_mapping(map_as_str): """ Parse a block device mapping from an image registration command line. """ try: (device, mapping) = map_as_str.split('=') except ValueError: raise argparse.ArgumentTypeError( 'block device mapping "{0}" must have form DEVICE=MAPPED' .format(map_as_str)) map_dict = {'DeviceName': device} if mapping.lower() == 'none': map_dict['NoDevice'] = 'true' elif mapping.startswith('ephemeral'): map_dict['VirtualName'] = mapping elif (mapping.startswith('snap-') or mapping.startswith('vol-') or mapping.startswith(':')): map_bits = mapping.split(':') while len(map_bits) < 5: map_bits.append(None) if len(map_bits) != 5: raise argparse.ArgumentTypeError( 'EBS block device mapping "{0}" must have form ' 'DEVICE=[SNAP-ID]:[GiB]:[true|false]:[standard|TYPE[:IOPS]]' .format(map_as_str)) map_dict['Ebs'] = {} if map_bits[0]: map_dict['Ebs']['SnapshotId'] = map_bits[0] if map_bits[1]: try: map_dict['Ebs']['VolumeSize'] = int(map_bits[1]) except ValueError: raise argparse.ArgumentTypeError( 'second element of EBS block device mapping "{0}" must be ' 'an integer'.format(map_as_str)) if map_bits[2]: if map_bits[2].lower() not in ('true', 'false'): raise argparse.ArgumentTypeError( 'third element of EBS block device mapping "{0}" must be ' '"true" or "false"'.format(map_as_str)) map_dict['Ebs']['DeleteOnTermination'] = map_bits[2].lower() if map_bits[3]: map_dict['Ebs']['VolumeType'] = map_bits[3] if map_bits[4]: if map_bits[3] == 'standard': raise argparse.ArgumentTypeError( 'fifth element of EBS block device mapping "{0}" is not ' 'allowed with volume type "standard"'.format(map_as_str)) map_dict['Ebs']['Iops'] = map_bits[4] if not map_dict['Ebs']: raise argparse.ArgumentTypeError( 'EBS block device mapping "{0}" must specify at least one ' 'element. Use "{1}=none" to suppress an existing mapping.' .format(map_as_str, device)) elif not mapping: raise argparse.ArgumentTypeError( 'invalid block device mapping "{0}". Use "{1}=none" to suppress ' 'an existing mapping.'.format(map_as_str, device)) else: raise argparse.ArgumentTypeError( 'invalid block device mapping "{0}"'.format(map_as_str)) return map_dict def flexible_bool(bool_str): if bool_str.strip().lower() in ('0', 'f', 'false', 'n', 'no'): return False if bool_str.strip().lower() in ('1', 't', 'true', 'y', 'yes'): return True raise argparse.ArgumentTypeError("'{0}' must be 'true' or 'false'" .format(bool_str)) def filesize(size): suffixes = 'kmgt' s_size = size.lower().rstrip('b') if len(s_size) > 0 and s_size[-1] in suffixes: multiplier = 1024 ** (suffixes.find(s_size[-1]) + 1) s_size = s_size[:-1] else: multiplier = 1 return multiplier * int(s_size) def vpc_interface(iface_as_str): """ Nine-part VPC network interface definition: [INTERFACE]:INDEX:[SUBNET]:[DESCRIPTION]:[PRIV_IP]:[GROUP1,GROUP2,...]: [true|false]:[SEC_IP_COUNT|:SEC_IP1,SEC_IP2,...] """ if len(iface_as_str) == 0: raise argparse.ArgumentTypeError( 'network interface definitions must be non-empty'.format( iface_as_str)) bits = iface_as_str.split(':') iface = {} if len(bits) < 2: raise argparse.ArgumentTypeError( 'network interface definition "{0}" must consist of at least 2 ' 'elements ({1} provided)'.format(iface_as_str, len(bits))) elif len(bits) > 9: raise argparse.ArgumentTypeError( 'network interface definition "{0}" must consist of at most 9 ' 'elements ({1} provided)'.format(iface_as_str, len(bits))) while len(bits) < 9: bits.append(None) if bits[0]: # Preexisting NetworkInterfaceId if bits[0].startswith('eni-') and len(bits[0]) == 12: iface['NetworkInterfaceId'] = bits[0] else: raise argparse.ArgumentTypeError( 'first element of network interface definition "{0}" must be ' 'a network interface ID'.format(iface_as_str)) if bits[1]: # DeviceIndex try: iface['DeviceIndex'] = int(bits[1]) except ValueError: raise argparse.ArgumentTypeError( 'second element of network interface definition "{0}" must be ' 'an integer'.format(iface_as_str)) else: raise argparse.ArgumentTypeError( 'second element of network interface definition "{0}" must be ' 'non-empty'.format(iface_as_str)) if bits[2]: # SubnetId if bits[2].startswith('subnet-'): iface['SubnetId'] = bits[2] else: raise argparse.ArgumentTypeError( 'third element of network interface definition "{0}" must be ' 'a subnet ID'.format(iface_as_str)) if bits[3]: # Description iface['Description'] = bits[3] if bits[4]: # PrivateIpAddresses.n.PrivateIpAddress # PrivateIpAddresses.n.Primary iface.setdefault('PrivateIpAddresses', []) iface['PrivateIpAddresses'].append({'PrivateIpAddress': bits[4], 'Primary': 'true'}) if bits[5]: # SecurityGroupId.n groups = [bit for bit in bits[5].split(',') if bit] if not all(group.startswith('sg-') for group in groups): raise argparse.ArgumentTypeError( 'sixth element of network interface definition "{0}" must ' 'refer to security groups by IDs, not names' .format(iface_as_str)) iface['SecurityGroupId'] = groups if bits[6]: # DeleteOnTermination if bits[6] in ('true', 'false'): iface['DeleteOnTermination'] = bits[6] else: raise argparse.ArgumentTypeError( 'seventh element of network interface definition "{0}" ' 'must be "true" or "false"'.format(iface_as_str)) if bits[7]: # SecondaryPrivateIpAddressCount if bits[8]: raise argparse.ArgumentTypeError( 'eighth and ninth elements of network interface definition ' '"{0}" must not both be non-empty'.format(iface_as_str)) try: iface['SecondaryPrivateIpAddressCount'] = int(bits[7]) except ValueError: raise argparse.ArgumentTypeError( 'eighth element of network interface definition "{0}" must be ' 'an integer'.format(iface_as_str)) if bits[8]: # PrivateIpAddresses.n.PrivateIpAddress sec_ips = [{'PrivateIpAddress': addr} for addr in bits[8].split(',') if addr] iface.setdefault('PrivateIpAddresses', []) iface['PrivateIpAddresses'].extend(sec_ips) return iface def file_contents(filename): if filename == '-': return sys.stdin.read() else: with open(filename) as arg_file: return arg_file.read() def b64encoded_file_contents(filename): if filename == '-': return base64.b64encode(sys.stdin.read()) else: with open(filename) as arg_file: return base64.b64encode(arg_file.read()) def binary_tag_def(tag_str): """ Parse a tag definition from the command line. Return a dict that depends on the format of the string given: - 'key=value': {'Key': key, 'Value': value} - 'key=': {'Key': key, 'Value': EMPTY} - 'key': {'Key': key, 'Value': EMPTY} """ if not tag_str: raise ValueError('tag must be non-empty') elif '=' in tag_str: (key, val) = tag_str.split('=', 1) if not key: raise ValueError('tag "{0}" must include a key'.format(tag_str)) return {'Key': key, 'Value': val or EMPTY} else: return {'Key': tag_str, 'Value': EMPTY} def ternary_tag_def(tag_str): """ Parse a tag definition from the command line. Return a dict that depends on the format of the string given: - 'key=value': {'Key': key, 'Value': value} - 'key=': {'Key': key, 'Value': EMPTY} - 'key': {'Key': key} """ if '=' in tag_str: (key, val) = tag_str.split('=', 1) return {'Key': key, 'Value': val or EMPTY} else: return {'Key': tag_str} def delimited_list(delimiter, item_type=str): def _delimited_list(list_as_str): if isinstance(list_as_str, str) and len(list_as_str) > 0: return [item_type(item.strip()) for item in list_as_str.split(delimiter) if len(item.strip()) > 0] else: return [] # Improve the output of argparse's TypeError/ValueError handling _delimited_list.__name__ = '{0} list'.format(item_type.__name__) return _delimited_list euca2ools-3.3.1/euca2ools/commands/autoscaling/000077500000000000000000000000001267461563000214325ustar00rootroot00000000000000euca2ools-3.3.1/euca2ools/commands/autoscaling/__init__.py000066400000000000000000000050261267461563000235460ustar00rootroot00000000000000# Copyright 2013-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os import sys from requestbuilder import Arg import requestbuilder.auth.aws import requestbuilder.service import requestbuilder.request from euca2ools.commands import Euca2ools from euca2ools.exceptions import AWSError from euca2ools.util import strip_response_metadata, add_fake_region_name class AutoScaling(requestbuilder.service.BaseService): NAME = 'autoscaling' DESCRIPTION = 'Auto-scaling service' API_VERSION = '2011-01-01' REGION_ENVVAR = 'AWS_DEFAULT_REGION' URL_ENVVAR = 'AWS_AUTO_SCALING_URL' ARGS = [Arg('-U', '--url', metavar='URL', help='auto-scaling service endpoint URL')] def configure(self): requestbuilder.service.BaseService.configure(self) add_fake_region_name(self) def handle_http_error(self, response): raise AWSError(response) class AutoScalingRequest(requestbuilder.request.AWSQueryRequest): SUITE = Euca2ools SERVICE_CLASS = AutoScaling AUTH_CLASS = requestbuilder.auth.aws.HmacV4Auth METHOD = 'POST' def parse_response(self, response): response_dict = requestbuilder.request.AWSQueryRequest.parse_response( self, response) return strip_response_metadata(response_dict) euca2ools-3.3.1/euca2ools/commands/autoscaling/arghelpers.py000066400000000000000000000045221267461563000241430ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.autoscaling.argtypes import autoscaling_tag_def from requestbuilder import Arg class TagArg(Arg): def __init__(self, required=False): helpstr = '''attributes of a tag to affect. Tags follow the following format: "id=resource-name, t=resource-type, k=tag-key, v=tag-val, p=propagate-at-launch-flag", where k is the tag's name, v is the tag's value, id is a resource ID, t is a resource type, and p is whether to propagate tags to instances created by the group. A value for 'k=' is required for each tag. The rest are optional. This argument may be used more than once. Each time affects a different tag.''' if required: helpstr += ' (at least 1 required)' Arg.__init__(self, '--tag', dest='Tags.member', required=required, action='append', type=autoscaling_tag_def, help=helpstr, metavar=('"k=VALUE, id=VALUE, t=VALUE, v=VALUE, ' 'p={true,false}"')) euca2ools-3.3.1/euca2ools/commands/autoscaling/argtypes.py000066400000000000000000000061411267461563000236440ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from argparse import ArgumentTypeError def autoscaling_filter_def(filter_str): filter_dict = {} pieces = filter_str.split(',') for piece in pieces: piece = piece.strip() if '=' not in piece: raise ArgumentTypeError( "invalid filter: each segment of '{0}' must have format " "KEY=VALUE".format(piece)) key, val = piece.split('=', 1) filter_dict.setdefault(key.strip(), []) filter_dict[key.strip()].append(val.strip()) filter_list = [] for key, values in filter_dict.iteritems(): filter_list.append({'Name': key, 'Values': values}) return filter_list def autoscaling_tag_def(tag_str): tag_dict = {} pieces = tag_str.split(',') for piece in pieces: piece = piece.strip() if '=' not in piece: raise ArgumentTypeError( "invalid tag definition: each segment of '{0}' must have " "format KEY=VALUE".format(piece)) key, val = piece.split('=', 1) if key == 'k': tag_dict['Key'] = val elif key == 'id': tag_dict['ResourceId'] = val elif key == 't': tag_dict['ResourceType'] = val elif key == 'v': tag_dict['Value'] = val elif key == 'p': if val.lower() in ('true', 'false'): tag_dict['PropagateAtLaunch'] = val.lower() else: raise ArgumentTypeError( "value for to 'p=' must be 'true' or 'false'") else: raise ArgumentTypeError( "unrecognized tag segment '{0}'".format(piece)) if not tag_dict.get('Key'): raise ArgumentTypeError( "tag '{0}' must contain a 'k=' segment with a non-empty value") return tag_dict euca2ools-3.3.1/euca2ools/commands/autoscaling/createautoscalinggroup.py000066400000000000000000000105711267461563000265620ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.argtypes import delimited_list from euca2ools.commands.autoscaling import AutoScalingRequest from euca2ools.commands.autoscaling.arghelpers import TagArg from requestbuilder import Arg class CreateAutoScalingGroup(AutoScalingRequest): DESCRIPTION = 'Create a new auto-scaling group' ARGS = [Arg('AutoScalingGroupName', metavar='ASGROUP', help='name of the new auto-scaling group (required)'), Arg('-l', '--launch-configuration', dest='LaunchConfigurationName', metavar='LAUNCHCONFIG', required=True, help='''name of the launch configuration to use with the new group (required)'''), Arg('-M', '--max-size', dest='MaxSize', metavar='COUNT', type=int, required=True, help='maximum group size (required)'), Arg('-m', '--min-size', dest='MinSize', metavar='COUNT', type=int, required=True, help='minimum group size (required)'), Arg('--default-cooldown', dest='DefaultCooldown', metavar='SECONDS', type=int, help='''amount of time, in seconds, after a scaling activity completes before any further trigger-related scaling activities may start'''), Arg('--desired-capacity', dest='DesiredCapacity', metavar='COUNT', type=int, help='number of running instances the group should contain'), Arg('--grace-period', dest='HealthCheckGracePeriod', metavar='SECONDS', type=int, help='''number of seconds to wait before starting health checks on newly-created instances'''), Arg('--health-check-type', dest='HealthCheckType', choices=('EC2', 'ELB'), help='service to obtain health check status from'), Arg('--load-balancers', dest='LoadBalancerNames.member', metavar='ELB1,ELB2,...', type=delimited_list(','), help='comma-separated list of load balancers to use'), Arg('--placement-group', dest='PlacementGroup', help='placement group in which to launch new instances'), TagArg(required=False), Arg('--termination-policies', dest='TerminationPolicies.member', metavar='POLICY1,POLICY2,...', type=delimited_list(','), help='''ordered list of termination policies. The first has the highest precedence.'''), Arg('--vpc-zone-identifier', dest='VPCZoneIdentifier', metavar='ZONE1,ZONE2,...', help='''comma-separated list of subnet identifiers. If you specify availability zones as well, ensure the subnets' availability zones match the ones you specified'''), Arg('-z', '--availability-zones', dest='AvailabilityZones.member', metavar='ZONE1,ZONE2,...', type=delimited_list(','), help='''comma-separated list of availability zones for the new group (required unless subnets are supplied)''')] euca2ools-3.3.1/euca2ools/commands/autoscaling/createlaunchconfiguration.py000066400000000000000000000142071267461563000272360ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import base64 import os.path from requestbuilder import Arg, MutuallyExclusiveArgList from requestbuilder.exceptions import ArgumentError from euca2ools.commands.argtypes import (delimited_list, ec2_block_device_mapping, flexible_bool) from euca2ools.commands.autoscaling import AutoScalingRequest class CreateLaunchConfiguration(AutoScalingRequest): DESCRIPTION = 'Create a new auto-scaling instance launch configuration' ARGS = [Arg('LaunchConfigurationName', metavar='LAUNCHCONFIG', help='name of the new launch configuration (required)'), Arg('-i', '--image-id', dest='ImageId', metavar='IMAGE', required=True, help='machine image to use for instances (required)'), Arg('-t', '--instance-type', dest='InstanceType', metavar='TYPE', required=True, help='instance type for use for instances (required)'), Arg('--associate-public-ip-address', dest='AssociatePublicIpAddress', type=flexible_bool, metavar='{true,false}', help='''[VPC only] whether to assign instances public IP addresses'''), Arg('--block-device-mapping', dest='BlockDeviceMappings.member', metavar='DEVICE1=MAPPED1,DEVICE2=MAPPED2,...', type=delimited_list(',', item_type=ec2_block_device_mapping), help='''a comma-separated list of block device mappings for the image, in the form DEVICE=MAPPED, where "MAPPED" is "none", "ephemeral(0-3)", or "[SNAP-ID]:[GiB]:[true|false]'''), Arg('--ebs-optimized', dest='EbsOptimized', action='store_const', const='true', help='whether the instance is optimized for EBS I/O'), Arg('--group', dest='SecurityGroups.member', metavar='GROUP1,GROUP2,...', type=delimited_list(','), help='''a comma-separated list of security groups with which to associate instances. Either all group names or all group IDs are allowed, but not both.'''), Arg('--iam-instance-profile', dest='IamInstanceProfile', metavar='PROFILE', help='''ARN of the instance profile associated with instances' IAM roles'''), Arg('--kernel', dest='KernelId', metavar='KERNEL', help='kernel image to use for instances'), Arg('--key', dest='KeyName', metavar='KEYPAIR', help='name of the key pair to use for instances'), Arg('--monitoring-enabled', dest='InstanceMonitoring.Enabled', action='store_const', const='true', help='enable detailed monitoring (enabled by default)'), Arg('--monitoring-disabled', dest='InstanceMonitoring.Enabled', action='store_const', const='false', help='disable detailed monitoring (enabled by default)'), Arg('--ramdisk', dest='RamdiskId', metavar='RAMDISK', help='ramdisk image to use for instances'), Arg('--spot-price', dest='SpotPrice', metavar='PRICE', help='maximum hourly price for any spot instances launched'), MutuallyExclusiveArgList( Arg('-d', '--user-data', metavar='DATA', route_to=None, help='user data to make available to instances'), Arg('--user-data-force', metavar='DATA', route_to=None, help='''same as -d/--user-data, but without checking if a file by that name exists first'''), Arg('-f', '--user-data-file', metavar='FILE', route_to=None, help='''file containing user data to make available to instances'''))] # noinspection PyExceptionInherit def configure(self): AutoScalingRequest.configure(self) if self.args.get('user_data'): if os.path.isfile(self.args['user_data']): raise ArgumentError( 'argument -d/--user-data: to pass the contents of a file ' 'as user data, use -f/--user-data-file. To pass the ' "literal value '{0}' as user data even though it matches " 'the name of a file, use --user-data-force.') else: self.params['UserData'] = base64.b64encode( self.args['user_data']) elif self.args.get('user_data_force'): self.params['UserData'] = base64.b64encode( self.args['user_data_force']) elif self.args.get('user_data_file'): with open(self.args['user_data_file']) as user_data_file: self.params['UserData'] = base64.b64encode( user_data_file.read()) euca2ools-3.3.1/euca2ools/commands/autoscaling/createorupdatetags.py000066400000000000000000000031131267461563000256700ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.autoscaling import AutoScalingRequest from euca2ools.commands.autoscaling.arghelpers import TagArg class CreateOrUpdateTags(AutoScalingRequest): DESCRIPTION = 'Create or update one or more resource tags' ARGS = [TagArg(required=True)] euca2ools-3.3.1/euca2ools/commands/autoscaling/deleteautoscalinggroup.py000066400000000000000000000040211267461563000265520ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder import Arg class DeleteAutoScalingGroup(AutoScalingRequest): DESCRIPTION = 'Delete an auto-scaling group' ARGS = [Arg('AutoScalingGroupName', metavar='ASGROUP', help='name of the auto-scaling group to delete (required)'), Arg('-d', '--force-delete', dest='ForceDelete', action='store_const', const='true', help='''delete the group and all of its instances without waiting for all instances to terminate'''), Arg('-f', '--force', action='store_true', route_to=None, help=argparse.SUPPRESS)] # for compatibility euca2ools-3.3.1/euca2ools/commands/autoscaling/deletelaunchconfiguration.py000066400000000000000000000035001267461563000272270ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder import Arg class DeleteLaunchConfiguration(AutoScalingRequest): DESCRIPTION = 'Delete an auto-scaling instance launch configuration' ARGS = [Arg('LaunchConfigurationName', metavar='LAUNCHCONFIG', help='name of the launch configuration to delete (required)'), Arg('-f', '--force', action='store_true', route_to=None, help=argparse.SUPPRESS)] # For compatibility euca2ools-3.3.1/euca2ools/commands/autoscaling/deletenotificationconfiguration.py000066400000000000000000000040051267461563000304440ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder import Arg class DeleteNotificationConfiguration(AutoScalingRequest): DESCRIPTION = "Delete an auto-scaling group's notification configuration" ARGS = [Arg('AutoScalingGroupName', metavar='ASGROUP', help='name of the auto-scaling group to update (required)'), Arg('-t', '--topic-arn', dest='TopicARN', metavar='TOPIC', required=True, help='''ARN of the SNS topic associated with the configuration to delete'''), Arg('-f', '--force', route_to=None, action='store_true', help=argparse.SUPPRESS)] # for compatibility euca2ools-3.3.1/euca2ools/commands/autoscaling/deletepolicy.py000066400000000000000000000037471267461563000245010ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder import Arg class DeletePolicy(AutoScalingRequest): DESCRIPTION = 'Delete a scaling policy' ARGS = [Arg('PolicyName', metavar='POLICY', help='name of the policy to delete (required)'), Arg('-g', '--auto-scaling-group', dest='AutoScalingGroupName', metavar='ASGROUP', required=True, help='''name of the auto-scaling group the policy is associated with (required)'''), Arg('-f', '--force', route_to=None, action='store_true', help=argparse.SUPPRESS)] # for compatibility euca2ools-3.3.1/euca2ools/commands/autoscaling/deletescheduledaction.py000066400000000000000000000040171267461563000263270ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder import Arg class DeleteScheduledAction(AutoScalingRequest): DESCRIPTION = 'Delete a scheduled action' ARGS = [Arg('ScheduledActionName', metavar='ACTION', help='name of the scheduled action to delete (required)'), Arg('-g', '--auto-scaling-group', dest='AutoScalingGroupName', metavar='ASGROUP', required=True, help='''name of the auto-scaling group the scheduled action is associated with (required)'''), Arg('-f', '--force', route_to=None, action='store_true', help=argparse.SUPPRESS)] # for compatibility euca2ools-3.3.1/euca2ools/commands/autoscaling/deletetags.py000066400000000000000000000030711267461563000241260ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.autoscaling import AutoScalingRequest from euca2ools.commands.autoscaling.arghelpers import TagArg class DeleteTags(AutoScalingRequest): DESCRIPTION = 'Delete one or more resource tags' ARGS = [TagArg(required=True)] euca2ools-3.3.1/euca2ools/commands/autoscaling/describeaccountlimits.py000066400000000000000000000032751267461563000263720ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder.mixins import TabifyingMixin from euca2ools.commands.autoscaling import AutoScalingRequest class DescribeAccountLimits(AutoScalingRequest, TabifyingMixin): DESCRIPTION = "Describe your account's limits on auto-scaling resources" def print_result(self, result): for key, val in sorted(result.items()): print self.tabify((key, val)) euca2ools-3.3.1/euca2ools/commands/autoscaling/describeadjustmenttypes.py000066400000000000000000000035221267461563000267520ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder.mixins import TabifyingMixin class DescribeAdjustmentTypes(AutoScalingRequest, TabifyingMixin): DESCRIPTION = ('Describe policy adjustment types usable with scaling ' 'policies') LIST_TAGS = ['AdjustmentTypes'] def print_result(self, result): for adj_type in result.get('AdjustmentTypes', []): print self.tabify(('ADJUSTMENT-TYPE', adj_type.get('AdjustmentType'))) euca2ools-3.3.1/euca2ools/commands/autoscaling/describeautoscalinggroups.py000066400000000000000000000130211267461563000272530ustar00rootroot00000000000000# Copyright 2013, 2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin from requestbuilder.response import PaginatedResponse class DescribeAutoScalingGroups(AutoScalingRequest, TabifyingMixin): DESCRIPTION = 'Describe auto-scaling groups' ARGS = [Arg('AutoScalingGroupNames.member', metavar='ASGROUP', nargs='*', help='limit results to specific auto-scaling groups'), Arg('--show-long', action='store_true', route_to=None, help="show all of the groups' info")] LIST_TAGS = ['AutoScalingGroups', 'AvailabilityZones', 'EnabledMetrics', 'Instances', 'LoadBalancerNames', 'SuspendedProcesses', 'Tags', 'TerminationPolicies'] def main(self): return PaginatedResponse(self, (None,), ('AutoScalingGroups',)) def prepare_for_page(self, page): # Pages are defined by NextToken self.params['NextToken'] = page def get_next_page(self, response): return response.get('NextToken') or None def print_result(self, result): lines = [] for group in result.get('AutoScalingGroups', []): bits = ['AUTO-SCALING-GROUP', group.get('AutoScalingGroupName'), group.get('LaunchConfigurationName'), ','.join(group.get('AvailabilityZones'))] if self.args['show_long']: bits.append(group.get('CreatedTime')) balancers = group.get('LoadBalancerNames') if balancers: bits.append(','.join(balancers)) else: bits.append(None) if self.args['show_long']: bits.append(group.get('HealthCheckType')) bits.append(group.get('MinSize')) bits.append(group.get('MaxSize')) bits.append(group.get('DesiredCapacity')) if self.args['show_long']: bits.append(group.get('DefaultCooldown')) bits.append(group.get('HealthCheckGracePeriod')) bits.append(group.get('VPCZoneIdentifier')) bits.append(group.get('PlacementGroup')) bits.append(group.get('AutoScalingGroupARN')) policies = group.get('TerminationPolicies') if policies: bits.append(','.join(policies)) else: bits.append(None) lines.append(self.tabify(bits)) for instance in group.get('Instances', []): lines.append(self._get_tabified_instance(instance)) scale_group = group.get('AutoScalingGroupName') for process in group.get('SuspendedProcesses', []): lines.append(self._get_tabified_suspended_process(process, scale_group)) for metric in group.get('EnabledMetrics', []): lines.append(self._get_tabified_metric(metric)) for tag in group.get('Tags') or []: lines.append(self.tabify(['TAG', tag.get('ResourceType'), tag.get('ResourceId'), tag.get('Key'), tag.get('Value'), tag.get('PropagateAtLaunch')])) for line in lines: print line def _get_tabified_instance(self, instance): return self.tabify(['INSTANCE', instance.get('InstanceId'), instance.get('AvailabilityZone'), instance.get('LifecycleState'), instance.get('HealthStatus'), instance.get('LaunchConfigurationName')]) def _get_tabified_suspended_process(self, process, scale_group): return self.tabify(['SUSPENDED-PROCESS', process.get('ProcessName'), process.get('SuspensionReason'), scale_group]) def _get_tabified_metric(self, metric): return self.tabify(['ENABLED-METRICS', metric.get('Metric'), metric.get('Granularity')]) euca2ools-3.3.1/euca2ools/commands/autoscaling/describeautoscalinginstances.py000066400000000000000000000054241267461563000277330ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin from requestbuilder.response import PaginatedResponse class DescribeAutoScalingInstances(AutoScalingRequest, TabifyingMixin): DESCRIPTION = 'Describe instances in auto-scaling groups' ARGS = [Arg('InstanceIds.member', metavar='INSTANCE', nargs='*', help='limit results to specific instances'), Arg('--show-long', action='store_true', route_to=None, help=argparse.SUPPRESS)] # Often typed out of habit LIST_TAGS = ['AutoScalingInstances'] def main(self): return PaginatedResponse(self, (None,), ('AutoScalingInstances',)) def prepare_for_page(self, page): # Pages are defined by NextToken self.params['NextToken'] = page def get_next_page(self, response): return response.get('NextToken') or None def print_result(self, result): for instance in result.get('AutoScalingInstances', []): print self.tabify(('INSTANCE', instance.get('InstanceId'), instance.get('AutoScalingGroupName'), instance.get('AvailabilityZone'), instance.get('LifecycleState'), instance.get('HealthStatus'), instance.get('LaunchConfigurationName'))) euca2ools-3.3.1/euca2ools/commands/autoscaling/describeautoscalingnotificationtypes.py000066400000000000000000000035241267461563000315160ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder.mixins import TabifyingMixin class DescribeAutoScalingNotificationTypes(AutoScalingRequest, TabifyingMixin): DESCRIPTION = 'List all notification types supported by the service' LIST_TAGS = ['AutoScalingNotificationTypes'] def print_result(self, result): for notif_type in result.get('AutoScalingNotificationTypes', []): print self.tabify(('NOTIFICATION-TYPE', notif_type)) euca2ools-3.3.1/euca2ools/commands/autoscaling/describelaunchconfigurations.py000066400000000000000000000102241267461563000277310ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin from requestbuilder.response import PaginatedResponse class DescribeLaunchConfigurations(AutoScalingRequest, TabifyingMixin): DESCRIPTION = 'Describe auto-scaling instance launch configurations' ARGS = [Arg('LaunchConfigurationNames.member', metavar='LAUNCHCONFIG', nargs='*', help='limit results to specific launch configurations'), Arg('--show-long', action='store_true', route_to=None, help="show all of the launch configurations' info")] LIST_TAGS = ['LaunchConfigurations', 'SecurityGroups', 'BlockDeviceMappings'] def main(self): return PaginatedResponse(self, (None,), ('LaunchConfigurations',)) def prepare_for_page(self, page): # Pages are defined by NextToken self.params['NextToken'] = page def get_next_page(self, response): return response.get('NextToken') or None def print_result(self, result): for config in result.get('LaunchConfigurations', []): bits = ['LAUNCH-CONFIG', config.get('LaunchConfigurationName'), config.get('ImageId'), config.get('InstanceType')] if self.args['show_long']: bits.append(config.get('KeyName')) bits.append(config.get('KernelId')) bits.append(config.get('RamdiskId')) block_maps = [convert_block_mapping_to_str(mapping) for mapping in config.get('BlockDeviceMappings', [])] if len(block_maps) > 0: bits.append('{' + ','.join(block_maps) + '}') else: bits.append(None) bits.append(','.join(config.get('SecurityGroups', [])) or None) bits.append(config.get('CreatedTime')) bits.append(config.get('InstanceMonitoring', {}).get( 'Enabled')) bits.append(config.get('LaunchConfigurationARN')) bits.append(config.get('SpotPrice')) bits.append(config.get('IamInstanceProfile')) if self.args['show_long']: bits.append(config.get('EbsOptimized')) bits.append(config.get('AssociatePublicIpAddress')) print self.tabify(bits) def convert_block_mapping_to_str(mapping): if mapping.get('Ebs'): mapped = ':'.join((mapping['Ebs'].get('SnapshotId') or '', mapping['Ebs'].get('VolumeSize') or '')) elif mapping.get('VirtualName'): mapped = mapping['VirtualName'] else: raise ValueError('unexpected block device mapping: {0}'.format( mapping)) return mapping['DeviceName'] + '=' + mapped euca2ools-3.3.1/euca2ools/commands/autoscaling/describemetriccollectiontypes.py000066400000000000000000000037051267461563000301360ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder.mixins import TabifyingMixin class DescribeMetricCollectionTypes(AutoScalingRequest, TabifyingMixin): DESCRIPTION = 'Describe auto-scaling metrics and granularities' LIST_TAGS = ['Metrics', 'Granularities'] def print_result(self, result): for metric in result.get('Metrics', []): print self.tabify(('METRIC-COLLECTION-TYPE', metric.get('Metric'))) for granularity in result.get('Granularities', []): print self.tabify(('METRIC-GRANULARITY-TYPE', granularity.get('Granularity'))) euca2ools-3.3.1/euca2ools/commands/autoscaling/describenotificationconfigurations.py000066400000000000000000000051051267461563000311470ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin from requestbuilder.response import PaginatedResponse class DescribeNotificationConfigurations(AutoScalingRequest, TabifyingMixin): DESCRIPTION = ('Describe notification actions associated with ' 'auto-scaling groups') ARGS = [Arg('AutoScalingGroupNames.member', metavar='ASGROUP', nargs='*', help='limit results to specific auto-scaling groups')] LIST_TAGS = ['NotificationConfigurations'] def main(self): return PaginatedResponse(self, (None,), ('NotificationConfigurations',)) def prepare_for_page(self, page): # Pages are defined by NextToken self.params['NextToken'] = page def get_next_page(self, response): return response.get('NextToken') or None def print_result(self, result): for config in result.get('NotificationConfigurations', []): print self.tabify(('NOTIFICATION-CONFIG', config.get('AutoScalingGroupName'), config.get('TopicARN'), config.get('NotificationType'))) euca2ools-3.3.1/euca2ools/commands/autoscaling/describepolicies.py000066400000000000000000000056541267461563000253260ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin from requestbuilder.response import PaginatedResponse class DescribePolicies(AutoScalingRequest, TabifyingMixin): DESCRIPTION = 'Describe auto-scaling policies' ARGS = [Arg('PolicyNames.member', metavar='POLICY', nargs='*', help='limit results to specific auto-scaling policies'), Arg('-g', '--auto-scaling-group', dest='AutoScalingGroupName', metavar='ASGROUP'), Arg('--show-long', action='store_true', route_to=None, help="show all of the policies' info")] LIST_TAGS = ['ScalingPolicies', 'Alarms'] def main(self): return PaginatedResponse(self, (None,), ('ScalingPolicies',)) def prepare_for_page(self, page): # Pages are defined by NextToken self.params['NextToken'] = page def get_next_page(self, response): return response.get('NextToken') or None def print_result(self, result): for policy in result.get('ScalingPolicies', []): bits = ['SCALING-POLICY', policy.get('AutoScalingGroupName'), policy.get('PolicyName'), policy.get('ScalingAdjustment')] if self.args['show_long']: bits.append(policy.get('MinAdjustmentStep')) bits.append(policy.get('AdjustmentType')) if self.args['show_long']: bits.append(policy.get('Cooldown')) bits.append(policy.get('PolicyARN')) print self.tabify(bits) euca2ools-3.3.1/euca2ools/commands/autoscaling/describescalingactivities.py000066400000000000000000000066141267461563000272210ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin from requestbuilder.response import PaginatedResponse class DescribeScalingActivities(AutoScalingRequest, TabifyingMixin): DESCRIPTION = 'Describe past and current auto-scaling activities' ARGS = [Arg('ActivityIds.member', metavar='ACTIVITY', nargs='*', help='limit results to specific auto-scaling activities'), Arg('-g', '--auto-scaling-group', dest='AutoScalingGroupName', metavar='ASGROUP', help='''name of an Auto Scaling group by which to filter the request'''), Arg('--show-long', action='store_true', route_to=None, help="show all of the activities' info")] LIST_TAGS = ['Activities'] def main(self): return PaginatedResponse(self, (None,), ('Activities',)) def prepare_for_page(self, page): # Pages are defined by NextToken self.params['NextToken'] = page def get_next_page(self, response): return response.get('NextToken') or None def print_result(self, result): for activity in result.get('Activities', []): bits = ['ACTIVITY', activity.get('ActivityId'), activity.get('EndTime'), activity.get('AutoScalingGroupName'), activity.get('StatusCode'), activity.get('StatusMessage')] if self.args['show_long']: bits.append(activity.get('Cause')) bits.append(activity.get('Progress')) bits.append(activity.get('Description')) # The AWS tool refers to this as "UPDATE-TIME", but seeing as # the API doesn't actually have anything like that, the process # of elimination dictates that this be the Details element in # the response instead. bits.append(activity.get('Details')) bits.append(activity.get('StartTime')) print self.tabify(bits) euca2ools-3.3.1/euca2ools/commands/autoscaling/describescalingprocesstypes.py000066400000000000000000000033541267461563000276160ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder.mixins import TabifyingMixin class DescribeScalingProcessTypes(AutoScalingRequest, TabifyingMixin): DESCRIPTION = 'List all types of scaling processes' LIST_TAGS = ['Processes'] def print_result(self, result): for process in result.get('Processes', []): print self.tabify(('PROCESS', process.get('ProcessName'))) euca2ools-3.3.1/euca2ools/commands/autoscaling/describescheduledactions.py000066400000000000000000000067471267461563000270440ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin from requestbuilder.response import PaginatedResponse class DescribeScheduledActions(AutoScalingRequest, TabifyingMixin): DESCRIPTION = 'Describe scheduled auto-scaling group actions' ARGS = [Arg('ScheduledActionNames.member', metavar='ACTION', nargs='*', help='limit results to specific actions'), Arg('-g', '--group', dest='AutoScalingGroupName', metavar='ASGROUP'), Arg('--start-time', dest='StartTime', metavar='YYYY-MM-DDThh:mm:ssZ', help='''earliest start time to return scheduled actions for. This is ignored when specific action names are provided.'''), Arg('--end-time', dest='EndTime', metavar='YYYY-MM-DDThh:mm:ssZ', help='''latest start time to return scheduled actions for. This is ignored when specific action names are provided.'''), Arg('--show-long', action='store_true', route_to=None, help="show all of the scheduled actions' info")] LIST_TAGS = ['ScheduledUpdateGroupActions'] def main(self): return PaginatedResponse(self, (None,), ('ScheduledUpdateGroupActions',)) def prepare_for_page(self, page): # Pages are defined by NextToken self.params['NextToken'] = page def get_next_page(self, response): return response.get('NextToken') or None def print_result(self, result): for action in result.get('ScheduledUpdateGroupActions', []): bits = ['UPDATE-GROUP-ACTION', action.get('AutoScalingGroupName'), action.get('ScheduledActionName'), action.get('StartTime'), action.get('Recurrence'), action.get('MinSize'), action.get('MaxSize'), action.get('DesiredCapacity')] if self.args['show_long']: bits.append(action.get('ScheduledActionARN')) print self.tabify(bits) euca2ools-3.3.1/euca2ools/commands/autoscaling/describetags.py000066400000000000000000000047461267461563000244560ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.autoscaling import AutoScalingRequest from euca2ools.commands.autoscaling.argtypes import autoscaling_filter_def from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin from requestbuilder.response import PaginatedResponse class DescribeTags(AutoScalingRequest, TabifyingMixin): DESCRIPTION = 'Describe auto-scaling tags' ARGS = [Arg('--filter', dest='Filters.member', type=autoscaling_filter_def, metavar='NAME=VALUE,...', action='append', help='restrict results to those that meet criteria')] LIST_TAGS = ['Tags'] def main(self): return PaginatedResponse(self, (None,), ('Tags',)) def prepare_for_page(self, page): # Pages are defined by NextToken self.params['NextToken'] = page def get_next_page(self, response): return response.get('NextToken') or None def print_result(self, result): for tag in result.get('Tags', []): print self.tabify(('TAG', tag.get('ResourceId'), tag.get('ResourceType'), tag.get('Key'), tag.get('Value'), tag.get('PropagateAtLaunch'))) euca2ools-3.3.1/euca2ools/commands/autoscaling/describeterminationpolicytypes.py000066400000000000000000000034311267461563000303440ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder.mixins import TabifyingMixin class DescribeTerminationPolicyTypes(AutoScalingRequest, TabifyingMixin): DESCRIPTION = 'List all termination policies supported by the service' LIST_TAGS = ['TerminationPolicyTypes'] def print_result(self, result): for tp_type in result.get('TerminationPolicyTypes', []): print self.tabify(('TERMINATION-POLICY-TYPE', tp_type)) euca2ools-3.3.1/euca2ools/commands/autoscaling/disablemetricscollection.py000066400000000000000000000036561267461563000270640ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.argtypes import delimited_list from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder import Arg class DisableMetricsCollection(AutoScalingRequest): DESCRIPTION = "Disable monitoring of an auto-scaling group's group metrics" ARGS = [Arg('AutoScalingGroupName', metavar='ASGROUP', help='name of the auto-scaling group to update (required)'), Arg('-m', '--metrics', dest='Metrics.member', metavar='METRIC1,METRIC2,...', type=delimited_list(','), help='list of metrics to disable (default: all metrics)')] euca2ools-3.3.1/euca2ools/commands/autoscaling/enablemetricscollection.py000066400000000000000000000041501267461563000266750ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.argtypes import delimited_list from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder import Arg class EnableMetricsCollection(AutoScalingRequest): DESCRIPTION = "Enable monitoring of an auto-scaling group's group metrics" ARGS = [Arg('AutoScalingGroupName', metavar='ASGROUP', help='name of the auto-scaling group to update (required)'), Arg('-g', '--granularity', dest='Granularity', required=True, help='''granularity at which to collect metrics (e.g., '1Minute') (required)'''), Arg('-m', '--metrics', dest='Metrics.member', metavar='METRIC1,METRIC2,...', type=delimited_list(','), help='list of metrics to collect (default: all metrics)')] euca2ools-3.3.1/euca2ools/commands/autoscaling/executepolicy.py000066400000000000000000000043561267461563000246760ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder import Arg class ExecutePolicy(AutoScalingRequest): DESCRIPTION = "Manually set an auto-scaling instance's health status" ARGS = [Arg('PolicyName', metavar='POLICY', help='name or ARN of the policy to run (required)'), Arg('-g', '--auto-scaling-group', dest='AutoScalingGroupName', metavar='ASGROUP', help='name or ARN of the auto-scaling group'), Arg('-h', '--honor-cooldown', dest='HonorCooldown', action='store_const', const='true', help='''reject the request if the group is in cooldown (default: override any cooldown period)'''), Arg('-H', '--no-honor-cooldown', dest='HonorCooldown', action='store_const', const='false', help='override any cooldown period (this is the default)')] euca2ools-3.3.1/euca2ools/commands/autoscaling/putnotificationconfiguration.py000066400000000000000000000043441267461563000300200ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.argtypes import delimited_list from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder import Arg class PutNotificationConfiguration(AutoScalingRequest): DESCRIPTION = ("Create or replace an auto-scaling group's notification " "configuration") ARGS = [Arg('AutoScalingGroupName', metavar='ASGROUP', help='name of the auto-scaling group to update (required)'), Arg('-n', '--notification-types', dest='NotificationTypes.member', metavar='TYPE1,TYPE2,...', type=delimited_list(','), required=True, help=('''comma-separated list of event types that will trigger notification (required)''')), Arg('-t', '--topic-arn', dest='TopicARN', metavar='TOPIC', required=True, help='''ARN of the SNS topic to publish notifications to (required)''')] euca2ools-3.3.1/euca2ools/commands/autoscaling/putscalingpolicy.py000066400000000000000000000063561267461563000254070ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder import Arg class PutScalingPolicy(AutoScalingRequest): DESCRIPTION = "Create or update an auto-scaling group's scaling policy" ARGS = [Arg('PolicyName', metavar='POLICY', help='name of the policy to create or update (required)'), Arg('-g', '--auto-scaling-group', dest='AutoScalingGroupName', metavar='ASGROUP', required=True, help='''name of the auto-scaling group the policy is associated with (required)'''), Arg('-a', '--adjustment', dest='ScalingAdjustment', metavar='SCALE', type=int, required=True, help='''amount to scale the group's capacity of the group. Use a negative value, as in "--adjustment=-1", to decrease capacity. (required)'''), Arg('-t', '--type', dest='AdjustmentType', required=True, choices=('ChangeInCapacity', 'ExactCapacity', 'PercentChangeInCapacity'), help='''whether the adjustment is the new desired size or an increment to the group's current capacity. An increment can either be a fixed number or a percentage of current capacity. (required)'''), Arg('--cooldown', dest='Cooldown', metavar='SECONDS', type=int, help='''waiting period after successful auto-scaling activities during which later auto-scaling activities will not execute'''), Arg('-s', '--min-adjustment-step', dest='MinAdjustmentStep', type=int, metavar='PERCENT', help='''for a PercentChangeInCapacity type policy, guarantee that this policy will change the group's desired capacity by at least this much''')] def print_result(self, result): print result.get('PolicyARN') euca2ools-3.3.1/euca2ools/commands/autoscaling/putscheduledupdategroupaction.py000066400000000000000000000054471267461563000301650ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder import Arg class PutScheduledUpdateGroupAction(AutoScalingRequest): DESCRIPTION = 'Schedule a scaling action for an auto-scaling group' ARGS = [Arg('ScheduledActionName', metavar='ACTION', help='name of the new scheduled action'), Arg('-g', '--auto-scaling-group', dest='AutoScalingGroupName', metavar='ASGROUP', required=True, help='''auto-scaling group the new action should affect (required)'''), Arg('-b', '--start-time', dest='StartTime', metavar='YYYY-MM-DDThh:mm:ssZ', help='time for this action to start'), Arg('-e', '--end-time', dest='EndTime', metavar='YYYY-MM-DDThh:mm:ssZ', help='time for this action to end'), Arg('-r', '--recurrence', dest='Recurrence', metavar='"MIN HOUR DATE MONTH DAY"', help='''time when recurring future actions will start, in crontab format'''), Arg('--desired-capacity', dest='DesiredCapacity', metavar='COUNT', type=int, help='new capacity setting for the group'), Arg('--max-size', dest='MaxSize', metavar='COUNT', type=int, help='maximum number of instances to allow in the group'), Arg('--min-size', dest='MinSize', metavar='COUNT', type=int, help='minimum number of instances to allow in the group')] euca2ools-3.3.1/euca2ools/commands/autoscaling/resumeprocesses.py000066400000000000000000000037321267461563000252400ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.argtypes import delimited_list from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder import Arg class ResumeProcesses(AutoScalingRequest): DESCRIPTION = "Resume an auto-scaling group's auto-scaling processes" ARGS = [Arg('AutoScalingGroupName', metavar='ASGROUP', help='name of the auto-scaling group to update (required)'), Arg('--processes', dest='ScalingProcesses.member', metavar='PROCESS1,PROCESS2,...', type=delimited_list(','), help='''comma-separated list of auto-scaling processes to resume (default: all processes)''')] euca2ools-3.3.1/euca2ools/commands/autoscaling/setdesiredcapacity.py000066400000000000000000000044041267461563000256570ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder import Arg class SetDesiredCapacity(AutoScalingRequest): DESCRIPTION = "Set an auto-scaling group's desired capacity" ARGS = [Arg('AutoScalingGroupName', metavar='ASGROUP', help='name of the auto-scaling group to update (required)'), Arg('-c', '--desired-capacity', dest='DesiredCapacity', type=int, required=True, help='new capacity setting for the group (required)'), Arg('-h', '--honor-cooldown', dest='HonorCooldown', action='store_const', const='true', help='''reject the request if the group is in cooldown (default: override any cooldown period)'''), Arg('-H', '--no-honor-cooldown', dest='HonorCooldown', action='store_const', const='false', help='override any cooldown period (this is the default)')] euca2ools-3.3.1/euca2ools/commands/autoscaling/setinstancehealth.py000066400000000000000000000044751267461563000255240ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder import Arg class SetInstanceHealth(AutoScalingRequest): DESCRIPTION = "Manually set an auto-scaling instance's health status" ARGS = [Arg('InstanceId', metavar='INSTANCE', help='ID of the instance to update (required)'), Arg('-s', '--status', dest='HealthStatus', required=True, choices=('Healthy', 'Unhealthy'), help='new status (required)'), Arg('--respect-grace-period', dest='ShouldRespectGracePeriod', action='store_const', const='true', help="""respect the associated auto-scaling group's grace period (this is the default)"""), Arg('--no-respect-grace-period', dest='ShouldRespectGracePeriod', action='store_const', const='false', help="""ignore the associated auto-scaling group's grace period (default: respect the group's grace period)""")] euca2ools-3.3.1/euca2ools/commands/autoscaling/suspendprocesses.py000066400000000000000000000037351267461563000254240ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.argtypes import delimited_list from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder import Arg class SuspendProcesses(AutoScalingRequest): DESCRIPTION = "Suspend an auto-scaling group's auto-scaling processes" ARGS = [Arg('AutoScalingGroupName', metavar='ASGROUP', help='name of the auto-scaling group to update (required)'), Arg('--processes', dest='ScalingProcesses.member', metavar='PROCESS1,PROCESS2,...', type=delimited_list(','), help='''comma-separated list of auto-scaling processes to suspend (default: all processes)''')] euca2ools-3.3.1/euca2ools/commands/autoscaling/terminateinstanceinautoscalinggroup.py000066400000000000000000000064511267461563000313650ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from requestbuilder import Arg, MutuallyExclusiveArgList from requestbuilder.mixins import TabifyingMixin from euca2ools.commands.autoscaling import AutoScalingRequest class TerminateInstanceInAutoScalingGroup(AutoScalingRequest, TabifyingMixin): DESCRIPTION = "Manually terminate an auto-scaling instance" ARGS = [Arg('InstanceId', metavar='INSTANCE', help='ID of the instance to terminate (required)'), MutuallyExclusiveArgList( Arg('-d', '--decrement-desired-capacity', action='store_const', dest='ShouldDecrementDesiredCapacity', const='true', help='''also reduce the desired capacity of the auto-scaling group by 1'''), Arg('-D', '--no-decrement-desired-capacity', dest='ShouldDecrementDesiredCapacity', action='store_const', const='false', help='''leave the auto-scaling group's desired capacity as-is. A new instance may be launched to compensate for the one being terminated.''')) .required(), Arg('--show-long', action='store_true', route_to=None, help='show extra info about the instance being terminated'), Arg('-f', '--force', action='store_true', route_to=None, help=argparse.SUPPRESS)] # for compatibility def print_result(self, result): activity = result['Activity'] bits = ['INSTANCE', activity.get('ActivityId'), activity.get('EndTime'), activity.get('StatusCode'), activity.get('Cause')] if self.args['show_long']: bits.append(activity.get('StatusMessage')) bits.append(activity.get('Progress')) bits.append(activity.get('Description')) bits.append(activity.get('StartTime')) print self.tabify(bits) euca2ools-3.3.1/euca2ools/commands/autoscaling/updateautoscalinggroup.py000066400000000000000000000100541267461563000265750ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.argtypes import delimited_list from euca2ools.commands.autoscaling import AutoScalingRequest from requestbuilder import Arg class UpdateAutoScalingGroup(AutoScalingRequest): DESCRIPTION = "Update an auto-scaling group's parameters" ARGS = [Arg('AutoScalingGroupName', metavar='ASGROUP', help='name of the auto-scaling group to update (required)'), Arg('--default-cooldown', dest='DefaultCooldown', metavar='SECONDS', type=int, help='''amount of time, in seconds, after a scaling activity completes before any further trigger-related scaling activities may start'''), Arg('--desired-capacity', dest='DesiredCapacity', metavar='COUNT', type=int, help='number of running instances the group should contain'), Arg('--grace-period', dest='HealthCheckGracePeriod', metavar='SECONDS', type=int, help='''number of seconds to wait before starting health checks on newly-created instances'''), Arg('--health-check-type', dest='HealthCheckType', choices=('EC2', 'ELB'), help='service to obtain health check status from'), Arg('-l', '--launch-configuration', dest='LaunchConfigurationName', metavar='LAUNCHCONFIG', help='''name of the launch configuration to use with the new group (required)'''), Arg('-M', '--max-size', dest='MaxSize', metavar='COUNT', type=int, help='maximum group size (required)'), Arg('-m', '--min-size', dest='MinSize', metavar='COUNT', type=int, help='minimum group size (required)'), Arg('--placement-group', dest='PlacementGroup', help='placement group in which to launch new instances'), Arg('--termination-policies', dest='TerminationPolicies.member', metavar='POLICY1,POLICY2,...', type=delimited_list(','), help='''ordered list of termination policies. The first has the highest precedence.'''), Arg('--vpc-zone-identifier', dest='VPCZoneIdentifier', metavar='ZONE1,ZONE2,...', help='''comma-separated list of subnet identifiers. If you specify availability zones as well, ensure the subnets' availability zones match the ones you specified'''), Arg('-z', '--availability-zones', dest='AvailabilityZones.member', metavar='ZONE1,ZONE2,...', type=delimited_list(','), help='''comma-separated list of availability zones for the new group (required unless subnets are supplied)''')] euca2ools-3.3.1/euca2ools/commands/bootstrap/000077500000000000000000000000001267461563000211365ustar00rootroot00000000000000euca2ools-3.3.1/euca2ools/commands/bootstrap/__init__.py000066400000000000000000000045111267461563000232500ustar00rootroot00000000000000# Copyright 2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg import requestbuilder.auth.aws import requestbuilder.request import requestbuilder.service from euca2ools.commands import Euca2ools from euca2ools.exceptions import AWSError from euca2ools.util import add_fake_region_name class Bootstrap(requestbuilder.service.BaseService): # Also known as Empyrean NAME = 'bootstrap' DESCRIPTION = '[Eucalyptus only] Bootstrap service' API_VERSION = 'eucalyptus' REGION_ENVVAR = 'AWS_DEFAULT_REGION' URL_ENVVAR = 'EUCA_BOOTSTRAP_URL' ARGS = [Arg('-U', '--url', metavar='URL', help='[Eucalyptus only] bootstrap service endpoint URL')] def configure(self): requestbuilder.service.BaseService.configure(self) add_fake_region_name(self) def handle_http_error(self, response): raise AWSError(response) class BootstrapRequest(requestbuilder.request.AWSQueryRequest): SUITE = Euca2ools SERVICE_CLASS = Bootstrap AUTH_CLASS = requestbuilder.auth.aws.HmacV4Auth METHOD = 'POST' euca2ools-3.3.1/euca2ools/commands/bootstrap/describeservicecertificates.py000066400000000000000000000037551267461563000272510ustar00rootroot00000000000000# Copyright 2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, Filter from euca2ools.commands.bootstrap import BootstrapRequest class DescribeServiceCertificates(BootstrapRequest): DESCRIPTION = 'Show information about one or more service certificates' ARGS = [Arg('--format', dest='Format', choices=('pem', 'der'), type=str.lower, help='format to output certificates in'), Arg('--digest', dest='FingerprintDigest', type=str.upper, choices=('SHA-1', 'SHA-256'), help='digest algorithm to use for certificate fingerprints')] FILTERS = [Filter('certificate-usage'), Filter('service-type')] LIST_TAGS = ['serviceCertificates'] euca2ools-3.3.1/euca2ools/commands/bundle/000077500000000000000000000000001267461563000203725ustar00rootroot00000000000000euca2ools-3.3.1/euca2ools/commands/bundle/__init__.py000066400000000000000000000025021267461563000225020ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. euca2ools-3.3.1/euca2ools/commands/bundle/bundleanduploadimage.py000066400000000000000000000222531267461563000251140ustar00rootroot00000000000000# Copyright 2013-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse import multiprocessing import os.path import tarfile from requestbuilder import Arg from requestbuilder.mixins import FileTransferProgressBarMixin from euca2ools.bundle.pipes.core import create_bundle_pipeline from euca2ools.bundle.pipes.fittings import (create_bundle_part_deleter, create_bundle_part_writer, create_mpconn_aggregator) import euca2ools.bundle.manifest import euca2ools.bundle.util from euca2ools.commands.bundle.mixins import (BundleCreatingMixin, BundleUploadingMixin) from euca2ools.commands.bootstrap import BootstrapRequest from euca2ools.commands.s3 import S3Request from euca2ools.util import mkdtemp_for_large_files class BundleAndUploadImage(S3Request, BundleCreatingMixin, BundleUploadingMixin, FileTransferProgressBarMixin): DESCRIPTION = 'Prepare and upload an image for use in the cloud' ARGS = [Arg('--preserve-bundle', action='store_true', help='do not delete the bundle as it is being uploaded'), Arg('--max-pending-parts', type=int, default=2, help='''pause the bundling process when more than this number of parts are waiting to be uploaded (default: 2)''')] # noinspection PyExceptionInherit def configure(self): # This goes before configure because -S's absence causes # self.auth.configure to blow up. With an upload policy that # is undesirable. self.configure_bundle_upload_auth() S3Request.configure(self) # Set up access to bootstrap in case we need auto cert fetching. try: self.args['bootstrap_service'] = \ BootstrapRequest.SERVICE_CLASS.from_other( self.service, url=self.args.get('bootstrap_url')) self.args['bootstrap_auth'] = \ BootstrapRequest.AUTH_CLASS.from_other(self.auth) except: self.log.debug('bootstrap setup failed; auto cert fetching ' 'will be unavailable', exc_info=True) self.configure_bundle_creds() self.configure_bundle_properties() self.configure_bundle_output() self.generate_encryption_keys() def main(self): if self.args.get('destination'): path_prefix = os.path.join(self.args['destination'], self.args['prefix']) if not os.path.exists(self.args['destination']): os.mkdir(self.args['destination']) else: tempdir = mkdtemp_for_large_files(prefix='bundle-') path_prefix = os.path.join(tempdir, self.args['prefix']) self.log.debug('bundle path prefix: %s', path_prefix) key_prefix = self.get_bundle_key_prefix() self.ensure_dest_bucket_exists() # First create the bundle and upload it to the server digest, partinfo = self.create_and_upload_bundle(path_prefix, key_prefix) # All done; now build the manifest, write it to disk, and upload it. manifest = self.build_manifest(digest, partinfo) manifest_filename = '{0}.manifest.xml'.format(path_prefix) with open(manifest_filename, 'w') as manifest_file: manifest.dump_to_file(manifest_file, self.args.get('privatekey'), self.args.get('cert'), self.args['ec2cert']) manifest_dest = key_prefix + os.path.basename(manifest_filename) self.upload_bundle_file(manifest_filename, manifest_dest, show_progress=self.args.get('show_progress')) if not self.args.get('preserve_bundle', False): os.remove(manifest_filename) # Then we just inform the caller of all the files we wrote. # Manifests are returned in a tuple for future expansion, where we # bundle for more than one region at a time. return {'parts': tuple({'filename': part.filename, 'key': (key_prefix + os.path.basename(part.filename))} for part in manifest.image_parts), 'manifests': ({'filename': manifest_filename, 'key': manifest_dest},)} def print_result(self, result): if self.debug: for part in result['parts']: print 'Uploaded', part['key'] if result['manifests'][0]['key'] is not None: print 'Uploaded', result['manifests'][0]['key'] def create_and_upload_bundle(self, path_prefix, key_prefix): part_write_sem = multiprocessing.Semaphore( max(1, self.args['max_pending_parts'])) # Fill out all the relevant info needed for a tarball tarinfo = tarfile.TarInfo(self.args['prefix']) tarinfo.size = self.args['image_size'] # disk --(bytes)-> bundler partwriter_in_r, partwriter_in_w = \ euca2ools.bundle.util.open_pipe_fileobjs() digest_result_mpconn = create_bundle_pipeline( self.args['image'], partwriter_in_w, self.args['enc_key'], self.args['enc_iv'], tarinfo, debug=self.debug) partwriter_in_w.close() # bundler --(bytes)-> part writer bundle_partinfo_mpconn = create_bundle_part_writer( partwriter_in_r, path_prefix, self.args['part_size'], part_write_sem=part_write_sem, debug=self.debug) partwriter_in_r.close() # part writer --(part info)-> part uploader # This must be driven on the main thread since it has a progress bar, # so for now we'll just set up its output pipe so we can attach it to # the remainder of the pipeline. uploaded_partinfo_mpconn_r, uploaded_partinfo_mpconn_w = \ multiprocessing.Pipe(duplex=False) # part uploader --(part info)-> part deleter if not self.args.get('preserve_bundle', False): deleted_partinfo_mpconn_r, deleted_partinfo_mpconn_w = \ multiprocessing.Pipe(duplex=False) create_bundle_part_deleter(uploaded_partinfo_mpconn_r, out_mpconn=deleted_partinfo_mpconn_w) uploaded_partinfo_mpconn_r.close() deleted_partinfo_mpconn_w.close() else: # Bypass this stage deleted_partinfo_mpconn_r = uploaded_partinfo_mpconn_r # part deleter --(part info)-> part info aggregator # (needed for building the manifest) bundle_partinfo_aggregate_mpconn = create_mpconn_aggregator( deleted_partinfo_mpconn_r, debug=self.debug) deleted_partinfo_mpconn_r.close() # Now drive the pipeline by uploading parts. try: self.upload_bundle_parts( bundle_partinfo_mpconn, key_prefix, partinfo_out_mpconn=uploaded_partinfo_mpconn_w, part_write_sem=part_write_sem, show_progress=self.args.get('show_progress')) finally: # Make sure the writer gets a chance to exit part_write_sem.release() # All done; now grab info about the bundle we just created try: digest = digest_result_mpconn.recv() partinfo = bundle_partinfo_aggregate_mpconn.recv() except EOFError: self.log.debug('EOFError from reading bundle info', exc_info=True) raise RuntimeError( 'corrupt bundle: bundle process was interrupted') finally: digest_result_mpconn.close() bundle_partinfo_aggregate_mpconn.close() self.log.info('%i bundle parts uploaded to %s', len(partinfo), self.args['bucket']) self.log.debug('bundle digest: %s', digest) return digest, partinfo euca2ools-3.3.1/euca2ools/commands/bundle/bundleimage.py000066400000000000000000000210121267461563000232140ustar00rootroot00000000000000# Copyright 2013-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os.path import tarfile from requestbuilder.command import BaseCommand from requestbuilder.mixins import (FileTransferProgressBarMixin, RegionConfigurableMixin) import euca2ools.bundle.manifest from euca2ools.bundle.pipes.core import (create_bundle_pipeline, copy_with_progressbar) from euca2ools.bundle.pipes.fittings import (create_bundle_part_writer, create_mpconn_aggregator) import euca2ools.bundle.util from euca2ools.commands import Euca2ools from euca2ools.commands.bundle.mixins import BundleCreatingMixin from euca2ools.commands.bootstrap import BootstrapRequest from euca2ools.util import mkdtemp_for_large_files class BundleImage(BaseCommand, BundleCreatingMixin, FileTransferProgressBarMixin, RegionConfigurableMixin): SUITE = Euca2ools DESCRIPTION = 'Prepare an image for use in the cloud' REGION_ENVVAR = 'AWS_DEFAULT_REGION' # Needed because BundleImage has no auth class of its own ARGS = BootstrapRequest.AUTH_CLASS.ARGS # noinspection PyExceptionInherit def configure(self): self.update_config_view() BaseCommand.configure(self) # Set up access to bootstrap in case we need auto cert fetching. # # We would normally make short work of this using from_other # methods, but since BundleImage doesn't have service or # auth classes of its own we get to do this the hard way. if not self.args.get('bootstrap_service'): service = BootstrapRequest.SERVICE_CLASS( config=self.config, loglevel=self.log.level, url=self.args.get('bootstrap_url')) try: service.configure() except: self.log.debug('bootstrap service setup failed; auto cert ' 'fetching will be unavailable', exc_info=True) else: self.args['bootstrap_service'] = service if (not self.args.get('bootstrap_auth') and self.args.get('bootstrap_service')): auth = BootstrapRequest.AUTH_CLASS( config=self.config, loglevel=self.log.level, **self.args) try: auth.configure() except: self.log.debug('bootstrap auth setup failed; auto cert ' 'fetching will be unavailable', exc_info=True) else: self.args['bootstrap_auth'] = auth self.configure_bundle_creds() self.configure_bundle_properties() self.configure_bundle_output() self.generate_encryption_keys() def main(self): if self.args.get('destination'): path_prefix = os.path.join(self.args['destination'], self.args['prefix']) if not os.path.exists(self.args['destination']): os.mkdir(self.args['destination']) else: tempdir = mkdtemp_for_large_files(prefix='bundle-') path_prefix = os.path.join(tempdir, self.args['prefix']) self.log.debug('bundle path prefix: %s', path_prefix) # First create the bundle digest, partinfo = self.create_bundle(path_prefix) # All done; now build the manifest and write it to disk manifest = self.build_manifest(digest, partinfo) manifest_filename = '{0}.manifest.xml'.format(path_prefix) with open(manifest_filename, 'w') as manifest_file: manifest.dump_to_file(manifest_file, self.args['privatekey'], self.args['cert'], self.args['ec2cert']) # Then we just inform the caller of all the files we wrote. # Manifests are returned in a tuple for future expansion, where we # bundle for more than one region at a time. return (part.filename for part in partinfo), (manifest_filename,) def print_result(self, result): for manifest_filename in result[1]: print 'Wrote manifest', manifest_filename def create_bundle(self, path_prefix): # Fill out all the relevant info needed for a tarball tarinfo = tarfile.TarInfo(self.args['prefix']) tarinfo.size = self.args['image_size'] # The pipeline begins with self.args['image'] feeding a bundling pipe # segment through a progress meter, which has to happen on the main # thread, so we add that to the pipeline last. # meter --(bytes)--> bundler bundle_in_r, bundle_in_w = euca2ools.bundle.util.open_pipe_fileobjs() partwriter_in_r, partwriter_in_w = \ euca2ools.bundle.util.open_pipe_fileobjs() digest_result_mpconn = create_bundle_pipeline( bundle_in_r, partwriter_in_w, self.args['enc_key'], self.args['enc_iv'], tarinfo, debug=self.debug) bundle_in_r.close() partwriter_in_w.close() # bundler --(bytes)-> part writer bundle_partinfo_mpconn = create_bundle_part_writer( partwriter_in_r, path_prefix, self.args['part_size'], debug=self.debug) partwriter_in_r.close() # part writer --(part info)-> part info aggregator # (needed for building the manifest) bundle_partinfo_aggr_mpconn = create_mpconn_aggregator( bundle_partinfo_mpconn, debug=self.debug) bundle_partinfo_mpconn.close() # disk --(bytes)-> bundler # (synchronous) label = self.args.get('progressbar_label') or 'Bundling image' pbar = self.get_progressbar(label=label, maxval=self.args['image_size']) with self.args['image'] as image: try: read_size = copy_with_progressbar(image, bundle_in_w, progressbar=pbar) except ValueError: self.log.debug('error from copy_with_progressbar', exc_info=True) raise RuntimeError('corrupt bundle: input size was larger ' 'than expected image size of {0}' .format(self.args['image_size'])) bundle_in_w.close() if read_size != self.args['image_size']: raise RuntimeError('corrupt bundle: input size did not match ' 'expected image size (expected size: {0}, ' 'read: {1})' .format(self.args['image_size'], read_size)) # All done; now grab info about the bundle we just created try: digest = digest_result_mpconn.recv() partinfo = bundle_partinfo_aggr_mpconn.recv() except EOFError: self.log.debug('EOFError from reading bundle info', exc_info=True) raise RuntimeError( 'corrupt bundle: bundle process was interrupted') finally: digest_result_mpconn.close() bundle_partinfo_aggr_mpconn.close() self.log.info('%i bundle parts written to %s', len(partinfo), os.path.dirname(path_prefix)) self.log.debug('bundle digest: %s', digest) return digest, partinfo euca2ools-3.3.1/euca2ools/commands/bundle/bundlevolume.py000066400000000000000000000615401267461563000234530ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse import os.path import pipes import shutil import subprocess import sys import tempfile import time from requestbuilder import Arg, MutuallyExclusiveArgList from requestbuilder.command import BaseCommand from requestbuilder.exceptions import ArgumentError, ClientError from requestbuilder.mixins import FileTransferProgressBarMixin import requests import euca2ools from euca2ools.commands import Euca2ools, SYSCONFDIR from euca2ools.commands.argtypes import (delimited_list, filesize, manifest_block_device_mappings) from euca2ools.commands.bundle.bundleimage import BundleImage ALLOWED_FILESYSTEM_TYPES = ['btrfs', 'ext2', 'ext3', 'ext4', 'jfs', 'xfs'] EXCLUDES_FILE = os.path.join(SYSCONFDIR, 'bundle-vol', 'excludes') FSTAB_TEMPLATE_FILE = os.path.join(SYSCONFDIR, 'bundle-vol', 'fstab') class BundleVolume(BaseCommand, FileTransferProgressBarMixin): SUITE = Euca2ools DESCRIPTION = ("Prepare this machine's filesystem for use in the cloud\n\n" "This command must be run as the superuser.") REGION_ENVVAR = 'AWS_DEFAULT_REGION' ARGS = [Arg('-p', '--prefix', help='''the file name prefix to give the bundle's files (default: image)'''), Arg('-d', '--destination', metavar='DIR', help='''location to place the bundle's files (default: dir named by TMPDIR, TEMP, or TMP environment variables, or otherwise /var/tmp)'''), # -r/--arch is required, but to keep the UID check we do at the # beginning of configure() first we enforce that there instead. Arg('-r', '--arch', help="the image's architecture (required)", choices=('i386', 'x86_64', 'armhf', 'ppc', 'ppc64', 'ppc64le')), Arg('-e', '--exclude', metavar='PATH,...', type=delimited_list(','), help='comma-separated list of paths to exclude'), Arg('-i', '--include', metavar='PATH,...', type=delimited_list(','), help='comma-separated list of paths to include'), Arg('-s', '--size', metavar='MiB', type=int, default=10240, help='size of the image to create (default: 10240 MiB)'), Arg('--no-filter', action='store_true', help='do not filter out sensitive/system files'), Arg('--all', action='store_true', help='''include all filesystems regardless of type (default: only include local filesystems)'''), MutuallyExclusiveArgList( Arg('--inherit', dest='inherit', action='store_true', help='''use the metadata service to provide metadata for the bundle (this is the default)'''), Arg('--no-inherit', dest='inherit', action='store_false', help='''do not use the metadata service for bundle metadata''')), Arg('-v', '--volume', metavar='DIR', default='/', help='''location of the volume from which to create the bundle (default: /)'''), Arg('-P', '--partition', choices=('mbr', 'gpt', 'none'), help='''the type of partition table to create (default: attempt to guess based on the existing disk)'''), Arg('-S', '--script', metavar='FILE', help='''location of a script to run immediately before bundling. It will receive the volume's mount point as its only argument.'''), MutuallyExclusiveArgList( Arg('--fstab', metavar='FILE', help='''location of an fstab(5) file to copy into the bundled image'''), Arg('--generate-fstab', action='store_true', help='''automatically generate an fstab(5) file for the bundled image''')), Arg('--grub-config', metavar='FILE', help='''location of a GRUB 1 configuration file to copy to /boot/grub/menu.lst on the bundled image'''), # Bundle-related stuff Arg('-k', '--privatekey', metavar='FILE', help='''file containing your private key to sign the bundle's manifest with. This private key will also be required to unbundle the image in the future.'''), Arg('-c', '--cert', metavar='FILE', help='file containing your X.509 certificate'), Arg('--ec2cert', metavar='FILE', help='''file containing the cloud's X.509 certificate'''), Arg('-u', '--user', metavar='ACCOUNT', help='your account ID'), Arg('--kernel', metavar='IMAGE', help='''ID of the kernel image to associate with this machine image'''), Arg('--ramdisk', metavar='IMAGE', help='''ID of the ramdisk image to associate with this machine image'''), Arg('-B', '--block-device-mappings', metavar='VIRTUAL1=DEVICE1,VIRTUAL2=DEVICE2,...', type=manifest_block_device_mappings, help='''block device mapping scheme with which to launch instances of this machine image'''), Arg('--productcodes', metavar='CODE1,CODE2,...', type=delimited_list(','), default=[], help='comma-separated list of product codes for the image'), Arg('--part-size', type=filesize, default=10485760, help=argparse.SUPPRESS), Arg('--enc-key', type=(lambda s: int(s, 16)), help=argparse.SUPPRESS), Arg('--enc-iv', type=(lambda s: int(s, 16)), help=argparse.SUPPRESS)] def configure(self): if os.geteuid() != 0: raise RuntimeError('must be superuser') if not self.args.get('arch'): raise ArgumentError('argument -r/--arch is required') # Farm all the bundle arg validation out to BundleImage self.__build_bundle_command('/dev/null', image_size=1) root_device = _get_root_device() if self.args.get('inherit'): self.__populate_args_from_metadata() if not self.args.get('partition'): self.args['partition'] = _get_partition_table_type(root_device) if not self.args['partition']: self.log.warn('could not determine the partition table type ' 'for root device %s', root_device) raise ArgumentError( 'could not determine the type of partition table to use; ' 'specify one with -P/--partition'.format(root_device)) self.log.info('discovered partition table type %s', self.args['partition']) if not self.args.get('fstab') and not self.args.get('generate_fstab'): self.args['fstab'] = '/etc/fstab' def main(self): if self.args.get('destination'): destdir = self.args['destination'] else: destdir = euca2ools.util.mkdtemp_for_large_files(prefix='bundle-') image = os.path.join(destdir, self.args.get('prefix') or 'image') mountpoint = tempfile.mkdtemp(prefix='target-', dir=destdir) # Prepare the disk image device = self.__create_disk_image(image, self.args['size']) try: self.__create_and_mount_filesystem(device, mountpoint) try: # Copy files exclude_opts = self.__get_exclude_and_include_args() exclude_opts.extend(['--exclude', image, '--exclude', mountpoint]) self.__copy_to_target_dir(mountpoint, exclude_opts) self.__insert_fstab(mountpoint) self.__insert_grub_config(mountpoint) if self.args.get('script'): cmd = [self.args['script'], mountpoint] self.log.info("running user script ``%s''", _quote_cmd(cmd)) subprocess.check_call(cmd) except KeyboardInterrupt: self.log.info('received ^C; skipping to cleanup') msg = ('Cleaning up after ^C -- pressing ^C again will ' 'result in the need for manual device cleanup') print >> sys.stderr, msg raise # Cleanup finally: time.sleep(0.2) self.__unmount_filesystem(device) os.rmdir(mountpoint) finally: self.__detach_disk_image(image, device) bundle_cmd = self.__build_bundle_command(image) result = bundle_cmd.main() os.remove(image) return result def print_result(self, result): for manifest_filename in result[1]: print 'Wrote manifest', manifest_filename def __build_bundle_command(self, image_filename, image_size=None): bundle_args = ('prefix', 'destination', 'arch', 'privatekey', 'cert', 'ec2cert', 'user', 'kernel', 'ramdisk', 'block_device_mappings', 'productcodes', 'part_size', 'enc_key', 'enc_iv', 'show_progress') bundle_args_dict = dict((key, self.args.get(key)) for key in bundle_args) return BundleImage.from_other(self, image=image_filename, image_size=image_size, image_type='machine', **bundle_args_dict) # INSTANCE METADATA # def __read_metadata_value(self, path): self.log.debug("reading metadata service value '%s'", path) url = 'http://169.254.169.254/2012-01-12/meta-data/' + path response = requests.get(url, timeout=1) if response.status_code == 200: return response.text return None def __read_metadata_list(self, path): value = self.__read_metadata_value(path) if value: return [line.rstrip('/') for line in value.splitlines() if line] return [] def __read_metadata_dict(self, path): metadata = {} if not path.endswith('/'): path += '/' keys = self.__read_metadata_list(path) for key in keys: if key: metadata[key] = self.__read_metadata_value(path + key) return metadata def __populate_args_from_metadata(self): """ Populate missing/empty values in self.args using info obtained from the metadata service. """ try: if not self.args.get('kernel'): self.args['kernel'] = self.__read_metadata_value('kernel-id') self.log.info('inherited kernel: %s', self.args['kernel']) if not self.args.get('ramdisk'): self.args['ramdisk'] = self.__read_metadata_value('ramdisk-id') self.log.info('inherited ramdisk: %s', self.args['ramdisk']) if not self.args.get('productcodes'): self.args['productcodes'] = self.__read_metadata_list( 'product-codes') if self.args['productcodes']: self.log.info('inherited product codes: %s', ','.join(self.args['productcodes'])) if not self.args.get('block_device_mappings'): self.args['block_device_mappings'] = {} for key, val in (self.__read_metadata_dict( 'block-device-mapping') or {}).iteritems(): if not key.startswith('ebs'): self.args['block_device_mappings'][key] = val for key, val in self.args['block_device_mappings'].iteritems(): self.log.info('inherited block device mapping: %s=%s', key, val) except requests.exceptions.Timeout: raise ClientError('metadata service is absent or unresponsive; ' 'use --no-inherit to proceed without it') # DISK MANAGEMENT # def __create_disk_image(self, image, size_in_mb): subprocess.check_call(['dd', 'if=/dev/zero', 'of={0}'.format(image), 'bs=1M', 'count=1', 'seek={0}'.format(int(size_in_mb) - 1)]) if self.args['partition'] == 'mbr': # Why use sfdisk when we can use parted? :-) parted_script = ( b'unit s', b'mklabel msdos', b'mkpart primary 64 -1s', b'set 1 boot on', b'print', b'quit') subprocess.check_call(['parted', '-s', image, '--', ' '.join(parted_script)]) elif self.args['partition'] == 'gpt': # type 0xef02 == BIOS boot (we'll put it at the end of the list) subprocess.check_call( ['sgdisk', '--new', '128:1M:+1M', '--typecode', '128:ef02', '--change-name', '128:BIOS Boot', image]) # type 0x8300 == Linux filesystem data subprocess.check_call( ['sgdisk', '--largest-new=1', '--typecode', '1:8300', '--change-name', '1:Image', image]) subprocess.check_call(['sgdisk', '--print', image]) mapped = self.__map_disk_image(image) assert os.path.exists(mapped) return mapped def __map_disk_image(self, image): if self.args['partition'] in ('mbr', 'gpt'): # Create /dev/mapper/loopXpY and return that. # We could do this with losetup -Pf as well, but that isn't # available on RHEL 6. self.log.debug('mapping partitioned image %s', image) kpartx = subprocess.Popen(['kpartx', '-s', '-v', '-a', image], stdout=subprocess.PIPE) try: for line in kpartx.stdout.readlines(): line_split = line.split() if line_split[:2] == ['add', 'map']: device = line_split[2] if device.endswith('p1'): return '/dev/mapper/{0}'.format(device) self.log.error('failed to get usable map output from kpartx') raise RuntimeError('device mapping failed') finally: # Make sure the process exits kpartx.communicate() else: # No partition table self.log.debug('mapping unpartitioned image %s', image) losetup = subprocess.Popen(['losetup', '-f', image, '--show'], stdout=subprocess.PIPE) loopdev, _ = losetup.communicate() return loopdev.strip() def __create_and_mount_filesystem(self, device, mountpoint): root_device = _get_root_device() fsinfo = _get_filesystem_info(root_device) self.log.info('creating filesystem on %s using metadata from %s: %s', device, root_device, fsinfo) fs_cmds = [['mkfs', '-t', fsinfo['type']]] if fsinfo.get('label'): fs_cmds[0].extend(['-L', fsinfo['label']]) elif fsinfo['type'] in ('ext2', 'ext3', 'ext4'): if fsinfo.get('uuid'): fs_cmds[0].extend(['-U', fsinfo['uuid']]) # Time-based checking doesn't make much sense for cloud images fs_cmds.append(['tune2fs', '-i', '0']) elif fsinfo['type'] == 'jfs': if fsinfo.get('uuid'): fs_cmds.append(['jfs_tune', '-U', fsinfo['uuid']]) elif fsinfo['type'] == 'xfs': if fsinfo.get('uuid'): fs_cmds.append(['xfs_admin', '-U', fsinfo['uuid']]) for fs_cmd in fs_cmds: fs_cmd.append(device) self.log.info("formatting with ``%s''", _quote_cmd(fs_cmd)) subprocess.check_call(fs_cmd) self.log.info('mounting %s filesystem %s at %s', fsinfo['type'], device, mountpoint) subprocess.check_call(['mount', '-t', fsinfo['type'], device, mountpoint]) def __unmount_filesystem(self, device): self.log.info('unmounting %s', device) subprocess.check_call(['sync']) time.sleep(0.2) subprocess.check_call(['umount', device]) def __detach_disk_image(self, image, device): if self.args['partition'] in ('mbr', 'gpt'): self.log.debug('unmapping partitioned image %s', image) cmd = ['kpartx', '-s', '-d', image] else: self.log.debug('unmapping unpartitioned device %s', device) cmd = ['losetup', '-d', device] subprocess.check_call(cmd) # FILE MANAGEMENT # def __get_exclude_and_include_args(self): args = [] for exclude in self.args.get('exclude') or []: args.extend(['--exclude', exclude]) for include in self.args.get('include') or []: args.extend(['--include', include]) # Exclude remote filesystems if not self.args.get('all'): for device, mountpoint, fstype in _get_all_mounts(): if fstype not in ALLOWED_FILESYSTEM_TYPES: self.log.debug('excluding %s filesystem %s at %s', fstype, device, mountpoint) args.extend(['--exclude', os.path.join(mountpoint, '**')]) # Add pre-defined exclusions if not self.args.get('no_filter') and os.path.isfile(EXCLUDES_FILE): self.log.debug('adding path exclusions from %s', EXCLUDES_FILE) args.extend(['--exclude-from', EXCLUDES_FILE]) return args def __copy_to_target_dir(self, dest, exclude_opts): source = self.args.get('volume') or '/' if not source.endswith('/'): source += '/' if not dest.endswith('/'): dest += '/' rsync_opts = ['-rHlpogDtS'] if self.args.get('show_progress'): rsync = subprocess.Popen(['rsync', '--version'], stdout=subprocess.PIPE) out, _ = rsync.communicate() rsync_version = (out.partition('version ')[2] or '\0').split()[0] if rsync_version >= '3.1.0': # Use the new summarizing version rsync_opts.append('--info=progress2') else: rsync_opts.append('--progress') else: rsync_opts.append('--quiet') cmd = ['rsync', '-X'] + rsync_opts + exclude_opts + [source, dest] self.log.info("copying files with ``%s''", _quote_cmd(cmd)) print 'Copying files...' rsync = subprocess.Popen(cmd) rsync.wait() if rsync.returncode == 1: # Try again without xattrs self.log.info('rsync exited with code %i; retrying without xattrs', rsync.returncode) print 'Retrying without extended attributes' cmd = ['rsync'] + rsync_opts + exclude_opts + [source, dest] rsync = subprocess.Popen(cmd) rsync.wait() if rsync.returncode not in (0, 23): self.log.error('rsync exited with code %i', rsync.returncode) raise subprocess.CalledProcessError(rsync.returncode, 'rsync') def __insert_fstab(self, mountpoint): fstab_filename = os.path.join(mountpoint, 'etc', 'fstab') if os.path.exists(fstab_filename): fstab_bak = fstab_filename + '.bak' self.log.debug('backing up original fstab file as %s', fstab_bak) _copy_with_xattrs(fstab_filename, fstab_bak) if self.args.get('generate_fstab'): # This isn't really a template, but if the need arises we # can add something of that sort later. self.log.info('generating fstab file from %s', self.args['fstab']) _copy_with_xattrs(FSTAB_TEMPLATE_FILE, fstab_filename) elif self.args.get('fstab'): self.log.info('using fstab file %s', self.args['fstab']) _copy_with_xattrs(self.args['fstab'], fstab_filename) def __insert_grub_config(self, mountpoint): if self.args.get('grub_config'): grub_filename = os.path.join(mountpoint, 'boot', 'grub', 'menu.lst') if os.path.exists(grub_filename): grub_back = grub_filename + '.bak' self.log.debug('backing up original grub1 config file as %s', grub_back) _copy_with_xattrs(grub_filename, grub_back) self.log.info('using grub1 config file %s', self.args['grub_config']) _copy_with_xattrs(self.args['grub_config'], grub_filename) def _get_all_mounts(): # This implementation is Linux-specific # We first load everything into a dict based on mount points so we # can return only the last filesystem to be mounted in each # location. This is important for / on Linux, where a rootfs # volume has a real filesystem mounted on top of it, because # returning both of them will cause / to get excluded due to its # filesystem type. filesystems_dict = {} with open('/proc/mounts') as mounts: for line in mounts: device, mountpoint, fstype, _ = line.split(None, 3) filesystems_dict[mountpoint] = (device, fstype) filesystems_list = [] for mountpoint, (device, fstype) in filesystems_dict.iteritems(): filesystems_list.append((device, mountpoint, fstype)) return filesystems_list def _get_filesystem_info(device): blkid = subprocess.Popen(['blkid', '-o', 'export', device], stdout=subprocess.PIPE) fsinfo = {} for line in blkid.stdout: key, _, val = line.strip().partition('=') if key == 'LABEL': fsinfo['label'] = val elif key == 'TYPE': fsinfo['type'] = val elif key == 'UUID': fsinfo['uuid'] = val blkid.wait() if blkid.returncode != 0: raise subprocess.CalledProcessError(blkid.returncode, 'blkid') return fsinfo def _get_partition_table_type(device, debug=False): if device[-1] in '0123456789': if device[-2] == 'd': # /dev/sda1, /dev/xvda1, /dev/vda1, etc. device = device[:-1] elif device[-2] == 'p': # /dev/loop0p1, /dev/sr0p1, etc. device = device[:-2] if debug: stderr_dest = subprocess.PIPE else: stderr_dest = None parted = subprocess.Popen(['parted', '-m', '-s', device, 'print'], stdout=subprocess.PIPE, stderr=stderr_dest) stdout, _ = parted.communicate() for line in stdout: if line.startswith('/dev/'): # /dev/sda:500GB:scsi:512:512:msdos:ATA WDC WD5003ABYX-1; line_bits = line.split(':') if line_bits[5] == 'msdos': return 'mbr' elif line_bits[5] == 'gpt': return 'gpt' else: return 'none' def _get_root_device(): for device, mountpoint, _ in _get_all_mounts(): if mountpoint == '/' and os.path.exists(device): root_device = device # Do not skip the rest of the mount points. Another # / filesystem, such as a btrfs subvolume, may be # mounted on top of that. return root_device def _quote_cmd(cmd): return ' '.join(pipes.quote(arg) for arg in cmd) def _copy_with_xattrs(source, dest): """ shutil.copy2 doesn't preserve xattrs until python 3.3, so here we attempt to leverage the cp command to do it for us. """ try: subprocess.check_call(['cp', '-a', source, dest]) except subprocess.CalledProcessError: shutil.copy2(source, dest) euca2ools-3.3.1/euca2ools/commands/bundle/deletebundle.py000066400000000000000000000067101267461563000234040ustar00rootroot00000000000000# Copyright 2009-2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from requestbuilder.exceptions import ServerError from euca2ools.commands.bundle.mixins import BundleDownloadingMixin from euca2ools.commands.s3 import S3Request from euca2ools.commands.s3.deletebucket import DeleteBucket from euca2ools.commands.s3.deleteobject import DeleteObject class DeleteBundle(S3Request, BundleDownloadingMixin): DESCRIPTION = 'Delete a previously-uploaded bundle' ARGS = [Arg('--clear', dest='clear', action='store_true', help='attempt to delete the bucket as well')] def main(self): try: manifest = self.fetch_manifest(self.service) except ServerError as err: if err.status_code == 404 and self.args.get('clear'): try: # We are supposed to try to delete the bucket even # if the manifest isn't there. If it works, the # bundle is also gone and we can safely return. # # https://eucalyptus.atlassian.net/browse/TOOLS-379 self.__delete_bucket() return except ServerError: # If the bucket wasn't empty then we'll go back to # complaining about the missing manifest. self.log.error( 'failed to delete bucket %s after a failed ' 'attempt to fetch the bundle manifest', bucket=self.args['bucket'].split('/')[0], exc_info=True) raise for _, part_s3path in self.map_bundle_parts_to_s3paths(manifest): req = DeleteObject.from_other(self, path=part_s3path) req.main() manifest_s3path = self.get_manifest_s3path() if manifest_s3path: req = DeleteObject.from_other(self, path=manifest_s3path) req.main() if self.args.get('clear'): self.__delete_bucket() def __delete_bucket(self): req = DeleteBucket.from_other(self, bucket=self.args['bucket'].split('/')[0]) req.main() euca2ools-3.3.1/euca2ools/commands/bundle/downloadandunbundle.py000066400000000000000000000136151267461563000250010ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import multiprocessing import os.path import sys from requestbuilder import Arg from requestbuilder.exceptions import ArgumentError from requestbuilder.mixins import FileTransferProgressBarMixin from euca2ools.bundle.util import open_pipe_fileobjs from euca2ools.bundle.util import waitpid_in_thread from euca2ools.commands.bundle.downloadbundle import DownloadBundle from euca2ools.commands.bundle.mixins import BundleDownloadingMixin from euca2ools.commands.bundle.unbundlestream import UnbundleStream from euca2ools.commands.s3 import S3Request class DownloadAndUnbundle(S3Request, FileTransferProgressBarMixin, BundleDownloadingMixin): DESCRIPTION = ('Download and unbundle a bundled image from the cloud\n\n ' 'The key used to unbundle the image must match a ' 'certificate that was used to bundle it.') ARGS = [Arg('-d', '--destination', dest='dest', metavar='(FILE | DIR)', default=".", help='''where to place the unbundled image (default: current directory)'''), Arg('-k', '--privatekey', help='''file containing the private key to decrypt the bundle with. This must match a certificate used when bundling the image.''')] # noinspection PyExceptionInherit def configure(self): S3Request.configure(self) # The private key could be the user's or the cloud's. In the config # this is a user-level option. if not self.args.get('privatekey'): config_privatekey = self.config.get_user_option('private-key') if self.args.get('userregion'): self.args['privatekey'] = config_privatekey elif 'EC2_PRIVATE_KEY' in os.environ: self.args['privatekey'] = os.getenv('EC2_PRIVATE_KEY') elif config_privatekey: self.args['privatekey'] = config_privatekey else: raise ArgumentError( 'missing private key; please supply one with -k') self.args['privatekey'] = os.path.expanduser(os.path.expandvars( self.args['privatekey'])) if not os.path.exists(self.args['privatekey']): raise ArgumentError("private key file '{0}' does not exist" .format(self.args['privatekey'])) if not os.path.isfile(self.args['privatekey']): raise ArgumentError("private key file '{0}' is not a file" .format(self.args['privatekey'])) self.log.debug('private key: %s', self.args['privatekey']) def __open_dest(self, manifest): if self.args['dest'] == '-': self.args['dest'] = sys.stdout self.args['show_progress'] = False elif isinstance(self.args['dest'], basestring): if os.path.isdir(self.args['dest']): image_filename = os.path.join(self.args['dest'], manifest.image_name) else: image_filename = self.args['dest'] self.args['dest'] = open(image_filename, 'w') return image_filename # Otherwise we assume it's a file object def main(self): manifest = self.fetch_manifest( self.service, privkey_filename=self.args['privatekey']) download_out_r, download_out_w = open_pipe_fileobjs() try: self.__create_download_pipeline(download_out_w) finally: download_out_w.close() image_filename = self.__open_dest(manifest) unbundlestream = UnbundleStream.from_other( self, source=download_out_r, dest=self.args['dest'], enc_key=manifest.enc_key, enc_iv=manifest.enc_iv, image_size=manifest.image_size, sha1_digest=manifest.image_digest, show_progress=self.args.get('show_progress', False)) unbundlestream.main() return image_filename def __create_download_pipeline(self, outfile): downloadbundle = DownloadBundle.from_other( self, dest=outfile, bucket=self.args['bucket'], manifest=self.args.get('manifest'), local_manifest=self.args.get('local_manifest'), show_progress=False) downloadbundle_p = multiprocessing.Process(target=downloadbundle.main) downloadbundle_p.start() waitpid_in_thread(downloadbundle_p.pid) outfile.close() def print_result(self, image_filename): if (image_filename and self.args['dest'].fileno() != sys.stdout.fileno()): print 'Wrote', image_filename euca2ools-3.3.1/euca2ools/commands/bundle/downloadbundle.py000066400000000000000000000071071267461563000237520ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os.path import sys from requestbuilder import Arg from requestbuilder.exceptions import ArgumentError from requestbuilder.mixins import FileTransferProgressBarMixin from euca2ools.commands.bundle.mixins import BundleDownloadingMixin from euca2ools.commands.s3 import S3Request class DownloadBundle(S3Request, FileTransferProgressBarMixin, BundleDownloadingMixin): DESCRIPTION = ('Download a bundled image from the cloud\n\nYou must run ' 'euca-unbundle-image on the bundle you download to obtain ' 'the original image.') ARGS = [Arg('-d', '--directory', dest='dest', metavar='DIR', default=".", help='''the directory to download the bundle parts to, or "-" to write the bundled image to stdout''')] # noinspection PyExceptionInherit def configure(self): S3Request.configure(self) if self.args['dest'] == '-': self.args['dest'] = sys.stdout self.args['show_progress'] = False elif isinstance(self.args['dest'], basestring): if not os.path.exists(self.args['dest']): raise ArgumentError( "argument -d/--directory: '{0}' does not exist" .format(self.args['dest'])) if not os.path.isdir(self.args['dest']): raise ArgumentError( "argument -d/--directory: '{0}' is not a directory" .format(self.args['dest'])) # Otherwise we assume it is a file object # noinspection PyExceptionInherit def main(self): manifest = self.fetch_manifest(self.service) if isinstance(self.args['dest'], basestring): manifest_dest = self.download_bundle_to_dir( manifest, self.args['dest'], self.service) else: manifest_dest = self.download_bundle_to_fileobj( manifest, self.args['dest'], self.service) return manifest, manifest_dest def print_result(self, result): _, manifest_filename = result if (manifest_filename and (isinstance(self.args['dest'], basestring) or self.args['dest'].fileno() != sys.stdout.fileno())): print 'Wrote manifest', manifest_filename euca2ools-3.3.1/euca2ools/commands/bundle/installimage.py000066400000000000000000000143351267461563000234230ustar00rootroot00000000000000# Copyright 2014-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from __future__ import division import argparse from requestbuilder import Arg from requestbuilder.auth.aws import QueryHmacV2Auth from requestbuilder.mixins import FileTransferProgressBarMixin, TabifyingMixin from euca2ools.commands.ec2 import EC2 from euca2ools.commands.ec2.registerimage import RegisterImage from euca2ools.commands.bootstrap import BootstrapRequest from euca2ools.commands.s3 import S3Request from euca2ools.commands.bundle.bundleanduploadimage import BundleAndUploadImage from euca2ools.commands.bundle.mixins import BundleCreatingMixin, \ BundleUploadingMixin class InstallImage(S3Request, BundleCreatingMixin, BundleUploadingMixin, FileTransferProgressBarMixin, TabifyingMixin): DESCRIPTION = 'Bundle, upload and register an image into the cloud' ARGS = [Arg('-n', '--name', route_to=None, required=True, help='name of the new image (required)'), Arg('--description', route_to=None, help='description of the new image'), Arg('--max-pending-parts', type=int, default=2, help='''pause the bundling process when more than this number of parts are waiting to be uploaded (default: 2)'''), Arg('--virtualization-type', route_to=None, choices=('paravirtual', 'hvm'), help='virtualization type for the new image'), Arg('--platform', route_to=None, metavar='windows', choices=('windows',), help="[Privileged] the new image's platform (windows)"), Arg('--ec2-url', route_to=None, help='compute service endpoint URL'), Arg('--ec2-auth', route_to=None, help=argparse.SUPPRESS), Arg('--ec2-service', route_to=None, help=argparse.SUPPRESS)] def configure(self): # This goes before configure because -S's absence causes # self.auth.configure to blow up. With an upload policy that # is undesirable. self.configure_bundle_upload_auth() S3Request.configure(self) if not self.args.get("ec2_service"): self.args["ec2_service"] = EC2.from_other( self.service, url=self.args.get('ec2_url')) if not self.args.get("ec2_auth"): self.args["ec2_auth"] = QueryHmacV2Auth.from_other(self.auth) if self.args.get('url') and not self.args.get('ec2_url'): self.log.warn('-U/--url used without --ec2-url; communication ' 'with different regions may result') if self.args.get('ec2_url') and not self.args.get('url'): self.log.warn('--ec2-url used without -U/--url; communication ' 'with different regions may result') # Set up access to bootstrap in case we need auto cert fetching. try: self.args['bootstrap_service'] = \ BootstrapRequest.SERVICE_CLASS.from_other( self.service, url=self.args.get('bootstrap_url')) self.args['bootstrap_auth'] = \ BootstrapRequest.AUTH_CLASS.from_other(self.auth) except: self.log.debug('bootstrap setup failed; auto cert fetching ' 'will be unavailable', exc_info=True) self.configure_bundle_creds() self.configure_bundle_properties() self.configure_bundle_output() def main(self): req = BundleAndUploadImage.from_other( self, image=self.args["image"], arch=self.args["arch"], bucket=self.args["bucket"], prefix=self.args.get("prefix"), destination=self.args.get("destination"), kernel=self.args.get("kernel"), ramdisk=self.args.get("ramdisk"), image_type=self.args.get("image_type"), image_size=self.args.get("image_size"), cert=self.args.get("cert"), privatekey=self.args.get("privatekey"), ec2cert=self.args.get("ec2cert"), user=self.args.get("user"), productcodes=self.args.get("productcodes"), enc_iv=self.args.get("enc_iv"), enc_key=self.args.get("enc_key"), max_pending_parts=self.args.get("max_pending_parts"), part_size=self.args.get("part_size"), batch=self.args.get("batch"), show_progress=self.args.get("show_progress")) result_bundle = req.main() image_location = result_bundle['manifests'][0]["key"] req = RegisterImage.from_other( self, service=self.args["ec2_service"], auth=self.args["ec2_auth"], Name=self.args["name"], Architecture=self.args["arch"], ImageLocation=image_location, Description=self.args.get("description"), VirtualizationType=self.args.get("virtualization_type"), Platform=self.args.get("platform")) result_register = req.main() return result_register def print_result(self, result): print self.tabify(('IMAGE', result.get('imageId'))) euca2ools-3.3.1/euca2ools/commands/bundle/mixins.py000066400000000000000000000710511267461563000222570ustar00rootroot00000000000000# Copyright 2013-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse import atexit import base64 import os.path import random import subprocess import sys import tempfile from requestbuilder import Arg, MutuallyExclusiveArgList from requestbuilder.exceptions import ArgumentError import euca2ools.bundle.manifest import euca2ools.bundle.util from euca2ools.commands.argtypes import (b64encoded_file_contents, delimited_list, filesize, manifest_block_device_mappings) from euca2ools.commands.bootstrap.describeservicecertificates import \ DescribeServiceCertificates from euca2ools.commands.s3.checkbucket import CheckBucket from euca2ools.commands.s3.createbucket import CreateBucket from euca2ools.commands.s3.getobject import GetObject from euca2ools.commands.s3.postobject import PostObject from euca2ools.commands.s3.putobject import PutObject from euca2ools.exceptions import AWSError EC2_BUNDLE_SIZE_LIMIT = 10 * 2 ** 30 # 10 GiB class BundleCreatingMixin(object): ARGS = [Arg('-i', '--image', metavar='FILE', required=True, help='file containing the image to bundle (required)'), Arg('-p', '--prefix', help='''the file name prefix to give the bundle's files (required when bundling stdin; otherwise defaults to the image's file name)'''), Arg('-d', '--destination', metavar='DIR', help='''location to place the bundle's files (default: dir named by TMPDIR, TEMP, or TMP environment variables, or otherwise /var/tmp)'''), Arg('-r', '--arch', required=True, choices=('i386', 'x86_64', 'armhf', 'ppc', 'ppc64', 'ppc64le'), help="the image's architecture (required)"), # User- and cloud-specific stuff Arg('-k', '--privatekey', metavar='FILE', help='''file containing your private key to sign the bundle's manifest with. If one is not available the bundle will not be signed.'''), Arg('-c', '--cert', metavar='FILE', help='''file containing your X.509 certificate. If one is not available it will not be possible to unbundle the bundle without cloud administrator assistance.'''), Arg('--ec2cert', metavar='FILE', help='''file containing the cloud's X.509 certificate. If one is not available locally it must be available from the bootstrap service.'''), Arg('-u', '--user', metavar='ACCOUNT', help='your account ID'), Arg('--kernel', metavar='IMAGE', help='''ID of the kernel image to associate with this machine image'''), Arg('--ramdisk', metavar='IMAGE', help='''ID of the ramdisk image to associate with this machine image'''), Arg('--bootstrap-url', route_to=None, help='''[Eucalyptus only] bootstrap service endpoint URL (used for obtaining --ec2cert automatically'''), Arg('--bootstrap-service', route_to=None, help=argparse.SUPPRESS), Arg('--bootstrap-auth', route_to=None, help=argparse.SUPPRESS), # Obscurities Arg('-B', '--block-device-mappings', metavar='VIRTUAL1=DEVICE1,VIRTUAL2=DEVICE2,...', type=manifest_block_device_mappings, help='''block device mapping scheme with which to launch instances of this machine image'''), Arg('--productcodes', metavar='CODE1,CODE2,...', type=delimited_list(','), default=[], help='comma-separated list of product codes for the image'), Arg('--image-type', choices=('machine', 'kernel', 'ramdisk'), default='machine', help=argparse.SUPPRESS), # Stuff needed to fill out TarInfo when input comes from stdin. # # We technically could ask for a lot more, but most of it is # unnecessary since owners/modes/etc will be ignored at unbundling # time anyway. # # When bundling stdin we interpret --prefix as the image's file # name. Arg('--image-size', type=filesize, help='''the image's size (required when bundling stdin)'''), # Overrides for debugging and other entertaining uses Arg('--part-size', type=filesize, default=10485760, # 10M help=argparse.SUPPRESS), Arg('--enc-key', type=(lambda s: int(s, 16)), help=argparse.SUPPRESS), # a hex string Arg('--enc-iv', type=(lambda s: int(s, 16)), help=argparse.SUPPRESS), # a hex string # Noop, for compatibility Arg('--batch', action='store_true', help=argparse.SUPPRESS)] # CONFIG METHODS # def configure_bundle_creds(self): # User's account ID (user-level) if not self.args.get('user'): config_val = self.config.get_user_option('account-id') if 'EC2_USER_ID' in os.environ: self.log.debug('using account ID from environment') self.args['user'] = os.getenv('EC2_USER_ID') elif config_val: self.log.debug('using account ID from configuration') self.args['user'] = config_val if self.args.get('user'): self.args['user'] = self.args['user'].replace('-', '') if not self.args.get('user'): raise ArgumentError( 'missing account ID; please supply one with --user') self.log.debug('account ID: %s', self.args['user']) # User's X.509 certificate (user-level in config) if not self.args.get('cert'): config_val = self.config.get_user_option('certificate') if 'EC2_CERT' in os.environ: self.log.debug('using certificate from environment') self.args['cert'] = os.getenv('EC2_CERT') elif 'EUCA_CERT' in os.environ: # used by the NC self.log.debug('using certificate from environment') self.args['cert'] = os.getenv('EUCA_CERT') elif config_val: self.log.debug('using certificate from configuration') self.args['cert'] = config_val if self.args.get('cert'): self.args['cert'] = os.path.expanduser(os.path.expandvars( self.args['cert'])) _assert_is_file(self.args['cert'], 'user certificate') self.log.debug('certificate: %s', self.args.get('cert')) # User's private key (user-level in config) if not self.args.get('privatekey'): config_val = self.config.get_user_option('private-key') if 'EC2_PRIVATE_KEY' in os.environ: self.log.debug('using private key from environment') self.args['privatekey'] = os.getenv('EC2_PRIVATE_KEY') if 'EUCA_PRIVATE_KEY' in os.environ: # used by the NC self.log.debug('using private key from environment') self.args['privatekey'] = os.getenv('EUCA_PRIVATE_KEY') elif config_val: self.log.debug('using private key from configuration') self.args['privatekey'] = config_val if self.args.get('privatekey'): self.args['privatekey'] = os.path.expanduser(os.path.expandvars( self.args['privatekey'])) _assert_is_file(self.args['privatekey'], 'private key') self.log.debug('private key: %s', self.args.get('privatekey')) # Cloud's X.509 cert (region-level in config) if not self.args.get('ec2cert'): config_val = self.config.get_region_option('certificate') if 'EUCALYPTUS_CERT' in os.environ: # This has no EC2 equivalent since they just bundle their cert. self.log.debug('using cloud certificate from environment') self.args['ec2cert'] = os.getenv('EUCALYPTUS_CERT') elif config_val: self.log.debug('using cloud certificate from configuration') self.args['ec2cert'] = config_val elif (self.args.get('bootstrap_service') and self.args.get('bootstrap_auth')): # Sending requests during configure() can be precarious. # Pay close attention to ordering to ensure all # of this request's dependencies have been fulfilled. fetched_cert = self.__get_bundle_certificate( self.args['bootstrap_service'], self.args['bootstrap_auth']) if fetched_cert: self.log.debug('using cloud certificate from ' 'bootstrap service') self.args['ec2cert'] = fetched_cert if self.args.get('ec2cert'): self.args['ec2cert'] = os.path.expanduser(os.path.expandvars( self.args['ec2cert'])) _assert_is_file(self.args['ec2cert'], 'cloud certificate') if not self.args.get('ec2cert'): raise ArgumentError( 'missing cloud certificate; please supply one with ' '--ec2cert or use --bootstrap-url to fetch one automatically') self.log.debug('cloud certificate: %s', self.args['ec2cert']) def configure_bundle_output(self): if (self.args.get('destination') and os.path.exists(self.args['destination']) and not os.path.isdir(self.args['destination'])): raise ArgumentError("argument -d/--destination: '{0}' is not a " "directory".format(self.args['destination'])) if self.args['image'] == '-': self.args['image'] = os.fdopen(os.dup(sys.stdin.fileno())) if not self.args.get('prefix'): raise ArgumentError( 'argument --prefix is required when bundling stdin') if not self.args.get('image_size'): raise ArgumentError( 'argument --image-size is required when bundling stdin') elif isinstance(self.args['image'], basestring): if not self.args.get('prefix'): self.args['prefix'] = os.path.basename(self.args['image']) if not self.args.get('image_size'): self.args['image_size'] = euca2ools.util.get_filesize( self.args['image']) self.args['image'] = open(self.args['image']) else: # Assume it is already a file object if not self.args.get('prefix'): raise ArgumentError('argument --prefix is required when ' 'bundling a file object') if not self.args.get('image_size'): raise ArgumentError('argument --image-size is required when ' 'bundling a file object') if self.args['image_size'] > EC2_BUNDLE_SIZE_LIMIT: self.log.warn( 'image is incompatible with EC2 due to its size (%i > %i)', self.args['image_size'], EC2_BUNDLE_SIZE_LIMIT) def configure_bundle_properties(self): if self.args.get('kernel') == 'true': self.args['image_type'] = 'kernel' if self.args.get('ramdisk') == 'true': self.args['image_type'] = 'ramdisk' if self.args['image_type'] == 'kernel': if self.args.get('kernel') and self.args['kernel'] != 'true': raise ArgumentError("argument --kernel: not compatible with " "image type 'kernel'") if self.args.get('ramdisk'): raise ArgumentError("argument --ramdisk: not compatible with " "image type 'kernel'") if self.args.get('block_device_mappings'): raise ArgumentError("argument -B/--block-device-mappings: not " "compatible with image type 'kernel'") if self.args['image_type'] == 'ramdisk': if self.args.get('kernel'): raise ArgumentError("argument --kernel: not compatible with " "image type 'ramdisk'") if self.args.get('ramdisk') and self.args['ramdisk'] != 'true': raise ArgumentError("argument --ramdisk: not compatible with " "image type 'ramdisk'") if self.args.get('block_device_mappings'): raise ArgumentError("argument -B/--block-device-mappings: not " "compatible with image type 'ramdisk'") def generate_encryption_keys(self): srand = random.SystemRandom() if self.args.get('enc_key'): self.log.info('using preexisting encryption key') enc_key_i = self.args['enc_key'] else: enc_key_i = srand.getrandbits(128) if self.args.get('enc_iv'): self.log.info('using preexisting encryption IV') enc_iv_i = self.args['enc_iv'] else: enc_iv_i = srand.getrandbits(128) self.args['enc_key'] = '{0:0>32x}'.format(enc_key_i) self.args['enc_iv'] = '{0:0>32x}'.format(enc_iv_i) def __get_bundle_certificate(self, bootstrap_service, bootstrap_auth): self.log.info('attempting to obtain cloud certificate from ' 'bootstrap service') req = DescribeServiceCertificates( config=self.config, loglevel=self.log.level, service=bootstrap_service, auth=bootstrap_auth, Format='pem', FingerprintDigest='SHA-256') response = req.main() for cert in response.get('serviceCertificates') or []: if (cert.get('certificateUsage') == 'image-bundling' and cert.get('serviceType') == 'compute'): cert_file = tempfile.NamedTemporaryFile(delete=False) cert_file.write(cert['certificate']) cert_file.file.flush() self.args['ec2cert'] = cert_file.name atexit.register(os.remove, cert_file.name) return cert_file.name # MANIFEST GENERATION METHODS # def build_manifest(self, digest, partinfo): manifest = euca2ools.bundle.manifest.BundleManifest( loglevel=self.log.level) manifest.image_arch = self.args['arch'] manifest.kernel_id = self.args.get('kernel') manifest.ramdisk_id = self.args.get('ramdisk') if self.args.get('block_device_mappings'): manifest.block_device_mappings.update( self.args['block_device_mappings']) if self.args.get('productcodes'): manifest.product_codes.extend(self.args['productcodes']) manifest.image_name = self.args['prefix'] manifest.account_id = self.args['user'] manifest.image_type = self.args['image_type'] manifest.image_digest = digest manifest.image_digest_algorithm = 'SHA1' # shouldn't be hardcoded here manifest.image_size = self.args['image_size'] manifest.bundled_image_size = sum(part.size for part in partinfo) manifest.enc_key = self.args['enc_key'] manifest.enc_iv = self.args['enc_iv'] manifest.enc_algorithm = 'AES-128-CBC' # shouldn't be hardcoded here manifest.image_parts = partinfo return manifest def dump_manifest_to_file(self, manifest, filename, pretty_print=False): with open(filename, 'w') as manifest_file: manifest_file.write(self.dump_manifest_to_str( manifest, pretty_print=pretty_print)) def dump_manifest_to_str(self, manifest, pretty_print=False): return manifest.dump_to_str(self.args['privatekey'], self.args['cert'], self.args['ec2cert'], pretty_print=pretty_print) class BundleUploadingMixin(object): ARGS = [Arg('-b', '--bucket', metavar='BUCKET[/PREFIX]', required=True, help='bucket to upload the bundle to (required)'), Arg('--acl', default='aws-exec-read', choices=('public-read', 'aws-exec-read', 'ec2-bundle-read'), help='''canned ACL policy to apply to the bundle (default: aws-exec-read)'''), MutuallyExclusiveArgList( Arg('--upload-policy', dest='upload_policy', metavar='POLICY', type=base64.b64encode, help='upload policy to use for authorization'), Arg('--upload-policy-file', dest='upload_policy', metavar='FILE', type=b64encoded_file_contents, help='''file containing an upload policy to use for authorization''')), Arg('--upload-policy-signature', metavar='SIGNATURE', help='''signature for the upload policy (required when an 'upload policy is used)'''), Arg('--location', help='''location constraint of the destination bucket (default: inferred from s3-location-constraint in configuration, or otherwise none)'''), Arg('--retry', dest='retries', action='store_const', const=5, default=0, help='retry failed uploads up to 5 times')] def configure_bundle_upload_auth(self): if self.args.get('upload_policy'): if not self.args.get('key_id'): raise ArgumentError('-I/--access-key-id is required when ' 'using an upload policy') if not self.args.get('upload_policy_signature'): raise ArgumentError('--upload-policy-signature is required ' 'when using an upload policy') self.auth = None def get_bundle_key_prefix(self): (bucket, _, prefix) = self.args['bucket'].partition('/') if prefix and not prefix.endswith('/'): prefix += '/' return bucket + '/' + prefix def ensure_dest_bucket_exists(self): if self.args.get('upload_policy'): # We won't have creds to sign our own requests self.log.info('using an upload policy; not verifying bucket ' 'existence') return bucket = self.args['bucket'].split('/', 1)[0] try: req = CheckBucket.from_other(self, bucket=bucket) req.main() except AWSError as err: if err.status_code == 404: # No such bucket self.log.info("creating bucket '%s'", bucket) req = CreateBucket.from_other( self, bucket=bucket, location=self.args.get('location')) req.main() else: raise # At this point we know we can at least see the bucket, but it's still # possible that we can't write to it with the desired key names. So # many policies are in play here that it isn't worth trying to be # proactive about it. def upload_bundle_file(self, source, dest, show_progress=False, **putobj_kwargs): if self.args.get('upload_policy'): if show_progress: # PostObject does not yet support show_progress print source, 'uploading...' if self.args.get('security_token'): postobj_kwargs = \ {'x-amz-security-token': self.args['security_token']} else: postobj_kwargs = {} postobj_kwargs.update(putobj_kwargs) req = PostObject.from_other( self, source=source, dest=dest, acl=self.args.get('acl') or 'aws-exec-read', Policy=self.args['upload_policy'], Signature=self.args['upload_policy_signature'], AWSAccessKeyId=self.args['key_id'], **postobj_kwargs) else: req = PutObject.from_other( self, source=source, dest=dest, acl=self.args.get('acl') or 'aws-exec-read', retries=self.args.get('retries') or 0, show_progress=show_progress, **putobj_kwargs) req.main() def upload_bundle_parts(self, partinfo_in_mpconn, key_prefix, partinfo_out_mpconn=None, part_write_sem=None, **putobj_kwargs): try: while True: part = partinfo_in_mpconn.recv() dest = key_prefix + os.path.basename(part.filename) self.upload_bundle_file(part.filename, dest, **putobj_kwargs) if part_write_sem is not None: # Allow something that's waiting for the upload to finish # to continue part_write_sem.release() if partinfo_out_mpconn is not None: partinfo_out_mpconn.send(part) except EOFError: return finally: partinfo_in_mpconn.close() if partinfo_out_mpconn is not None: partinfo_out_mpconn.close() class BundleDownloadingMixin(object): # When fetching the manifest from the server there are two ways to get # its path: # -m: BUCKET[/PREFIX]/MANIFEST # -p: BUCKET[/PREFIX]/PREFIX.manifest.xml (the PREFIXes are different) # # In all cases, after we obtain the manifest (whether it is local or not) # we choose key names for parts based on the file names in the manifest: # BUCKET[/PREFIX]/PART ARGS = [Arg('-b', '--bucket', metavar='BUCKET[/PREFIX]', required=True, route_to=None, help='''the bucket that contains the bundle, with an optional path prefix (required)'''), MutuallyExclusiveArgList( Arg('-m', '--manifest', dest='manifest', route_to=None, help='''the manifest's complete file name, not including any path that may be specified using -b'''), Arg('-p', '--prefix', dest='manifest', route_to=None, type=(lambda x: x + '.manifest.xml'), help='''the portion of the manifest's file name that precedes ".manifest.xml"'''), Arg('--local-manifest', dest='local_manifest', metavar='FILE', route_to=None, help='''use a manifest on disk and ignore any that appear on the server''')) .required()] def fetch_manifest(self, s3_service, privkey_filename=None): if self.args.get('local_manifest'): _assert_is_file(self.args['local_manifest'], 'manifest') return euca2ools.bundle.manifest.BundleManifest.read_from_file( self.args['local_manifest'], privkey_filename=privkey_filename) # It's on the server, so do things the hard way manifest_s3path = self.get_manifest_s3path() with tempfile.TemporaryFile() as manifest_tempfile: self.log.info('reading manifest from %s', manifest_s3path) req = GetObject.from_other( self, service=s3_service, source=manifest_s3path, dest=manifest_tempfile) try: req.main() except AWSError as err: if err.status_code == 404: self.log.debug('failed to fetch manifest', exc_info=True) raise ValueError("manifest '{0}' does not exist on the " "server".format(manifest_s3path)) raise manifest_tempfile.flush() manifest_tempfile.seek(0) return euca2ools.bundle.manifest.BundleManifest.read_from_fileobj( manifest_tempfile, privkey_filename=privkey_filename) def get_manifest_s3path(self): if self.args.get('manifest'): return '/'.join((self.args['bucket'], self.args['manifest'])) else: # With a local manifest we can't divine the manifest's key name is return None def download_bundle_to_dir(self, manifest, dest_dir, s3_service): parts = self.map_bundle_parts_to_s3paths(manifest) for part, part_s3path in parts: part.filename = os.path.join(dest_dir, os.path.basename(part_s3path)) self.log.info('downloading part %s to %s', part_s3path, part.filename) req = GetObject.from_other( self, service=s3_service, source=part_s3path, dest=part.filename, show_progress=self.args.get('show_progress', False)) response = req.main() self.__check_part_sha1(part, part_s3path, response) manifest_s3path = self.get_manifest_s3path() if manifest_s3path: # Can't download a manifest if we're using a local one manifest_dest = os.path.join(dest_dir, os.path.basename(manifest_s3path)) self.log.info('downloading manifest %s to %s', manifest_s3path, manifest_dest) req = GetObject.from_other( self, service=s3_service, source=manifest_s3path, dest=manifest_dest, show_progress=self.args.get('show_progress', False)) req.main() return manifest_dest return None def download_bundle_to_fileobj(self, manifest, fileobj, s3_service): # We can skip downloading the manifest since we're just writing all # parts to a file object. parts = self.map_bundle_parts_to_s3paths(manifest) for part, part_s3path in parts: self.log.info('downloading part %s', part_s3path) req = GetObject.from_other( self, service=s3_service, source=part_s3path, dest=fileobj, show_progress=self.args.get('show_progress', False)) response = req.main() self.__check_part_sha1(part, part_s3path, response) def map_bundle_parts_to_s3paths(self, manifest): parts = [] for part in manifest.image_parts: parts.append((part, '/'.join((self.args['bucket'], part.filename)))) return parts def __check_part_sha1(self, part, part_s3path, response): if response[part_s3path]['sha1'] != part.hexdigest: self.log.error('rejecting download due to manifest SHA1 ' 'mismatch (expected: %s, actual: %s)', part.hexdigest, response[part_s3path]['sha1']) raise RuntimeError('downloaded file {0} appears to be corrupt ' '(expected SHA1: {0}, actual: {1}' .format(part.hexdigest, response[part_s3path]['sha1'])) def _assert_is_file(filename, filetype): if not os.path.exists(filename): raise ArgumentError("{0} file '{1}' does not exist" .format(filetype, filename)) if not os.path.isfile(filename): raise ArgumentError("{0} file '{1}' is not a file" .format(filetype, filename)) def _get_cert_fingerprint(cert_content): popen = subprocess.Popen(('openssl', 'x509', '-fingerprint', '-noout'), stdin=subprocess.PIPE, stdout=subprocess.PIPE) return popen.communicate(cert_content)[0].strip() euca2ools-3.3.1/euca2ools/commands/bundle/unbundle.py000066400000000000000000000200021267461563000225520ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import hashlib import os import multiprocessing from requestbuilder import Arg from requestbuilder.command import BaseCommand from requestbuilder.exceptions import ArgumentError from requestbuilder.mixins import (FileTransferProgressBarMixin, RegionConfigurableMixin) from euca2ools.commands import Euca2ools import euca2ools.bundle.pipes from euca2ools.bundle.manifest import BundleManifest from euca2ools.bundle.util import (close_all_fds, open_pipe_fileobjs, waitpid_in_thread) from euca2ools.commands.bundle.unbundlestream import UnbundleStream class Unbundle(BaseCommand, FileTransferProgressBarMixin, RegionConfigurableMixin): DESCRIPTION = ('Recreate an image from its bundled parts\n\nThe key used ' 'to unbundle the image must match a certificate that was ' 'used to bundle it.') SUITE = Euca2ools ARGS = [Arg('-m', '--manifest', type=open, metavar='FILE', required=True, help="the bundle's manifest file (required)"), Arg('-s', '--source', metavar='DIR', default='.', help='''directory containing the bundled image parts (default: current directory)'''), Arg('-d', '--destination', metavar='DIR', default='.', help='''where to place the unbundled image (default: current directory)'''), Arg('-k', '--privatekey', metavar='FILE', help='''file containing the private key to decrypt the bundle with. This must match a certificate used when bundling the image.''')] # noinspection PyExceptionInherit def configure(self): BaseCommand.configure(self) self.update_config_view() # The private key could be the user's or the cloud's. In the config # this is a user-level option. if not self.args.get('privatekey'): config_privatekey = self.config.get_user_option('private-key') if self.args.get('userregion'): self.args['privatekey'] = config_privatekey elif 'EC2_PRIVATE_KEY' in os.environ: self.args['privatekey'] = os.getenv('EC2_PRIVATE_KEY') elif config_privatekey: self.args['privatekey'] = config_privatekey else: raise ArgumentError( 'missing private key; please supply one with -k') self.args['privatekey'] = os.path.expanduser(os.path.expandvars( self.args['privatekey'])) if not os.path.exists(self.args['privatekey']): raise ArgumentError("private key file '{0}' does not exist" .format(self.args['privatekey'])) if not os.path.isfile(self.args['privatekey']): raise ArgumentError("private key file '{0}' is not a file" .format(self.args['privatekey'])) self.log.debug('private key: %s', self.args['privatekey']) if not os.path.exists(self.args.get('source', '.')): raise ArgumentError("argument -s/--source: directory '{0}' does " "not exist".format(self.args['source'])) if not os.path.isdir(self.args.get('source', '.')): raise ArgumentError("argument -s/--source: '{0}' is not a " "directory".format(self.args['source'])) if not os.path.exists(self.args.get('destination', '.')): raise ArgumentError("argument -d/--destination: directory '{0}' " "does not exist" .format(self.args['destination'])) if not os.path.isdir(self.args.get('destination', '.')): raise ArgumentError("argument -d/--destination: '{0}' is not a " "directory".format(self.args['destination'])) def __read_bundle_parts(self, manifest, outfile): close_all_fds(except_fds=[outfile]) for part in manifest.image_parts: self.log.debug("opening part '%s' for reading", part.filename) digest = hashlib.sha1() with open(part.filename) as part_file: while True: chunk = part_file.read(euca2ools.BUFSIZE) if chunk: digest.update(chunk) outfile.write(chunk) outfile.flush() else: break actual_digest = int(digest.hexdigest(), 16) expected_digest = int(part.hexdigest, 16) if actual_digest != expected_digest: self.log.error('rejecting unbundle due to part SHA1 ' 'mismatch (expected: %x, actual: %x)', expected_digest, actual_digest) raise RuntimeError( "bundle part '{0}' appears to be corrupt (expected " "SHA1: {1:x}, actual: {2:x}" .format(part.filename, expected_digest, actual_digest)) def main(self): manifest = BundleManifest.read_from_fileobj( self.args['manifest'], privkey_filename=self.args['privatekey']) for part in manifest.image_parts: part_path = os.path.join(self.args['source'], part.filename) while part_path.startswith('./'): part_path = part_path[2:] if os.path.exists(part_path): part.filename = part_path else: raise RuntimeError( "bundle part '{0}' does not exist; you may need to use " "-s to specify where to find the bundle's parts" .format(part_path)) part_reader_out_r, part_reader_out_w = open_pipe_fileobjs() part_reader = multiprocessing.Process( target=self.__read_bundle_parts, args=(manifest, part_reader_out_w)) part_reader.start() part_reader_out_w.close() waitpid_in_thread(part_reader.pid) image_filename = os.path.join(self.args['destination'], manifest.image_name) with open(image_filename, 'w') as image: unbundlestream = UnbundleStream.from_other( self, source=part_reader_out_r, dest=image, enc_key=manifest.enc_key, enc_iv=manifest.enc_iv, image_size=manifest.image_size, sha1_digest=manifest.image_digest, show_progress=self.args.get('show_progress', False)) unbundlestream.main() return image_filename def print_result(self, image_filename): print 'Wrote', image_filename euca2ools-3.3.1/euca2ools/commands/bundle/unbundlestream.py000066400000000000000000000127131267461563000240000ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os.path import sys from requestbuilder import Arg from requestbuilder.command import BaseCommand from requestbuilder.mixins import (FileTransferProgressBarMixin, RegionConfigurableMixin) from euca2ools.bundle.pipes.core import (create_unbundle_pipeline, copy_with_progressbar) from euca2ools.bundle.util import open_pipe_fileobjs from euca2ools.commands import Euca2ools from euca2ools.commands.argtypes import filesize class UnbundleStream(BaseCommand, FileTransferProgressBarMixin, RegionConfigurableMixin): DESCRIPTION = ('Recreate an image solely from its combined bundled parts ' 'without using a manifest\n\nUsually one would want to use ' 'euca-unbundle instead.') SUITE = Euca2ools ARGS = [Arg('-i', dest='source', metavar='FILE', help='file to read the bundle from (default: stdin)'), Arg('-o', dest='dest', metavar='FILE', help='file to write the unbundled image to (default: stdout)'), Arg('--enc-key', metavar='HEX', required=True, help='''the symmetric key used to encrypt the bundle (required)'''), Arg('--enc-iv', metavar='HEX', required=True, help='''the initialization vector used to encrypt the bundle (required)'''), Arg('--image-size', metavar='BYTES', type=filesize, help='verify the unbundled image is a certain size'), Arg('--sha1-digest', metavar='HEX', help='''verify the image's contents against a SHA1 digest from its manifest file''')] # noinspection PyExceptionInherit def configure(self): BaseCommand.configure(self) self.update_config_view() if not self.args.get('source') or self.args['source'] == '-': # We dup stdin because the multiprocessing lib closes it self.args['source'] = os.fdopen(os.dup(sys.stdin.fileno())) elif isinstance(self.args['source'], basestring): self.args['source'] = open(self.args['source']) # Otherwise, assume it is already a file object if not self.args.get('dest') or self.args['dest'] == '-': self.args['dest'] = sys.stdout self.args['show_progress'] = False elif isinstance(self.args['dest'], basestring): self.args['dest'] = open(self.args['dest'], 'w') # Otherwise, assume it is already a file object def main(self): pbar = self.get_progressbar(maxval=self.args.get('image_size')) unbundle_out_r, unbundle_out_w = open_pipe_fileobjs() unbundle_sha1_r = create_unbundle_pipeline( self.args['source'], unbundle_out_w, self.args['enc_key'], self.args['enc_iv'], debug=self.debug) unbundle_out_w.close() actual_size = copy_with_progressbar(unbundle_out_r, self.args['dest'], progressbar=pbar) actual_sha1 = int(unbundle_sha1_r.recv(), 16) unbundle_sha1_r.close() expected_sha1 = int(self.args.get('sha1_digest') or '0', 16) expected_size = self.args.get('image_size') if expected_sha1 and expected_sha1 != actual_sha1: self.log.error('rejecting unbundle due to SHA1 mismatch ' '(expected SHA1: %x, actual: %x)', expected_sha1, actual_sha1) raise RuntimeError('bundle appears to be corrupt (expected SHA1: ' '{0:x}, actual: {1:x})' .format(expected_sha1, actual_sha1)) expected_size = self.args.get('image_size') if expected_size and expected_size != actual_size: self.log.error('rejecting unbundle due to size mismatch ' '(expected: %i, actual: %i)', expected_size, actual_size) raise RuntimeError('bundle appears to be corrupt (expected size: ' '{0}, actual: {1})' .format(expected_size, actual_size)) return actual_sha1, actual_size euca2ools-3.3.1/euca2ools/commands/bundle/uploadbundle.py000066400000000000000000000120541267461563000234240ustar00rootroot00000000000000# Copyright (c) 2009-2016 Hewlett Packard Enterprise Development LP # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse import multiprocessing import os.path from requestbuilder import Arg from requestbuilder.mixins import FileTransferProgressBarMixin from euca2ools.bundle.manifest import BundleManifest from euca2ools.commands.bundle.mixins import BundleUploadingMixin from euca2ools.commands.s3 import S3Request from euca2ools.commands.s3.putobject import PutObject class UploadBundle(S3Request, BundleUploadingMixin, FileTransferProgressBarMixin): DESCRIPTION = 'Upload a bundle prepared by euca-bundle-image to the cloud' ARGS = [Arg('-m', '--manifest', metavar='FILE', required=True, help='manifest for the bundle to upload (required)'), Arg('-d', '--directory', metavar='DIR', help='''directory that contains the bundle parts (default: directory that contains the manifest)'''), # TODO: make this work Arg('--part', metavar='INT', type=int, default=0, help=argparse.SUPPRESS), Arg('--skipmanifest', action='store_true', help='do not upload the manifest')] def configure(self): # This goes before configure because -S's absence causes # self.auth.configure to blow up. With an upload policy that # is undesirable. self.configure_bundle_upload_auth() S3Request.configure(self) def main(self): key_prefix = self.get_bundle_key_prefix() self.ensure_dest_bucket_exists() manifest = BundleManifest.read_from_file(self.args['manifest']) part_dir = (self.args.get('directory') or os.path.dirname(self.args['manifest'])) for part in manifest.image_parts: part.filename = os.path.join(part_dir, part.filename) if not os.path.isfile(part.filename): raise ValueError("no such part: '{0}'".format(part.filename)) # manifest -> upload part_out_r, part_out_w = multiprocessing.Pipe(duplex=False) part_gen = multiprocessing.Process(target=_generate_bundle_parts, args=(manifest, part_out_w)) part_gen.start() part_out_w.close() # Drive the upload process by feeding in part info self.upload_bundle_parts(part_out_r, key_prefix, show_progress=self.args.get('show_progress')) part_gen.join() # (conditionally) upload the manifest if not self.args.get('skipmanifest'): manifest_dest = (key_prefix + os.path.basename(self.args['manifest'])) req = PutObject.from_other( self, source=self.args['manifest'], dest=manifest_dest, acl=self.args.get('acl') or 'aws-exec-read', retries=self.args.get('retries') or 0) req.main() else: manifest_dest = None return {'parts': tuple({'filename': part.filename, 'key': (key_prefix + os.path.basename(part.filename))} for part in manifest.image_parts), 'manifests': ({'filename': self.args['manifest'], 'key': manifest_dest},)} def print_result(self, result): if self.debug: for part in result['parts']: print 'Uploaded', part['key'] if result['manifests'][0]['key'] is not None: print 'Uploaded', result['manifests'][0]['key'] def _generate_bundle_parts(manifest, out_mpconn): try: for part in manifest.image_parts: assert os.path.isfile(part.filename) out_mpconn.send(part) finally: out_mpconn.close() euca2ools-3.3.1/euca2ools/commands/cloudformation/000077500000000000000000000000001267461563000221465ustar00rootroot00000000000000euca2ools-3.3.1/euca2ools/commands/cloudformation/__init__.py000066400000000000000000000077301267461563000242660ustar00rootroot00000000000000# Copyright 2014-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg import requestbuilder.auth.aws from requestbuilder.mixins import TabifyingMixin from requestbuilder.request import AWSQueryRequest import requestbuilder.service from euca2ools.commands import Euca2ools from euca2ools.exceptions import AWSError from euca2ools.util import strip_response_metadata, add_fake_region_name class CloudFormation(requestbuilder.service.BaseService): NAME = 'cloudformation' DESCRIPTION = 'Deployment templating service' API_VERSION = '2010-05-15' REGION_ENVVAR = 'AWS_DEFAULT_REGION' URL_ENVVAR = 'AWS_CLOUDFORMATION_URL' ARGS = [Arg('-U', '--url', metavar='URL', help='deployment templating service endpoint URL')] def configure(self): requestbuilder.service.BaseService.configure(self) add_fake_region_name(self) def handle_http_error(self, response): raise AWSError(response) class CloudFormationRequest(AWSQueryRequest, TabifyingMixin): SUITE = Euca2ools SERVICE_CLASS = CloudFormation AUTH_CLASS = requestbuilder.auth.aws.HmacV4Auth METHOD = 'POST' def parse_response(self, response): response_dict = AWSQueryRequest.parse_response(self, response) return strip_response_metadata(response_dict) def print_stack(self, stack): stack_bits = ['STACK'] for attr in ('StackName', 'StackStatus', 'StackStatusReason', 'Description', 'CreationTime'): stack_bits.append(stack.get(attr)) print self.tabify(stack_bits) def print_parameter(self, param): param_bits = ['PARAMETER'] for attr in ('ParameterKey', 'UsePreviousValue', 'ParameterValue'): param_bits.append(param.get(attr)) print self.tabify(param_bits) def print_output(self, output): output_bits = ['OUTPUT'] for attr in ('OutputKey', 'OutputValue'): output_bits.append(output.get(attr)) print self.tabify(output_bits) def print_stack_event(self, event): event_bits = ['EVENT'] for attr in ('StackName', 'EventId', 'ResourceType', 'LogicalResourceId', 'PhysicalResourceId', 'Timestamp', 'ResourceStatus', 'ResourceStatusReason'): event_bits.append(event.get(attr)) print self.tabify(event_bits) def print_resource(self, resource): resource_bits = ['RESOURCE'] for attr in ('LogicalResourceId', 'PhysicalResourceId', 'ResourceType', 'LastUpdatedTimestamp', 'ResourceStatus', 'ResourceStatusReason'): resource_bits.append(resource.get(attr)) print self.tabify(resource_bits) euca2ools-3.3.1/euca2ools/commands/cloudformation/argtypes.py000066400000000000000000000042231267461563000243570ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse import requestbuilder def parameter_list(param_list_str): """ Parse a semicolon-delimited list of tag definitions from the command line. Return a list with dicts that contain each parameter's key and value as follows: - 'key=value': {'ParameterKey': key, 'ParameterValue': value} """ params = [] for param_str in param_list_str.split(';'): errmsg = 'parameter "{0}" must have form KEY=VALUE'.format(param_str) if '=' in param_str: key, val = param_str.split('=', 1) if not key: raise argparse.ArgumentTypeError(errmsg) if not val: val = requestbuilder.EMPTY params.append({'ParameterKey': key, 'ParameterValue': val}) else: raise argparse.ArgumentTypeError(errmsg) return params euca2ools-3.3.1/euca2ools/commands/cloudformation/cancelupdatestack.py000066400000000000000000000032501267461563000261760ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.cloudformation import CloudFormationRequest class CancelUpdateStack(CloudFormationRequest): DESCRIPTION = 'Cancel a stack update that is currently running' LIST_TAGS = ['Stacks'] ARGS = [Arg('StackName', metavar='STACK', help='name of the stack to stop updating (required)')] euca2ools-3.3.1/euca2ools/commands/cloudformation/createstack.py000066400000000000000000000074151267461563000250200ustar00rootroot00000000000000# Copyright (c) 2014-2016 Hewlett Packard Enterprise Development LP # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from requestbuilder import Arg, MutuallyExclusiveArgList from euca2ools.commands.argtypes import binary_tag_def, delimited_list from euca2ools.commands.cloudformation import CloudFormationRequest from euca2ools.commands.cloudformation.argtypes import parameter_list class CreateStack(CloudFormationRequest): DESCRIPTION = 'Create a new stack' ARGS = [Arg('StackName', metavar='STACK', help='name of the new stack (required)'), MutuallyExclusiveArgList( Arg('--template-file', dest='TemplateBody', metavar='FILE', type=open, help="file containing the new stack's JSON template"), Arg('--template-url', dest='TemplateURL', metavar='URL', help="URL pointing to the new stack's JSON template")) .required(), Arg('-d', '--disable-rollback', dest='DisableRollback', action='store_true', default=argparse.SUPPRESS, help='disable rollback on failure'), Arg('-n', '--notification-arns', dest='NotificationARNs.member', metavar='ARN[,...]', type=delimited_list(','), action='append', help='''SNS ARNs to publish stack actions to'''), Arg('--capabilities', dest='Capabilities.member', metavar='CAP[,...]', type=delimited_list(','), help='capabilities needed to create the stack'), Arg('-p', '--parameter', dest='param_sets', route_to=None, metavar='KEY=VALUE', type=parameter_list, action='append', help='''key and value of the parameters to use with the new stack's template, separated by an "=" character'''), Arg('-t', '--timeout', dest='TimeoutInMinutes', type=int, metavar='MINUTES', help='timeout for stack creation'), Arg('--tag', dest='Tags.member', metavar='KEY[=VALUE]', type=binary_tag_def, action='append', help='''key and optional value of the tag to create, separated by an "=" character. If no value is given the tag's value is set to an empty string.''')] def configure(self): CloudFormationRequest.configure(self) stack_params = sum(self.args.get('param_sets') or [], []) self.params['Parameters.member'] = stack_params def print_result(self, result): print result.get('StackId') euca2ools-3.3.1/euca2ools/commands/cloudformation/deletestack.py000066400000000000000000000033551267461563000250160ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from requestbuilder import Arg from euca2ools.commands.cloudformation import CloudFormationRequest class DeleteStack(CloudFormationRequest): DESCRIPTION = 'Delete a stack' ARGS = [Arg('StackName', metavar='STACK', help='name of the stack to delete (required)'), Arg('--force', action='store_true', route_to=None, help=argparse.SUPPRESS)] # for compatibility euca2ools-3.3.1/euca2ools/commands/cloudformation/describestackevents.py000066400000000000000000000034451267461563000265610ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.cloudformation import CloudFormationRequest class DescribeStackEvents(CloudFormationRequest): DESCRIPTION = 'Describe events that occurred in a stack' ARGS = [Arg('StackName', metavar='STACK', help='name of the stack to show events for (required)')] LIST_TAGS = ['StackEvents'] def print_result(self, result): for event in result['StackEvents']: self.print_stack_event(event) euca2ools-3.3.1/euca2ools/commands/cloudformation/describestackresource.py000066400000000000000000000036431267461563000271040ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.cloudformation import CloudFormationRequest class DescribeStackResource(CloudFormationRequest): DESCRIPTION = 'Describe a resource from a particular stack' ARGS = [Arg('StackName', metavar='STACK', help='name of the stack (required)'), Arg('-l', '--logical-resource-id', metavar='RESOURCE', dest='LogicalResourceId', required=True, help='logical ID of the resource to describe (required)')] def print_result(self, result): self.print_resource(result['StackResourceDetail']) euca2ools-3.3.1/euca2ools/commands/cloudformation/describestackresources.py000066400000000000000000000042621267461563000272650ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.cloudformation import CloudFormationRequest class DescribeStackResources(CloudFormationRequest): DESCRIPTION = 'List all of the resources in one or more stacks' ARGS = [Arg('-n', '--name', dest='StackName', metavar='STACK', help='limit results to a specific stack'), Arg('-l', '--logical-resource-id', metavar='RESOURCE', dest='LogicalResourceId', help='logical ID of the resource to describe (required)'), Arg('-p', '--physical-resource-id', metavar='RESOURCE', dest='PhysicalResourceId', help='physical ID of the resource to describe (required)')] LIST_TAGS = ['StackResources'] def print_result(self, result): for resource in result['StackResources']: self.print_resource(resource) euca2ools-3.3.1/euca2ools/commands/cloudformation/describestacks.py000066400000000000000000000044531267461563000255170ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.cloudformation import CloudFormationRequest class DescribeStacks(CloudFormationRequest): DESCRIPTION = 'Describe one or more stacks' ARGS = [Arg('StackName', metavar='STACK', nargs="?", help='limit results to a single stack'), Arg('--show-long', action='store_true', route_to=None, help="show all of the stacks' info")] LIST_TAGS = ['Outputs', 'Parameters', 'Stacks'] def print_result(self, result): for stack in result['Stacks']: self.print_stack(stack) if self.args['show_long']: print stack.get('StackId') print stack.get('NotificationARNs') if stack.get('Parameters'): for param in stack.get('Parameters'): self.print_parameter(param) if stack.get('Outputs'): for output in stack.get('Outputs'): self.print_output(output) euca2ools-3.3.1/euca2ools/commands/cloudformation/gettemplate.py000066400000000000000000000033731267461563000250410ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.cloudformation import CloudFormationRequest class GetTemplate(CloudFormationRequest): DESCRIPTION = "Show a stack's template" ARGS = [Arg('StackName', metavar='STACK', help='''name or ID of the stack (names cannot be used for deleted stacks) (required)''')] LIST_TAGS = ['Stacks'] def print_result(self, result): print result.get('TemplateBody') euca2ools-3.3.1/euca2ools/commands/cloudformation/liststackresources.py000066400000000000000000000034671267461563000264660ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.cloudformation import CloudFormationRequest class ListStackResources(CloudFormationRequest): DESCRIPTION = 'List all resources for a stack' ARGS = [Arg('StackName', metavar='STACK', help='name of the stack to list resources from (required)')] LIST_TAGS = ['StackResourceSummaries'] def print_result(self, result): for resource in result['StackResourceSummaries']: self.print_resource(resource) euca2ools-3.3.1/euca2ools/commands/cloudformation/liststacks.py000066400000000000000000000031641267461563000247100ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.cloudformation import CloudFormationRequest class ListStacks(CloudFormationRequest): DESCRIPTION = 'List all running stacks' LIST_TAGS = ['StackSummaries'] def print_result(self, result): for stack in result['StackSummaries']: self.print_stack(stack) euca2ools-3.3.1/euca2ools/commands/cloudformation/updatestack.py000066400000000000000000000067351267461563000250430ustar00rootroot00000000000000# Copyright (c) 2014-2016 Hewlett Packard Enterprise Development LP # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, EMPTY, MutuallyExclusiveArgList from euca2ools.commands.argtypes import binary_tag_def, delimited_list from euca2ools.commands.cloudformation import CloudFormationRequest from euca2ools.commands.cloudformation.argtypes import parameter_list class UpdateStack(CloudFormationRequest): DESCRIPTION = 'Update a stack with a new template' ARGS = [Arg('StackName', metavar='STACK', help='name of the stack to update (required)'), MutuallyExclusiveArgList( Arg('--template-file', dest='TemplateBody', metavar='FILE', type=open, help='file containing a new JSON template for the stack'), Arg('--template-url', dest='TemplateURL', metavar='URL', help='URL pointing to a new JSON template for the stack')) .required(), Arg('--capabilities', dest='Capabilities.member', metavar='CAP[,...]', type=delimited_list(','), help='capabilities needed to update the stack'), Arg('-p', '--parameter', dest='param_sets', route_to=None, metavar='KEY=VALUE', type=parameter_list, action='append', help='''key and value of the parameters to use with the stack's template, separated by an "=" character'''), MutuallyExclusiveArgList( Arg('--tag', dest='Tags.member', metavar='KEY[=VALUE]', type=binary_tag_def, action='append', help='''key and optional value of a tag to add, separated by an "=" character. If no value is given the tag's value is set to an empty string.'''), Arg('--delete-tags', dest='Tags', action='store_const', const=EMPTY, help='remove all tags associated with the stack'))] def configure(self): CloudFormationRequest.configure(self) stack_params = sum(self.args.get('param_sets') or [], []) self.params['Parameters.member'] = stack_params def print_result(self, result): print result.get('StackId') euca2ools-3.3.1/euca2ools/commands/cloudformation/validatetemplate.py000066400000000000000000000050311267461563000260440ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, MutuallyExclusiveArgList from euca2ools.commands.cloudformation import CloudFormationRequest class ValidateTemplate(CloudFormationRequest): DESCRIPTION = 'Validate a template' ARGS = [MutuallyExclusiveArgList( Arg('--template-file', dest='TemplateBody', metavar='FILE', type=open, help='file location containing JSON template'), Arg('--template-url', dest='TemplateURL', metavar='URL', help='S3 URL for JSON template')) .required()] LIST_TAGS = ['Parameters', 'CapabilitiesReason', 'Capabilities'] def print_result(self, result): print self.tabify(('DESCRIPTION', result.get('Description'))) for cap in result.get('Capabilities') or []: print self.tabify(('CAPABILITY', cap)) for reason in result.get('CapabilitiesReason') or []: print self.tabify(('CAPABILITYREASON', reason)) for param in result.get('Parameters') or []: print self.tabify(('PARAMETER', param.get('ParameterKey'), param.get('NoEcho'), param.get('DefaultValue'), param.get('Description'))) euca2ools-3.3.1/euca2ools/commands/ec2/000077500000000000000000000000001267461563000175725ustar00rootroot00000000000000euca2ools-3.3.1/euca2ools/commands/ec2/__init__.py000066400000000000000000000675001267461563000217130ustar00rootroot00000000000000# Copyright (c) 2009-2016 Hewlett Packard Enterprise Development LP # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse import io from operator import itemgetter import os.path import six import socket from string import Template import sys import lxml.etree from requestbuilder import Arg import requestbuilder.auth.aws from requestbuilder.exceptions import ArgumentError, AuthError, ClientError from requestbuilder.mixins import TabifyingMixin from requestbuilder.request import AWSQueryRequest from requestbuilder.service import BaseService import requests.exceptions from euca2ools.commands import Euca2ools from euca2ools.exceptions import AWSError from euca2ools.util import add_fake_region_name class EC2(BaseService): NAME = 'ec2' DESCRIPTION = 'Elastic compute cloud service' API_VERSION = '2014-06-15' REGION_ENVVAR = 'AWS_DEFAULT_REGION' URL_ENVVAR = 'EC2_URL' ARGS = [Arg('-U', '--url', metavar='URL', help='compute service endpoint URL')] def configure(self): requestbuilder.service.BaseService.configure(self) add_fake_region_name(self) def handle_http_error(self, response): raise AWSError(response) class EC2Request(AWSQueryRequest, TabifyingMixin): SUITE = Euca2ools SERVICE_CLASS = EC2 AUTH_CLASS = requestbuilder.auth.aws.HmacV4Auth METHOD = 'POST' def __init__(self, **kwargs): AWSQueryRequest.__init__(self, **kwargs) def print_resource_tag(self, resource_tag, resource_id): resource_type = RESOURCE_TYPE_MAP.lookup(resource_id) print self.tabify(['TAG', resource_type, resource_id, resource_tag.get('key'), resource_tag.get('value')]) def print_reservation(self, reservation): res_line = ['RESERVATION', reservation['reservationId'], reservation.get('ownerId')] # group.get('entry') is a workaround for a CLC bug group_ids = [group.get('groupName') or group.get('groupId') or group.get('entry') or '' for group in reservation['groupSet']] res_line.append(', '.join(group_ids)) print self.tabify(res_line) for instance in sorted(reservation.get('instancesSet') or [], key=itemgetter('launchTime')): self.print_instance(instance) def print_instance(self, instance): instance_line = ['INSTANCE'] for key in ['instanceId', 'imageId', 'dnsName', 'privateDnsName']: instance_line.append(instance.get(key)) instance_line.append(instance.get('instanceState', {}).get('name')) instance_line.append(instance.get('keyName')) instance_line.append(instance.get('amiLaunchIndex')) instance_line.append(','.join([code['productCode'] for code in instance.get('productCodes', [])])) instance_line.append(instance.get('instanceType')) instance_line.append(instance.get('launchTime')) instance_line.append(instance.get('placement', {}).get( 'availabilityZone')) instance_line.append(instance.get('kernelId')) instance_line.append(instance.get('ramdiskId')) instance_line.append(instance.get('platform')) if instance.get('monitoring'): instance_line.append('monitoring-' + instance['monitoring'].get('state')) else: # noinspection PyTypeChecker instance_line.append(None) instance_line.append(instance.get('ipAddress')) instance_line.append(instance.get('privateIpAddress')) instance_line.append(instance.get('vpcId')) instance_line.append(instance.get('subnetId')) instance_line.append(instance.get('rootDeviceType')) instance_line.append(instance.get('instanceLifecycle')) instance_line.append(instance.get('showInstanceRequestId')) # noinspection PyTypeChecker instance_line.append(None) # Should be the license, but where is it? instance_line.append(instance.get('placement', {}).get('groupName')) instance_line.append(instance.get('virtualizationType')) instance_line.append(instance.get('hypervisor')) instance_line.append(instance.get('clientToken')) instance_line.append(','.join([group['groupId'] for group in instance.get('groupSet', [])])) instance_line.append(instance.get('placement', {}).get('tenancy')) instance_line.append(instance.get('ebsOptimized')) instance_line.append(instance.get('iamInstanceProfile', {}).get('arn')) instance_line.append(instance.get('architecture')) print self.tabify(instance_line) for blockdev in instance.get('blockDeviceMapping', []): self.print_blockdevice(blockdev) for nic in instance.get('networkInterfaceSet', []): self.print_interface(nic) for tag in instance.get('tagSet', []): self.print_resource_tag(tag, instance.get('instanceId')) def print_blockdevice(self, blockdev): # Block devices belong to instances print self.tabify(('BLOCKDEVICE', blockdev.get('deviceName'), blockdev.get('ebs', {}).get('volumeId'), blockdev.get('ebs', {}).get('attachTime'), blockdev.get('ebs', {}).get('deleteOnTermination'), blockdev.get('ebs', {}).get('volumeType'), blockdev.get('ebs', {}).get('iops'))) def print_blockdevice_mapping(self, mapping): # Block device mappings belong to images if mapping.get('virtualName'): print self.tabify(('BLOCKDEVICEMAPPING', 'EPHEMERAL', mapping.get('deviceName'), mapping.get('virtualName'))) else: ebs = mapping.get('ebs') or {} print self.tabify(('BLOCKDEVICEMAPPING', 'EBS', mapping.get('deviceName'), ebs.get('snapshotId'), ebs.get('volumeSize'), ebs.get('deleteOnTermination'), ebs.get('volumeType'), ebs.get('iops'))) def print_attachment(self, attachment): print self.tabify(['ATTACHMENT', attachment.get('volumeId'), attachment.get('instanceId'), attachment.get('device'), attachment.get('status'), attachment.get('attachTime')]) def print_vpc(self, vpc): print self.tabify(('VPC', vpc.get('vpcId'), vpc.get('state'), vpc.get('cidrBlock'), vpc.get('dhcpOptionsId'), vpc.get('instanceTenancy'), vpc.get('isDefault'))) for tag in vpc.get('tagSet') or []: self.print_resource_tag(tag, vpc.get('vpcId')) def print_internet_gateway(self, igw): print self.tabify(('INTERNETGATEWAY', igw.get('internetGatewayId'))) for attachment in igw.get('attachmentSet') or []: print self.tabify(('ATTACHMENT', attachment.get('vpcId'), attachment.get('state'))) for tag in igw.get('tagSet') or []: self.print_resource_tag(tag, igw.get('internetGatewayId')) def print_peering_connection(self, pcx): status = pcx.get('status') or {} print self.tabify(('VPCPEERINGCONNECTION', pcx.get('vpcPeeringConnectionId'), pcx.get('expirationTime'), '{0}: {1}'.format(status.get('code'), status.get('message')))) requester = pcx.get('requesterVpcInfo') or {} print self.tabify(('REQUESTERVPCINFO', requester.get('vpcId'), requester.get('cidrBlock'), requester.get('ownerId'))) accepter = pcx.get('accepterVpcInfo') or {} print self.tabify(('ACCEPTERVPCINFO', accepter.get('vpcId'), accepter.get('cidrBlock'), accepter.get('ownerId'))) for tag in pcx.get('tagSet') or []: self.print_resource_tag(tag, pcx.get('vpcPeeringConnectionId')) def print_subnet(self, subnet): print self.tabify(('SUBNET', subnet.get('subnetId'), subnet.get('state'), subnet.get('vpcId'), subnet.get('cidrBlock'), subnet.get('availableIpAddressCount'), subnet.get('availabilityZone'), subnet.get('defaultForAz'), subnet.get('mapPublicIpOnLaunch'))) for tag in subnet.get('tagSet') or []: self.print_resource_tag(tag, subnet.get('subnetId')) def print_network_acl(self, acl): if acl.get('default').lower() == 'true': default = 'default' else: default = '' print self.tabify(('NETWORKACL', acl.get('networkAclId'), acl.get('vpcId'), default)) for entry in acl.get('entrySet') or []: if entry.get('egress').lower() == 'true': direction = 'egress' else: direction = 'ingress' protocol = entry.get('protocol') port_map = {-1: 'all', 1: 'icmp', 6: 'tcp', 17: 'udp', 132: 'sctp'} try: protocol = port_map.get(int(protocol), int(protocol)) except ValueError: pass if 'icmpTypeCode' in entry: from_port = entry.get('icmpTypeCode', {}).get('code') to_port = entry.get('icmpTypeCode', {}).get('type') else: from_port = entry.get('portRange', {}).get('from') to_port = entry.get('portRange', {}).get('to') print self.tabify(('ENTRY', direction, entry.get('ruleNumber'), entry.get('ruleAction'), entry.get('cidrBlock'), protocol, from_port, to_port)) for assoc in acl.get('associationSet') or []: print self.tabify(('ASSOCIATION', assoc.get('networkAclAssociationId'), assoc.get('subnetId'))) for tag in acl.get('tagSet') or []: self.print_resource_tag(tag, acl.get('networkAclId')) def print_route_table(self, table): print self.tabify(('ROUTETABLE', table.get('routeTableId'), table.get('vpcId'))) for route in table.get('routeSet') or []: target = (route.get('gatewayId') or route.get('instanceId') or route.get('networkInterfaceId') or route.get('vpcPeeringConnectionId')) print self.tabify(( 'ROUTE', target, route.get('state'), route.get('destinationCidrBlock'), route.get('origin'))) for vgw in table.get('propagatingVgwSet') or []: print self.tabify(('PROPAGATINGVGW', vgw.get('gatewayID'))) for assoc in table.get('associationSet') or []: if (assoc.get('main') or '').lower() == 'true': main = 'main' else: main = '' print self.tabify(('ASSOCIATION', assoc.get('routeTableAssociationId'), assoc.get('subnetId'), main)) for tag in table.get('tagSet') or []: self.print_resource_tag(tag, table.get('routeTableId')) def print_interface(self, nic): nic_info = [nic.get(attr) for attr in ( 'networkInterfaceId', 'subnetId', 'vpcId', 'ownerId', 'status', 'privateIpAddress', 'privateDnsName', 'sourceDestCheck')] print self.tabify(['NETWORKINTERFACE'] + nic_info) if nic.get('attachment'): attachment_info = [nic['attachment'].get(attr) for attr in ( 'attachmentId', 'deviceIndex', 'status', 'attachTime', 'deleteOnTermination')] print self.tabify(['ATTACHMENT'] + attachment_info) privaddresses = nic.get('privateIpAddressesSet', []) if nic.get('association'): association = nic['association'] # The EC2 tools apparently print private IP info in the # association even though that info doesn't appear there # in the response, so we have to look it up elsewhere. for privaddress in privaddresses: if (privaddress.get('association', {}).get('publicIp') == association.get('publicIp')): # Found a match break else: privaddress = None print self.tabify(('ASSOCIATION', association.get('publicIp'), association.get('ipOwnerId'), privaddress.get('privateIpAddress'))) for group in nic.get('groupSet', []): print self.tabify(('GROUP', group.get('groupId'), group.get('groupName'))) for privaddress in privaddresses: if privaddress.get('primary').lower() == 'true': primary = 'primary' else: primary = None print self.tabify(('PRIVATEIPADDRESS', privaddress.get('privateIpAddress'), privaddress.get('privateDnsName'), primary)) for tag in nic.get('tagSet') or []: self.print_resource_tag(tag, nic.get('networkInterfaceId')) def print_customer_gateway(self, cgw): print self.tabify(('CUSTOMERGATEWAY', cgw.get('customerGatewayId'), cgw.get('state'), cgw.get('type'), cgw.get('ipAddress'), cgw.get('bgpAsn'))) for tag in cgw.get('tagSet', []): self.print_resource_tag(tag, cgw.get('customerGatewayId')) def print_vpn_gateway(self, vgw): print self.tabify(('VPNGATEWAY', vgw.get('vpnGatewayId'), vgw.get('state'), vgw.get('availabilityZone'), vgw.get('type'))) for attachment in vgw.get('attachments'): print self.tabify(('VGWATTACHMENT', attachment.get('vpcId'), attachment.get('state'))) for tag in vgw.get('tagSet', []): self.print_resource_tag(tag, vgw.get('vpnGatewayId')) def print_vpn_connection(self, vpn, show_conn_info=False, stylesheet=None): print self.tabify(('VPNCONNECTION', vpn.get('vpnConnectionId'), vpn.get('type'), vpn.get('customerGatewayId'), vpn.get('vpnGatewayId'), vpn.get('state'))) if show_conn_info and vpn.get('customerGatewayConfiguration'): if stylesheet is None: print vpn.get('customerGatewayConfiguration') else: if (stylesheet.startswith('http://') or stylesheet.startswith('https://')): self.log.info('fetching connection info stylesheet from %s', stylesheet) response = requests.get(stylesheet) try: response.raise_for_status() except requests.exceptions.HTTPError as err: raise ClientError('failed to fetch stylesheet: {0}' .format(str(err))) xslt_root = lxml.etree.XML(response.text) else: if stylesheet.startswith('file://'): stylesheet = stylesheet[7:] self.log.info('using connection info stylesheet %s', stylesheet) with open(stylesheet) as stylesheet_file: xslt_root = lxml.etree.parse(stylesheet_file) transform = lxml.etree.XSLT(xslt_root) conn_info_root = lxml.etree.parse(io.BytesIO( vpn.get('customerGatewayConfiguration'))) print transform(conn_info_root) for tag in vpn.get('tagSet') or []: self.print_resource_tag(tag, vpn.get('vpnConnectionId')) def print_dhcp_options(self, dopt): print self.tabify(('DHCPOPTIONS', dopt.get('dhcpOptionsId'))) for option in dopt.get('dhcpConfigurationSet') or {}: values = [val_dict.get('value') for val_dict in option.get('valueSet')] print self.tabify(('OPTION', option.get('key'), ','.join(values))) for tag in dopt.get('tagSet', []): self.print_resource_tag(tag, dopt.get('dhcpOptionsId')) def print_volume(self, volume): vol_bits = ['VOLUME'] for attr in ('volumeId', 'size', 'snapshotId', 'availabilityZone', 'status', 'createTime'): vol_bits.append(volume.get(attr)) vol_bits.append(volume.get('volumeType') or 'standard') vol_bits.append(volume.get('iops')) print self.tabify(vol_bits) for attachment in volume.get('attachmentSet', []): self.print_attachment(attachment) for tag in volume.get('tagSet', []): self.print_resource_tag(tag, volume.get('volumeId')) def print_snapshot(self, snap): print self.tabify(['SNAPSHOT', snap.get('snapshotId'), snap.get('volumeId'), snap.get('status'), snap.get('startTime'), snap.get('progress'), snap.get('ownerId'), snap.get('volumeSize'), snap.get('description')]) for tag in snap.get('tagSet', []): self.print_resource_tag(tag, snap.get('snapshotId')) def print_bundle_task(self, task): bucket = task.get('storage', {}).get('S3', {}).get('bucket') prefix = task.get('storage', {}).get('S3', {}).get('prefix') if bucket and prefix: manifest = '{0}/{1}.manifest.xml'.format(bucket, prefix) else: manifest = None print self.tabify(['BUNDLE', task.get('bundleId'), task.get('instanceId'), bucket, prefix, task.get('startTime'), task.get('updateTime'), task.get('state'), task.get('progress'), manifest]) def print_conversion_task(self, task): task_bits = [] if task.get('importVolume'): task_bits.extend(('TaskType', 'IMPORTVOLUME')) if task.get('importInstance'): task_bits.extend(('TaskType', 'IMPORTINSTANCE')) if task.get('conversionTaskId'): task_bits.append('TaskId') task_bits.append(task.get('conversionTaskId')) if task.get('expirationTime'): task_bits.append('ExpirationTime') task_bits.append(task['expirationTime']) if task.get('state'): task_bits.append('Status') task_bits.append(task['state']) if task.get('statusMessage'): task_bits.append('StatusMessage') task_bits.append(task['statusMessage']) if task.get('importVolume'): print self.tabify(task_bits) self.__print_import_disk(task['importVolume']) if task.get('importInstance'): if task['importInstance'].get('instanceId'): task_bits.extend(('InstanceID', task['importInstance']['instanceId'])) print self.tabify(task_bits) for volume in task['importInstance'].get('volumes') or []: self.__print_import_disk(volume) def __print_import_disk(self, container): disk_bits = ['DISKIMAGE'] image = container.get('image') or {} volume = container.get('volume') or {} if image.get('format'): disk_bits.extend(('DiskImageFormat', image['format'])) if image.get('size'): disk_bits.extend(('DiskImageSize', image['size'])) if volume.get('id'): disk_bits.extend(('VolumeId', volume['id'])) if volume.get('size'): disk_bits.extend(('VolumeSize', volume['size'])) if container.get('availabilityZone'): disk_bits.extend(('AvailabilityZone', container['availabilityZone'])) if container.get('bytesConverted'): disk_bits.extend(('ApproximateBytesConverted', container['bytesConverted'])) if container.get('status'): # This is the status of the volume for an ImportInstance operation disk_bits.extend(('Status', container.get('status'))) if container.get('statusMessage'): disk_bits.extend(('StatusMessage', container.get('statusMessage'))) print self.tabify((disk_bits)) def process_port_cli_args(self): """ Security group and network ACL rule commands need to be able to to parse "-1:-1" before argparse can see it because of Python bug 9334, which causes argparse to treat it as a nonexistent option name and not an option value. This method wraps process_cli_args in such a way that values beginning with "-1" are preserved. """ saved_sys_argv = list(sys.argv) def parse_neg_one_value(opt_name): if opt_name in sys.argv: index = sys.argv.index(opt_name) if (index < len(sys.argv) - 1 and sys.argv[index + 1].startswith('-1')): opt_val = sys.argv[index + 1] del sys.argv[index:index + 2] return opt_val icmp_type_code = (parse_neg_one_value('-t') or parse_neg_one_value('--icmp-type-code')) port_range = (parse_neg_one_value('-p') or parse_neg_one_value('--port-range')) EC2Request.process_cli_args(self) if icmp_type_code: self.args['icmp_type_code'] = icmp_type_code if port_range: self.args['port_range'] = port_range sys.argv = saved_sys_argv class _ResourceTypeMap(object): _prefix_type_map = { 'eipalloc': 'allocation-id', 'bun': 'bundle', # technically a bundle *task* 'import': 'conversion-task', # this is a guess 'cgw': 'customer-gateway', 'dopt': 'dhcp-options', 'export': 'export-task', # this is a guess 'aki': 'image', 'ami': 'image', 'ari': 'image', 'eki': 'image', 'emi': 'image', 'eri': 'image', 'i': 'instance', 'igw': 'internet-gateway', 'acl': 'network-acl', 'eni': 'network-interface', 'xxx': 'reserved-instances', # reserved instance IDs are UUIDs 'rtb': 'route-table', 'sg': 'security-group', 'snap': 'snapshot', 'sir': 'spot-instances-request', 'subnet': 'subnet', 'vol': 'volume', 'vpc': 'vpc', 'pcx': 'vpc-peering-connection', 'vpn': 'vpn-connection', 'vgw': 'vpn-gateway'} def lookup(self, item): if not isinstance(item, basestring): raise TypeError('argument type must be str') for prefix in self._prefix_type_map: if item.startswith(prefix + '-'): return self._prefix_type_map[prefix] def __iter__(self): return iter(set(self._prefix_type_map.values())) RESOURCE_TYPE_MAP = _ResourceTypeMap() def parse_ports(protocol, port_range=None, icmp_type_code=None): # This function's error messages make assumptions about arguments' # names, but currently all of its callers agree on them. If that # changes then please fix this. from_port = None to_port = None if str(protocol).lower() in ('icmp', '1'): if port_range: raise ArgumentError('argument -p/--port-range: not compatible ' 'with protocol "{0}"'.format(protocol)) if not icmp_type_code: icmp_type_code = '-1:-1' types = icmp_type_code.split(':') if len(types) == 2: try: from_port = int(types[0]) to_port = int(types[1]) except ValueError: raise ArgumentError('argument -t/--icmp-type-code: value ' 'must have format "1:2"') else: raise ArgumentError('argument -t/--icmp-type-code: value ' 'must have format "1:2"') if from_port < -1 or to_port < -1: raise ArgumentError('argument -t/--icmp-type-code: ICMP type, ' 'code must be at least -1') elif str(protocol).lower() in ('tcp', '6', 'udp', '17'): if icmp_type_code: raise ArgumentError('argument -t/--icmp-type-code: not compatible ' 'with protocol "{0}"'.format(protocol)) if not port_range: raise ArgumentError('argument -p/--port-range is required ' 'for protocol "{0}"'.format(protocol)) if ':' in port_range: # Be extra helpful in the event of this common typo raise ArgumentError('argument -p/--port-range: multi-port ' 'range must be separated by "-", not ":"') from_port, to_port = _parse_port_range(port_range, protocol) if from_port < -1 or to_port < -1: raise ArgumentError('argument -p/--port-range: port number(s) ' 'must be at least -1') if from_port == -1: from_port = 1 if to_port == -1: to_port = 65535 # We allow other protocols through without parsing port numbers at all. return from_port, to_port def _parse_port_range(port_range, protocol): # Try for an integer try: return (int(port_range), int(port_range)) except ValueError: pass # Try for an integer range if port_range.count('-') == 1: ports = port_range.split('-') try: return (int(ports[0]), int(ports[1])) except ValueError: pass # Try for a service name if isinstance(protocol, six.string_types): try: # This is going to fail if protocol is a number. port = socket.getservbyname(port_range, protocol) return (port, port) except socket.error: pass # That's all, folks! raise ArgumentError("argument -p/--port-range: '{0}' is neither a port " "number, range of port numbers, nor a recognized " "service name".format(port_range)) euca2ools-3.3.1/euca2ools/commands/ec2/acceptvpcpeeringconnection.py000066400000000000000000000034241267461563000255510ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class AcceptVpcPeeringConnection(EC2Request): DESCRIPTION = 'Accept a request for a VPC peering connection' ARGS = [Arg('VpcPeeringConnectionId', metavar='PEERCON', help='the VPC peering connection to accept (required)')] LIST_TAGS = ['tagSet'] def print_result(self, result): self.print_peering_connection(result.get('vpcPeeringConnection') or {}) euca2ools-3.3.1/euca2ools/commands/ec2/allocateaddress.py000066400000000000000000000035671267461563000233110ustar00rootroot00000000000000# Copyright 2009-2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg class AllocateAddress(EC2Request): DESCRIPTION = 'Allocate a public IP address' ARGS = [Arg('-d', '--domain', dest='Domain', metavar='vpc', choices=('vpc',), help='''[VPC only] "vpc" to allocate the address for use in a VPC''')] def print_result(self, result): print self.tabify(('ADDRESS', result.get('publicIp'), result.get('domain', 'standard'), result.get('allocationId'))) euca2ools-3.3.1/euca2ools/commands/ec2/assignprivateipaddresses.py000066400000000000000000000071321267461563000252550ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from requestbuilder import Arg, MutuallyExclusiveArgList from requestbuilder.exceptions import ArgumentError from euca2ools.commands.ec2 import EC2Request class AssignPrivateIpAddresses(EC2Request): DESCRIPTION = ('Assign one or more private IP addresses to a network ' 'interface\n\nNote that an instance\'s type may affect ' 'the number of addresses it can hold at once.') ARGS = [Arg('-n', '--network-interface', metavar='INTERFACE', dest='NetworkInterfaceId', help='''ID of the network interface to assign addresses to (required)'''), Arg('positional_interface', nargs='?', route_to=None, help=argparse.SUPPRESS), MutuallyExclusiveArgList( Arg('--secondary-address', '--secondary-private-ip-address', metavar='ADDRESS', dest='PrivateIpAddress', action='append', help='''assign a specific secondary private IP address to the network interface. Use this option multiple times to add additional addresses.'''), Arg('--secondary-count', '--secondary-private-ip-address-count', dest='SecondaryPrivateIpAddressCount', metavar='COUNT', type=int, help='''automatically assign a specific number of secondary private IP addresses to the network interface''')) .required(), Arg('--allow-reassignment', dest='AllowReassignment', action='store_true', help='''Allow addresses to be assigned even if they are already associated with other interfaces''')] def configure(self): EC2Request.configure(self) if self.args.get('positional_interface'): if self.params.get('NetworkInterfaceId'): # Shouldn't be supplied both positionally and optionally raise ArgumentError('unrecognized arguments: {0}'.format( self.args['positional_interface'])) self.params['NetworkInterfaceId'] = \ self.args['positional_interface'] if not self.params.get('NetworkInterfaceId'): raise ArgumentError('argument -n/--network-interface is required') euca2ools-3.3.1/euca2ools/commands/ec2/associateaddress.py000066400000000000000000000102331267461563000234640ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, MutuallyExclusiveArgList from requestbuilder.exceptions import ArgumentError from euca2ools.commands.ec2 import EC2Request class AssociateAddress(EC2Request): DESCRIPTION = 'Associate an elastic IP address with a running instance' ARGS = [Arg('PublicIp', metavar='ADDRESS', nargs='?', help='''[Non-VPC only] IP address to associate (required)'''), Arg('-a', '--allocation-id', dest='AllocationId', metavar='ALLOC', help='[VPC only] VPC allocation ID (required)'), MutuallyExclusiveArgList( Arg('-i', '--instance-id', dest='InstanceId', metavar='INSTANCE', help='''ID of the instance to associate the address with'''), Arg('-n', '--network-interface', dest='NetworkInterfaceId', metavar='INTERFACE', help='''[VPC only] network interface to associate the address with''')) .required(), Arg('-p', '--private-ip-address', dest='PrivateIpAddress', metavar='ADDRESS', help='''[VPC only] the private address to associate with the address being associated in the VPC (default: primary private IP)'''), Arg('--allow-reassociation', dest='AllowReassociation', action='store_const', const='true', help='''[VPC only] allow the address to be associated even if it is already associated with another interface''')] # noinspection PyExceptionInherit def configure(self): EC2Request.configure(self) if (self.args.get('PublicIp') is not None and self.args.get('AllocationId') is not None): # Can't be both EC2 and VPC raise ArgumentError( 'argument -a/--allocation-id: not allowed with an IP address') if (self.args.get('PublicIp') is None and self.args.get('AllocationId') is None): # ...but we still have to be one of them raise ArgumentError( 'argument -a/--allocation-id or an IP address is required') if (self.args.get('PublicIp') or '').startswith('eipalloc-'): # Make allocation IDs work positionally for convenience self.params['AllocationId'] = self.params.pop('PublicIp') def print_result(self, result): if self.args.get('AllocationId'): # VPC print self.tabify(('ADDRESS', self.args.get('InstanceId'), self.args.get('AllocationId'), result.get('associationId'), self.args.get('PrivateIpAddress'))) else: # EC2 print self.tabify(('ADDRESS', self.args.get('PublicIp'), self.args.get('InstanceId'))) euca2ools-3.3.1/euca2ools/commands/ec2/associatedhcpoptions.py000066400000000000000000000037201267461563000243740ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class AssociateDhcpOptions(EC2Request): DESCRIPTION = 'Associate a DHCP option set with a VPC' ARGS = [Arg('DhcpOptionsId', metavar='DHCPOPTS', help='''ID of the DHCP option set to associate, or "default" (required)'''), Arg('-c', '--vpc', dest='VpcId', metavar='VPC', required=True, help='''ID of the VPC to associate the DHCP option set with (required)''')] def print_result(self, _): print self.tabify(('DHCPOPTIONS', self.args['DhcpOptionsId'], self.args['VpcId'])) euca2ools-3.3.1/euca2ools/commands/ec2/associateroutetable.py000066400000000000000000000037521267461563000242150ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class AssociateRouteTable(EC2Request): DESCRIPTION = 'Associate a VPC route table with a subnet' ARGS = [Arg('RouteTableId', metavar='RTABLE', help='ID of the route table to associate (required)'), Arg('-s', '--subnet', dest='SubnetId', metavar='SUBNET', required=True, help='''ID of the subnet to associate the route table with (required)''')] def print_result(self, result): print self.tabify(('ASSOCIATION', result.get('associationId'), self.args['RouteTableId'], self.args['SubnetId'])) euca2ools-3.3.1/euca2ools/commands/ec2/attachinternetgateway.py000066400000000000000000000034141267461563000245450ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class AttachInternetGateway(EC2Request): DESCRIPTION = 'Attach an Internet gateway to a VPC' ARGS = [Arg('-c', '--vpc', dest='VpcId', metavar='VPC', required=True, help='VPC to attach the Internet gateway to (required)'), Arg('InternetGatewayId', metavar='IGATEWAY', help='Internet gateway to attach (required)')] euca2ools-3.3.1/euca2ools/commands/ec2/attachnetworkinterface.py000066400000000000000000000041331267461563000247040ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class AttachNetworkInterface(EC2Request): DESCRIPTION = 'Attach a VPC network interface to an instance' ARGS = [Arg('-i', '--instance', dest='InstanceId', metavar='INSTANCE', required=True, help='instance to attach the network interface to (required)'), Arg('-d', '--device-index', dest='DeviceIndex', metavar='INT', type=int, required=True, help='''device index to attach the network interface with (required)'''), Arg('NetworkInterfaceId', metavar='INTERFACE', help='network interface to attach to the instance (required)')] def print_result(self, result): print result.get('attachmentId') euca2ools-3.3.1/euca2ools/commands/ec2/attachvolume.py000066400000000000000000000037311267461563000226440ustar00rootroot00000000000000# Copyright 2009-2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg class AttachVolume(EC2Request): DESCRIPTION = 'Attach an EBS volume to an instance' ARGS = [Arg('-i', '--instance', dest='InstanceId', metavar='INSTANCE', required=True, help='instance to attach the volume to (required)'), Arg('-d', '--device', dest='Device', required=True, help='device name exposed to the instance (required)'), Arg('VolumeId', metavar='VOLUME', help='ID of the volume to attach (required)')] def print_result(self, result): self.print_attachment(result) euca2ools-3.3.1/euca2ools/commands/ec2/attachvpngateway.py000066400000000000000000000037511267461563000235240ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class AttachVpnGateway(EC2Request): DESCRIPTION = 'Attach a virtual private gateway to a VPC' ARGS = [Arg('-c', '--vpc', dest='VpcId', metavar='VPC', required=True, help='VPC to attach the virtual private gateway to (required)'), Arg('VpnGatewayId', metavar='VGATEWAY', help='virtual private gateway to attach (required)')] def print_result(self, result): attachment = result.get('attachment') or {} print self.tabify(('VGWATTACHMENT', attachment.get('vpcId'), attachment.get('state'))) euca2ools-3.3.1/euca2ools/commands/ec2/bundleinstance.py000066400000000000000000000145161267461563000231510ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import base64 from datetime import datetime, timedelta import hashlib import hmac import json import time from requestbuilder import Arg from requestbuilder.exceptions import ArgumentError from euca2ools.commands.ec2 import EC2Request class BundleInstance(EC2Request): DESCRIPTION = 'Bundle an S3-backed Windows instance' ARGS = [Arg('InstanceId', metavar='INSTANCE', help='ID of the instance to bundle (required)'), Arg('-b', '--bucket', dest='Storage.S3.Bucket', metavar='BUCKET', required=True, help='''bucket in which to store the new machine image (required)'''), Arg('-p', '--prefix', dest='Storage.S3.Prefix', metavar='PREFIX', required=True, help='beginning of the machine image bundle name (required)'), Arg('-o', '--owner-akid', '--user-access-key', metavar='KEY-ID', dest='Storage.S3.AWSAccessKeyId', help='''bucket owner's access key ID (required if not specified in configuration)'''), Arg('-c', '--policy', metavar='POLICY', dest='Storage.S3.UploadPolicy', help='''Base64-encoded upload policy that allows the server to upload a bundle on your behalf. If unused, a secret key is required.'''), Arg('-s', '--policy-signature', metavar='SIGNATURE', dest='Storage.S3.UploadPolicySignature', help='''signature of the Base64-encoded upload policy. If unused, a secret key is required.'''), Arg('-w', '--owner-sak', '--user-secret-key', metavar='KEY', route_to=None, help='''bucket owner's secret access key, used to sign upload policies. This is required unless both -c and -s are used or if a secret key is specified in a configuration file.'''), Arg('-x', '--expires', metavar='HOURS', type=int, default=24, route_to=None, help='generated upload policy expiration time (default: 24)')] def generate_default_policy(self): delta = timedelta(hours=self.args['expires']) expire_time = (datetime.utcnow() + delta).replace(microsecond=0) conditions = [{'acl': 'ec2-bundle-read'}, {'bucket': self.args.get('Storage.S3.Bucket')}, ['starts-with', '$key', self.args.get('Storage.S3.Prefix')]] policy = {'conditions': conditions, 'expiration': time.strftime('%Y-%m-%dT%H:%M:%SZ', expire_time.timetuple())} policy_json = json.dumps(policy) self.log.info('generated default policy: %s', policy_json) self.params['Storage.S3.UploadPolicy'] = base64.b64encode(policy_json) def sign_policy(self): my_hmac = hmac.new(self.args['owner_sak'], digestmod=hashlib.sha1) my_hmac.update(self.params.get('Storage.S3.UploadPolicy')) self.params['Storage.S3.UploadPolicySignature'] = \ base64.b64encode(my_hmac.digest()) # noinspection PyExceptionInherit def configure(self): EC2Request.configure(self) if not self.params.get('Storage.S3.AWSAccessKeyId'): config_key_id = self.config.get_user_option('key-id') if config_key_id: self.log.info('Using access key ID %s from configuration', config_key_id) self.params['Storage.S3.AWSAccessKeyId'] = config_key_id else: raise ArgumentError('argument -o/--owner-akid is required') if not self.params.get('Storage.S3.UploadPolicy'): if not self.args.get('owner_sak'): config_secret_key = self.config.get_user_option('secret-key') if config_secret_key: self.log.info('Using secret key from configuration') self.args['owner_sak'] = config_secret_key else: raise ArgumentError('argument -w/--owner-sak is required ' 'when -c/--policy is not used') elif not self.args.get('Storage.S3.UploadPolicySignature'): if not self.args.get('owner_sak'): config_secret_key = self.config.get_user_option('secret-key') if config_secret_key: self.log.info('Using secret key from configuration') self.args['owner_sak'] = config_secret_key else: raise ArgumentError('argument -w/--owner-sak is required ' 'when -s/--policy-signature is not ' 'used') def preprocess(self): if not self.args.get('Storage.S3.UploadPolicy'): self.generate_default_policy() if not self.args.get('Storage.S3.UploadPolicySignature'): self.sign_policy() def print_result(self, result): self.print_bundle_task(result['bundleInstanceTask']) euca2ools-3.3.1/euca2ools/commands/ec2/cancelbundletask.py000066400000000000000000000033111267461563000234440ustar00rootroot00000000000000# Copyright 2009-2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg class CancelBundleTask(EC2Request): DESCRIPTION = 'Cancel an instance bundling operation' ARGS = [Arg('BundleId', metavar='TASK-ID', help='ID of the bundle task to cancel (required)')] def print_result(self, result): self.print_bundle_task(result.get('bundleInstanceTask')) euca2ools-3.3.1/euca2ools/commands/ec2/cancelconversiontask.py000066400000000000000000000031331267461563000243620ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class CancelConversionTask(EC2Request): DESCRIPTION = 'Cancel an import task' ARGS = [Arg('ConversionTaskId', metavar='TASK-ID', help='ID of the import task to cancel (required)')] euca2ools-3.3.1/euca2ools/commands/ec2/confirmproductinstance.py000066400000000000000000000037331267461563000247350ustar00rootroot00000000000000# Copyright 2009-2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg class ConfirmProductInstance(EC2Request): DESCRIPTION = 'Verify if a product code is associated with an instance' ARGS = [Arg('ProductCode', metavar='CODE', help='product code to confirm (required)'), Arg('-i', '--instance', dest='InstanceId', metavar='INSTANCE', required=True, help='ID of the instance to confirm (required)')] def print_result(self, result): print self.tabify((self.args['ProductCode'], self.args['InstanceId'], result.get('return'), result.get('ownerId'))) euca2ools-3.3.1/euca2ools/commands/ec2/copyimage.py000066400000000000000000000046451267461563000221320ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg class CopyImage(EC2Request): DESCRIPTION = ('Copy an image from another region\n\nRun this command ' 'against the destination region, not the source region.') ARGS = [Arg('-r', '--source-region', dest='SourceRegion', metavar='REGION', required=True, help='name of the region to copy the image from (required)'), Arg('-s', '--source-ami-id', dest='SourceImageId', metavar='IMAGE', required=True, help='ID of the image to copy (required)'), Arg('-n', '--name', dest='Name', help='name to assign the new copy of the image'), Arg('-d', '--description', dest='Description', metavar='DESC', help='description to assign the new copy of the image'), Arg('-c', '--client-token', dest='ClientToken', metavar='TOKEN', help='unique identifier to ensure request idempotency')] def print_result(self, result): print self.tabify(('IMAGE', result.get('imageId'))) euca2ools-3.3.1/euca2ools/commands/ec2/createcustomergateway.py000066400000000000000000000044131267461563000245550ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class CreateCustomerGateway(EC2Request): DESCRIPTION = ('Create a VPN customer gateway\n\nThis is the external ' 'side of a VPN connection. You will also need to create ' 'a virtual private gateway with euca-create-vpn-gateway(1).') ARGS = [Arg('-t', '--type', dest='Type', metavar='ipsec.1', required=True, choices=('ipsec.1',), help='the type of VPN connection to use (required)'), Arg('-i', '--ip', dest='IpAddress', metavar='ADDRESS', required=True, help='''the new customer gateway's cloud-facing IP address (required)'''), Arg('-b', '--bgp-asn', dest='BgpAsn', metavar='ASN', help="the new customer gateway's BGP AS number")] def print_result(self, result): self.print_customer_gateway(result.get('customerGateway') or {}) euca2ools-3.3.1/euca2ools/commands/ec2/createdhcpoptions.py000066400000000000000000000051441267461563000236660ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request _DHCP_OPTION_KEYS = ('domain-name-servers', 'domain-name', 'ntp-servers', 'netbios-name-servers', 'netbios-node-type') def _dhcp_option(option_str): if '=' not in option_str: raise argparse.ArgumentTypeError( "value '{0}' must have form KEY=VALUE,VALUE,..." .format(option_str)) key, vals = option_str.split('=', 1) if key not in _DHCP_OPTION_KEYS: raise argparse.ArgumentTypeError( "'{0}' is not a valid DHCP option; choose from {1}" .format(key, ', '.join(_DHCP_OPTION_KEYS))) return {'Key': key, 'Value': vals.split(',')} class CreateDhcpOptions(EC2Request): DESCRIPTION = 'Create a VPC DHCP option set' # EC2 throws 500s when presented with empty DhcpConfigurations. ARGS = [Arg('DhcpConfiguration', nargs='+', metavar='KEY=VALUE,[VALUE,...]', type=_dhcp_option, help='''key and one or more values for a DHCP option (choose from {0}) (required)'''.format(', '.join(_DHCP_OPTION_KEYS)))] LIST_TAGS = ['dhcpConfigurationSet', 'tagSet', 'valueSet'] def print_result(self, result): self.print_dhcp_options(result.get('dhcpOptions') or {}) euca2ools-3.3.1/euca2ools/commands/ec2/createimage.py000066400000000000000000000052621267461563000224170ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.argtypes import ec2_block_device_mapping from euca2ools.commands.ec2 import EC2Request class CreateImage(EC2Request): DESCRIPTION = 'Create an EBS image from a running or stopped EBS instance' ARGS = [Arg('InstanceId', metavar='INSTANCE', help='instance from which to create the image (required)'), Arg('-n', '--name', dest='Name', required=True, help='name for the new image (required)'), Arg('-d', '--description', dest='Description', metavar='DESC', help='description for the new image'), Arg('--no-reboot', dest='NoReboot', action='store_const', const='true', help='''do not shut down the instance before creating the image. Image integrity may be affected.'''), Arg('-b', '--block-device-mapping', metavar='DEVICE=MAPPED', dest='BlockDeviceMapping', action='append', type=ec2_block_device_mapping, default=[], help='''define a block device mapping for the image, in the form DEVICE=MAPPED, where "MAPPED" is "none", "ephemeral(0-3)", or "[SNAP_ID]:[GiB]:[true|false]:[standard|VOLTYPE[:IOPS]]"''')] def print_result(self, result): print self.tabify(('IMAGE', result.get('imageId'))) euca2ools-3.3.1/euca2ools/commands/ec2/createinternetgateway.py000066400000000000000000000031471267461563000245470ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request class CreateInternetGateway(EC2Request): DESCRIPTION = 'Create a new VPC Internet gateway' LIST_TAGS = ['attachmentSet', 'tagSet'] def print_result(self, result): self.print_internet_gateway(result.get('internetGateway') or {}) euca2ools-3.3.1/euca2ools/commands/ec2/createkeypair.py000066400000000000000000000042431267461563000227770ustar00rootroot00000000000000# Copyright 2009-2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request import os from requestbuilder import Arg class CreateKeyPair(EC2Request): DESCRIPTION = 'Create a new SSH key pair for use with instances' ARGS = [Arg('KeyName', metavar='KEYPAIR', help='name of the new key pair (required)'), Arg('-f', '--filename', metavar='FILE', route_to=None, help='file name to save the private key to')] def print_result(self, result): print self.tabify(('KEYPAIR', result['keyName'], result['keyFingerprint'])) if self.args.get('filename'): prev_umask = os.umask(0o077) with open(self.args['filename'], 'w') as privkeyfile: privkeyfile.write(result['keyMaterial']) os.umask(prev_umask) else: print result['keyMaterial'] euca2ools-3.3.1/euca2ools/commands/ec2/createnetworkacl.py000066400000000000000000000034121267461563000235010ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class CreateNetworkAcl(EC2Request): DESCRIPTION = 'Create a new VPC network ACL' ARGS = [Arg('VpcId', metavar='VPC', help='''ID of the VPC in which to create the new network ACL (required)''')] LIST_TAGS = ['associationSet', 'entrySet', 'tagSet'] def print_result(self, result): self.print_network_acl(result.get('networkAcl') or {}) euca2ools-3.3.1/euca2ools/commands/ec2/createnetworkinterface.py000066400000000000000000000071221267461563000247040ustar00rootroot00000000000000# Copyright 2014-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, MutuallyExclusiveArgList from euca2ools.commands.ec2 import EC2Request class CreateNetworkInterface(EC2Request): DESCRIPTION = 'Create a new VPC network interface' ARGS = [Arg('SubnetId', metavar='SUBNET', help='''subnet to create the new network interface in (required)'''), Arg('-d', '--description', dest='Description', metavar='DESC', help='description for the new network interface'), Arg('-g', '--group', dest='SecurityGroupId', metavar='GROUP', action='append', help='''ID of a security group to add the new network interface to. This option may be used more than once. Each time adds the network interface to an additional security group.'''), Arg('--private-ip-address', metavar='ADDRESS', route_to=None, help='''assign a specific primary private IP address to the new network interface'''), MutuallyExclusiveArgList( Arg('--secondary-address', '--secondary-private-ip-address', metavar='ADDRESS', route_to=None, action='append', help='''assign a specific secondary private IP address to the new network interface. Use this option multiple times to add additional addresses.'''), Arg('--secondary-count', '--secondary-private-ip-address-count', dest='SecondaryPrivateIpAddressCount', metavar='COUNT', type=int, help='''automatically assign a specific number of secondary private IP addresses to the new network interface'''))] LIST_TAGS = ['groupSet', 'privateIpAddressesSet'] def preprocess(self): addrs = [] if self.args.get('private_ip_address'): addrs.append({'PrivateIpAddress': self.args['private_ip_address'], 'Primary': True}) for addr in self.args.get('secondary_private_ip_address') or []: addrs.append({'PrivateIpAddress': addr, 'Primary': False}) self.params['PrivateIpAddresses'] = addrs def print_result(self, result): self.print_interface(result.get('networkInterface') or {}) euca2ools-3.3.1/euca2ools/commands/ec2/createroute.py000066400000000000000000000054301267461563000224700ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, MutuallyExclusiveArgList from euca2ools.commands.ec2 import EC2Request class CreateRoute(EC2Request): DESCRIPTION = 'Add a route to a VPC route table' ARGS = [Arg('RouteTableId', metavar='RTABLE', help='ID of the route table to add the route to (required)'), Arg('-r', '--cidr', dest='DestinationCidrBlock', metavar='CIDR', required=True, help='CIDR address block the route should affect (required)'), MutuallyExclusiveArgList( Arg('-g', '--gateway-id', dest='GatewayId', metavar='GATEWAY', help='ID of an Internet gateway to target'), Arg('-i', '--instance', dest='InstanceId', metavar='INSTANCE', help='ID of a NAT instance to target'), Arg('-n', '--network-interface', dest='NetworkInterfaceId', help='ID of a network interface to target'), Arg('-p', '--vpc-peering-connection', metavar='PEERCON', dest='VpcPeeringConnectionId', help='ID of a VPC peering connection to target')) .required()] def print_result(self, _): target = (self.args.get('GatewayId') or self.args.get('InstanceId') or self.args.get('NetworkInterfaceId') or self.args.get('VpcPeeringConnectionId')) print self.tabify(('ROUTE', target, self.args['DestinationCidrBlock'])) euca2ools-3.3.1/euca2ools/commands/ec2/createroutetable.py000066400000000000000000000034631267461563000235040ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class CreateRouteTable(EC2Request): DESCRIPTION = 'Create a new VPC route table' ARGS = [Arg('VpcId', metavar='VPC', help='ID of the VPC to create the route table in (required)')] LIST_TAGS = ['associationSet', 'propagatingVgwSet', 'routeTableSet', 'routeSet', 'tagSet'] def print_result(self, result): self.print_route_table(result.get('routeTable') or {}) euca2ools-3.3.1/euca2ools/commands/ec2/createsecuritygroup.py000066400000000000000000000041041267461563000242530ustar00rootroot00000000000000# Copyright 2009-2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg class CreateSecurityGroup(EC2Request): DESCRIPTION = 'Create a new security group' ARGS = [Arg('GroupName', metavar='GROUP', help='name of the new group (required)'), Arg('-d', '--description', dest='GroupDescription', metavar='DESC', required=True, help='description of the new group (required)'), Arg('-c', '--vpc', dest='VpcId', metavar='VPC', help='[VPC only] ID of the VPC to create the group in')] def print_result(self, result): print self.tabify(('GROUP', result.get('groupId'), self.args['GroupName'], self.args['GroupDescription'])) euca2ools-3.3.1/euca2ools/commands/ec2/createsnapshot.py000066400000000000000000000040661267461563000231750ustar00rootroot00000000000000# Copyright 2009-2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg class CreateSnapshot(EC2Request): DESCRIPTION = 'Create a snapshot of a volume' ARGS = [Arg('VolumeId', metavar='VOLUME', help='volume to create a snapshot of (required)'), Arg('-d', '--description', metavar='DESC', dest='Description', help='snapshot description')] def print_result(self, result): print self.tabify(('SNAPSHOT', result.get('snapshotId'), result.get('volumeId'), result.get('status'), result.get('startTime'), result.get('ownerId'), result.get('volumeSize'), result.get('description'))) euca2ools-3.3.1/euca2ools/commands/ec2/createsubnet.py000066400000000000000000000054761267461563000226440ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from requestbuilder import Arg from requestbuilder.exceptions import ArgumentError from euca2ools.commands.ec2 import EC2Request class CreateSubnet(EC2Request): DESCRIPTION = 'Create a new VPC subnet' # We also accept CidrBlock positionally because forgetting -i is common. # https://eucalyptus.atlassian.net/browse/TOOLS-497 ARGS = [Arg('positional_cidr', nargs='?', route_to=None, help=argparse.SUPPRESS), Arg('-c', '--vpc', dest='VpcId', required=True, help='ID of the VPC to create the new subnet in (required)'), Arg('-i', '--cidr', dest='CidrBlock', metavar='CIDR', help='CIDR address block for the new subnet (required)'), Arg('-z', '--availability-zone', dest='AvailabilityZone', help='availability zone in which to create the new subnet')] LIST_TAGS = ['tagSet'] def configure(self): EC2Request.configure(self) if self.args.get('positional_cidr'): if self.params.get('CidrBlock'): # Shouldn't be supplied both positionally and optionally raise ArgumentError('unrecognized arguments: {0}'.format( self.args['positional_cidr'])) self.params['CidrBlock'] = self.args['positional_cidr'] if not self.params.get('CidrBlock'): raise ArgumentError('argument -i/--cidr is required') def print_result(self, result): self.print_subnet(result.get('subnet') or {}) euca2ools-3.3.1/euca2ools/commands/ec2/createtags.py000066400000000000000000000044511267461563000222720ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.argtypes import binary_tag_def from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg class CreateTags(EC2Request): DESCRIPTION = 'Add or overwrite tags for one or more resources' ARGS = [Arg('ResourceId', metavar='RESOURCE', nargs='+', help='ID(s) of the resource(s) to tag (at least 1 required)'), Arg('--tag', dest='Tag', metavar='KEY[=VALUE]', type=binary_tag_def, action='append', required=True, help='''key and optional value of the tag to create, separated by an "=" character. If no value is given the tag's value is set to an empty string. (at least 1 required)''')] def print_result(self, _): for resource_id in self.args['ResourceId']: for tag in self.args['Tag']: lc_resource_tag = {'key': tag['Key'], 'value': tag['Value']} self.print_resource_tag(lc_resource_tag, resource_id) euca2ools-3.3.1/euca2ools/commands/ec2/createvolume.py000066400000000000000000000061771267461563000226520ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from requestbuilder.exceptions import ArgumentError from euca2ools.commands.ec2 import EC2Request class CreateVolume(EC2Request): DESCRIPTION = 'Create a new volume' ARGS = [Arg('-z', '--availability-zone', dest='AvailabilityZone', metavar='ZONE', required=True, help='''availability zone in which to create the new volume (required)'''), Arg('-s', '--size', dest='Size', metavar='GiB', type=int, help='''size of the new volume in GiB (required unless --snapshot is used)'''), Arg('--snapshot', dest='SnapshotId', metavar='SNAPSHOT', help='snapshot from which to create the new volume'), Arg('-t', '--type', dest='VolumeType', metavar='VOLTYPE', help='volume type'), Arg('-i', '--iops', dest='Iops', type=int, help='number of I/O operations per second')] # noinspection PyExceptionInherit def configure(self): EC2Request.configure(self) if not self.args.get('Size') and not self.args.get('SnapshotId'): raise ArgumentError('-s/--size or --snapshot must be specified') if self.args.get('Iops') and not self.args.get('VolumeType'): raise ArgumentError('argument -i/--iops: -t/--type is required') if self.args.get('Iops') and self.args.get('VolumeType') == 'standard': raise ArgumentError( 'argument -i/--iops: not allowed with volume type "standard"') def print_result(self, result): print self.tabify(('VOLUME', result.get('volumeId'), result.get('size'), result.get('snapshotId'), result.get('availabilityZone'), result.get('status'), result.get('createTime'))) euca2ools-3.3.1/euca2ools/commands/ec2/createvpc.py000066400000000000000000000035351267461563000221260ustar00rootroot00000000000000# Copyright 2013-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class CreateVpc(EC2Request): DESCRIPTION = 'Create a new VPC' ARGS = [Arg('CidrBlock', metavar='CIDR', help='Address CIDR block for the new VPC (required)'), Arg('--tenancy', dest='InstanceTenancy', choices=('default', 'dedicated'), help='the type of instance tenancy to use')] LIST_TAGS = ['tagSet'] def print_result(self, result): self.print_vpc(result.get('vpc') or {}) euca2ools-3.3.1/euca2ools/commands/ec2/createvpcpeeringconnection.py000066400000000000000000000045011267461563000255520ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class CreateVpcPeeringConnection(EC2Request): DESCRIPTION = ('Request a peering connection between two VPCs\n\nThe ' 'owner of the VPC you wish to peer with must accept ' 'the peering request to activate the peering connection') ARGS = [Arg('-c', '--vpc', dest='VpcId', metavar='VPC', required=True, help='the VPC to request a peering connection from (required)'), Arg('-p', '--peer-vpc', dest='PeerVpcId', metavar='VPC', required=True, help='the VPC to request a peering connection to (required)'), Arg('-o', '--peer-owner-id', dest='PeerOwnerId', metavar='ACCOUNT', help='''account ID of the peer VPC's owner (default: current user's account ID)''')] LIST_TAGS = ['tagSet'] def print_result(self, result): self.print_peering_connection(result.get('vpcPeeringConnection') or {}) euca2ools-3.3.1/euca2ools/commands/ec2/createvpnconnection.py000066400000000000000000000112161267461563000242140ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import sys from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class CreateVpnConnection(EC2Request): DESCRIPTION = ('Create a VPN connection between a virtual private ' 'gateway and a customer gateway\n\nYou can optionally ' 'format the connection information for specific ' 'devices using the --format or --stylesheet options. ' 'If the --stylesheet option is an HTTP or HTTPS URL it ' 'will be downloaded as needed.') ARGS = [Arg('-t', '--type', dest='Type', metavar='ipsec.1', required=True, choices=('ipsec.1',), help='the type of VPN connection to use (required)'), Arg('--customer-gateway', dest='CustomerGatewayId', required=True, metavar='CGATEWAY', help='ID of the customer gateway to connect (required)'), Arg('--vpn-gateway', dest='VpnGatewayId', required=True, metavar='VGATEWAY', help='ID of the virtual private gateway to connect (required)'), Arg('--static-routes-only', dest='Options.StaticRoutesOnly', action='store_true', help='use only static routes instead of BGP'), Arg('--format', route_to=None, help='''show connection information in a specific format (cisco-ios-isr, juniper-junos-j, juniper-screenos-6.1, juniper-screenos-6.2, generic, xml, none) (default: xml)'''), Arg('--stylesheet', route_to=None, help='''format the connection information using an XSL stylesheet. If the value contains "{format}" it will be replaced with the format chosen by the --format option. If the value is an HTTP or HTTPS URL it will be downloaded as needed. (default: value of "vpn-stylesheet" region option)''')] def print_result(self, result): if self.args.get('format') is None: # If --stylesheet is used it will be applied. Otherwise, # None will make it print the raw XML, which is what we want. stylesheet = self.args.get('stylesheet') show_conn_info = True elif self.args.get('format') == 'none': stylesheet = None show_conn_info = False elif self.args.get('format') == 'xml': stylesheet = None show_conn_info = True else: stylesheet = self.args.get('stylesheet') if not stylesheet: stylesheet = self.config.get_region_option('vpn-stylesheet') if stylesheet: stylesheet = stylesheet.format(format=self.args['format']) else: self.log.warn('current region has no stylesheet') msg = ('current region has no XSLT stylesheet to format ' 'output; connection info will not be shown (try ' 'specifying one with "--stylesheet" or using ' '"--format xml")') print >> sys.stderr, msg show_conn_info = bool(stylesheet) self.print_vpn_connection(result.get('vpnConnection') or {}, show_conn_info=show_conn_info, stylesheet=stylesheet) euca2ools-3.3.1/euca2ools/commands/ec2/createvpnconnectionroute.py000066400000000000000000000036611267461563000253000ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class CreateVpnConnectionRoute(EC2Request): DESCRIPTION = ('Create a static route that sends traffic from a ' 'virtual private gateway to a customer gateway') ARGS = [Arg('--vpn-connection', dest='VpnConnectionId', metavar='VPNCONN', required=True, help='ID of the virtual private gateway to affect (required)'), Arg('--cidr', dest='DestinationCidrBlock', metavar='CIDR', required=True, help='the address block to add a route to (required)')] euca2ools-3.3.1/euca2ools/commands/ec2/createvpngateway.py000066400000000000000000000036741267461563000235270ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class CreateVpnGateway(EC2Request): DESCRIPTION = ('Create a virtual private gateway\n\nThis is the VPC side ' 'of a VPN connection. You will also need to create a VPN ' 'customer gateway with euca-create-customer-gateway(1).') ARGS = [Arg('-t', '--type', dest='Type', metavar='ipsec.1', required=True, choices=('ipsec.1',), help='the type of VPN connection to use (required)')] def print_result(self, result): self.print_vpn_gateway(result.get('vpnGateway') or {}) euca2ools-3.3.1/euca2ools/commands/ec2/deletecustomergateway.py000066400000000000000000000031531267461563000245540ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class DeleteCustomerGateway(EC2Request): DESCRIPTION = 'Delete a VPN customer gateway' ARGS = [Arg('CustomerGatewayId', metavar='CGATEWAY', help='ID of the customer gateway to delete (required)')] euca2ools-3.3.1/euca2ools/commands/ec2/deletedhcpoptions.py000066400000000000000000000031411267461563000236600ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class DeleteDhcpOptions(EC2Request): DESCRIPTION = 'Delete a VPC DHCP option set' ARGS = [Arg('DhcpOptionsId', metavar='DHCPOPTS', help='ID of the DHCP option set to delete (required)')] euca2ools-3.3.1/euca2ools/commands/ec2/deletediskimage.py000066400000000000000000000113111267461563000232610ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import tempfile from requestbuilder import Arg, MutuallyExclusiveArgList from requestbuilder.exceptions import ArgumentError from euca2ools.commands.ec2 import EC2Request from euca2ools.commands.ec2.describeconversiontasks import \ DescribeConversionTasks from euca2ools.commands.ec2.mixins import S3AccessMixin from euca2ools.commands.ec2.structures import ImportManifest from euca2ools.commands.s3.deleteobject import DeleteObject from euca2ools.commands.s3.getobject import GetObject from euca2ools.exceptions import AWSError class DeleteDiskImage(EC2Request, S3AccessMixin): DESCRIPTION = 'Delete a disk image used for an import task' ARGS = [MutuallyExclusiveArgList( Arg('-t', '--task', help='ID of the task to delete the image from'), Arg('-u', '--manifest-url', help='location of the import manifest')) .required(), Arg('--ignore-active-task', action='store_true', help='''delete the image even if the import task is active (only works with -t/--task)''')] def configure(self): EC2Request.configure(self) self.configure_s3_access() if self.args.get('ignore_active_task') and not self.args.get('task'): raise ArgumentError('argument --ignore-active-task my only be ' 'used with -t/--task') def main(self): if self.args.get('manifest_url'): manifest_url = self.args['manifest_url'] if self.args.get('task'): desc_conv = DescribeConversionTasks.from_other( self, ConversionTaskId=[self.args['task']]) task = desc_conv.main()['conversionTasks'][0] assert task['conversionTaskId'] == self.args['task'] if task.get('importVolume'): vol_container = task['importVolume'] else: vol_container = task['importInstance']['volumes'][0] manifest_url = vol_container['image']['importManifestUrl'] _, bucket, key = self.args['s3_service'].resolve_url_to_location( manifest_url) manifest_s3path = '/'.join((bucket, key)) manifest = self.__download_manifest(manifest_s3path) for part in manifest.image_parts: delete_req = DeleteObject.from_other( self, service=self.args['s3_service'], auth=self.args['s3_auth'], path='/'.join((bucket, part.key))) delete_req.main() delete_req = DeleteObject.from_other( self, service=self.args['s3_service'], auth=self.args['s3_auth'], path=manifest_s3path) delete_req.main() def __download_manifest(self, s3path): with tempfile.SpooledTemporaryFile(max_size=1024000) as \ manifest_destfile: get_req = GetObject.from_other( self, service=self.args['s3_service'], auth=self.args['s3_auth'], source=s3path, dest=manifest_destfile, show_progress=False) try: get_req.main() except AWSError as err: if err.status_code == 404: raise ArgumentError('import manifest "{0}" does not exist' .format(s3path)) raise manifest_destfile.seek(0) return ImportManifest.read_from_fileobj(manifest_destfile) euca2ools-3.3.1/euca2ools/commands/ec2/deleteinternetgateway.py000066400000000000000000000031531267461563000245430ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class DeleteInternetGateway(EC2Request): DESCRIPTION = 'Delete a VPC Internet gateway' ARGS = [Arg('InternetGatewayId', metavar='IGATEWAY', help='ID of the Internet gateway to delete (required)')] euca2ools-3.3.1/euca2ools/commands/ec2/deletekeypair.py000066400000000000000000000032471267461563000230010ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg class DeleteKeyPair(EC2Request): DESCRIPTION = 'Delete a key pair' ARGS = [Arg('KeyName', metavar='KEYPAIR', help='name of the key pair to delete (required)')] def print_result(self, _): print self.tabify(('KEYPAIR', self.args['KeyName'])) euca2ools-3.3.1/euca2ools/commands/ec2/deletenetworkacl.py000066400000000000000000000031271267461563000235030ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class DeleteNetworkAcl(EC2Request): DESCRIPTION = 'Delete a VPC network ACL' ARGS = [Arg('NetworkAclId', metavar='ACL', help='ID of the network ACL to delete (required)')] euca2ools-3.3.1/euca2ools/commands/ec2/deletenetworkaclentry.py000066400000000000000000000036341267461563000245700ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class DeleteNetworkAclEntry(EC2Request): DESCRIPTION = 'Delete a network acl rule' ARGS = [Arg('NetworkAclId', metavar='NACL', help='''ID of the network ACL to delete an entry from (required)'''), Arg('-n', '--rule-number', dest='RuleNumber', required=True, type=int, help='number of the entry to delete (required)'), Arg('--egress', dest='Egress', action='store_true', help='''delete an egress entry (default: delete an ingress entry)''')] euca2ools-3.3.1/euca2ools/commands/ec2/deletenetworkinterface.py000066400000000000000000000031601267461563000247010ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class DeleteNetworkInterface(EC2Request): DESCRIPTION = 'Delete a VPC network interface' ARGS = [Arg('NetworkInterfaceId', metavar='INTERFACE', help='ID of the network interface to delete (required)')] euca2ools-3.3.1/euca2ools/commands/ec2/deleteroute.py000066400000000000000000000034051267461563000224670ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class DeleteRoute(EC2Request): DESCRIPTION = 'Delete a route from a VPC route table' ARGS = [Arg('RouteTableId', metavar='RTABLE', help='ID of the table to remove the route from (required)'), Arg('-r', '--cidr', dest='DestinationCidrBlock', required=True, help='CIDR address block of the route to delete (required)')] euca2ools-3.3.1/euca2ools/commands/ec2/deleteroutetable.py000066400000000000000000000031321267461563000234740ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class DeleteRouteTable(EC2Request): DESCRIPTION = 'Delete a VPC route table' ARGS = [Arg('RouteTableId', metavar='RTABLE', help='ID of the route table to delete (required)')] euca2ools-3.3.1/euca2ools/commands/ec2/deletesecuritygroup.py000066400000000000000000000036321267461563000242570ustar00rootroot00000000000000# Copyright 2009-2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg class DeleteSecurityGroup(EC2Request): DESCRIPTION = 'Delete a security group' ARGS = [Arg('group', metavar='GROUP', route_to=None, help='name or ID of the security group to delete (required)')] def preprocess(self): if self.args['group'].startswith('sg-'): self.params['GroupId'] = self.args['group'] else: self.params['GroupName'] = self.args['group'] def print_result(self, result): print self.tabify(('RETURN', result.get('return'))) euca2ools-3.3.1/euca2ools/commands/ec2/deletesnapshot.py000066400000000000000000000032561267461563000231740ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg class DeleteSnapshot(EC2Request): DESCRIPTION = 'Delete a snapshot' ARGS = [Arg('SnapshotId', metavar='SNAPSHOT', help='ID of the snapshot to delete (required)')] def print_result(self, _): print self.tabify(('SNAPSHOT', self.args['SnapshotId'])) euca2ools-3.3.1/euca2ools/commands/ec2/deletesubnet.py000066400000000000000000000031101267461563000226220ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class DeleteSubnet(EC2Request): DESCRIPTION = 'Delete a VPC subnet' ARGS = [Arg('SubnetId', metavar='SUBNET', help='ID of the subnet to delete (required)')] euca2ools-3.3.1/euca2ools/commands/ec2/deletetags.py000066400000000000000000000045561267461563000222770ustar00rootroot00000000000000# Copyright 2009-2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.argtypes import ternary_tag_def from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg class DeleteTags(EC2Request): DESCRIPTION = 'Delete tags from one or more resources' ARGS = [Arg('ResourceId', metavar='RESOURCE', nargs='+', help='''ID(s) of the resource(s) to un-tag (at least 1 required)'''), Arg('--tag', dest='Tag', metavar='KEY[=[VALUE]]', type=ternary_tag_def, action='append', required=True, help='''key and optional value of the tag to delete, separated by an "=" character. If you specify a value then the tag is deleted only if its value matches the one you specified. If you specify the empty string as the value (e.g. "--tag foo=") then the tag is deleted only if its value is the empty string. If you do not specify a value (e.g. "--tag foo") then the tag is deleted regardless of its value. (at least 1 required)''')] euca2ools-3.3.1/euca2ools/commands/ec2/deletevolume.py000066400000000000000000000032401267461563000226350ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg class DeleteVolume(EC2Request): DESCRIPTION = 'Delete a volume' ARGS = [Arg('VolumeId', metavar='VOLUME', help='ID of the volume to delete (required)')] def print_result(self, _): print self.tabify(('VOLUME', self.args['VolumeId'])) euca2ools-3.3.1/euca2ools/commands/ec2/deletevpc.py000066400000000000000000000030651267461563000221230ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class DeleteVpc(EC2Request): DESCRIPTION = 'Delete a VPC' ARGS = [Arg('VpcId', metavar='VPC', help='ID of the VPC to delete (required)')] euca2ools-3.3.1/euca2ools/commands/ec2/deletevpcpeeringconnection.py000066400000000000000000000031741267461563000255560ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class DeleteVpcPeeringConnection(EC2Request): DESCRIPTION = 'Delete a VPC peering connection' ARGS = [Arg('VpcPeeringConnectionId', metavar='PEERCON', help='ID of the VPC peering connection to delete (required)')] euca2ools-3.3.1/euca2ools/commands/ec2/deletevpnconnection.py000066400000000000000000000031361267461563000242150ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class DeleteVpnConnection(EC2Request): DESCRIPTION = 'Delete a VPN connection' ARGS = [Arg('VpnConnectionId', metavar='VPNCONN', help='ID of the VPN connection to delete (required)')] euca2ools-3.3.1/euca2ools/commands/ec2/deletevpnconnectionroute.py000066400000000000000000000036441267461563000253000ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class DeleteVpnConnectionRoute(EC2Request): DESCRIPTION = ('Delete a static route from a virtual private ' 'gateway to a customer gateway') ARGS = [Arg('--vpn-connection', dest='VpnConnectionId', metavar='VPNCONN', required=True, help='ID of the virtual private gateway to affect (required)'), Arg('--cidr', dest='DestinationCidrBlock', metavar='CIDR', required=True, help='the address block to delete the route for (required)')] euca2ools-3.3.1/euca2ools/commands/ec2/deletevpngateway.py000066400000000000000000000031531267461563000235160ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class DeleteVpnGateway(EC2Request): DESCRIPTION = 'Delete a virtual private gateway' ARGS = [Arg('VpnGatewayId', metavar='VGATEWAY', help='ID of the virtual private gateway to delete (required)')] euca2ools-3.3.1/euca2ools/commands/ec2/deregisterimage.py000066400000000000000000000036621267461563000233130ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg class DeregisterImage(EC2Request): DESCRIPTION = ('De-register an image. After you de-register an image it ' 'cannot be used to launch new instances.\n\nNote that in ' 'Eucalyptus 3 you may need to run this twice to completely ' "remove an image's registration from the system.") ARGS = [Arg('ImageId', metavar='IMAGE', help='ID of the image to de-register (required)')] def print_result(self, _): print self.tabify(('IMAGE', self.args['ImageId'])) euca2ools-3.3.1/euca2ools/commands/ec2/describeaccountattributes.py000066400000000000000000000037601267461563000254160ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class DescribeAccountAttributes(EC2Request): DESCRIPTION = 'Show information about your account' ARGS = [Arg('AttributeName', metavar='ATTRIBUTE', nargs='*', help='limit results to specific account attributes')] LIST_TAGS = ['accountAttributeSet', 'attributeValueSet'] def print_result(self, result): for attr in result.get('accountAttributeSet') or []: print self.tabify(('ACCOUNTATTRIBUTE', attr.get('attributeName'))) for value in attr.get('attributeValueSet') or []: print self.tabify(('VALUE', value.get('attributeValue'))) euca2ools-3.3.1/euca2ools/commands/ec2/describeaddresses.py000066400000000000000000000067201267461563000236270ustar00rootroot00000000000000# Copyright 2009-2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg, Filter class DescribeAddresses(EC2Request): DESCRIPTION = 'Show information about elastic IP addresses' ARGS = [Arg('address', metavar='ADDRESS', nargs='*', route_to=None, help='''limit results to specific elastic IP addresses or VPC allocation IDs''')] FILTERS = [Filter('allocation-id', help='[VPC only] allocation ID'), Filter('association-id', help='[VPC only] association ID'), Filter('domain', help='''whether the address is a standard ("standard") or VPC ("vpc") address'''), Filter('instance-id', help='instance the address is associated with'), Filter('network-interface-id', help='''[VPC only] network interface the address is associated with'''), Filter('network-interface-owner-id', help='''[VPC only] ID of the network interface's owner'''), Filter('private-ip-address', help='''[VPC only] private address associated with the public address'''), Filter('public-ip', help='the elastic IP address')] LIST_TAGS = ['addressesSet'] def preprocess(self): alloc_ids = set(addr for addr in self.args.get('address', []) if addr.startswith('eipalloc-')) public_ips = set(self.args.get('address', [])) - alloc_ids if alloc_ids: self.params['AllocationId'] = list(sorted(alloc_ids)) if public_ips: self.params['PublicIp'] = list(sorted(public_ips)) def print_result(self, result): for addr in result.get('addressesSet', []): print self.tabify(('ADDRESS', addr.get('publicIp'), addr.get('instanceId'), addr.get('domain', 'standard'), addr.get('allocationId'), addr.get('associationId'), addr.get('networkInterfaceId'), addr.get('privateIpAddress'))) euca2ools-3.3.1/euca2ools/commands/ec2/describeavailabilityzones.py000066400000000000000000000045461267461563000254070ustar00rootroot00000000000000# Copyright 2009-2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg, Filter class DescribeAvailabilityZones(EC2Request): DESCRIPTION = 'Display availability zones within the current region' ARGS = [Arg('ZoneName', metavar='ZONE', nargs='*', help='limit results to specific availability zones')] FILTERS = [Filter('message', help='''message giving information about the availability zone'''), Filter('region-name', help='region the availability zone is in'), Filter('state', help='state of the availability zone'), Filter('zone-name', help='name of the availability zone')] LIST_TAGS = ['availabilityZoneInfo', 'messageSet'] def print_result(self, result): for zone in result.get('availabilityZoneInfo', []): msgs = ', '.join(msg for msg in zone.get('messageSet', [])) print self.tabify(('AVAILABILITYZONE', zone.get('zoneName'), zone.get('zoneState'), msgs)) euca2ools-3.3.1/euca2ools/commands/ec2/describebundletasks.py000066400000000000000000000051221267461563000241640ustar00rootroot00000000000000# Copyright 2009-2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg, Filter class DescribeBundleTasks(EC2Request): DESCRIPTION = 'Describe current instance-bundling tasks' ARGS = [Arg('BundleId', metavar='BUNDLE', nargs='*', help='limit results to specific bundle tasks')] FILTERS = [Filter('bundle-id', help='bundle task ID'), Filter('error-code', help='if the task failed, the error code returned'), Filter('error-message', help='if the task failed, the error message returned'), Filter('instance-id', help='ID of the bundled instance'), Filter('progress', help='level of task completion, in percent'), Filter('s3-bucket', help='bucket where the image will be stored'), Filter('s3-prefix', help='beginning of the bundle name'), Filter('start-time', help='task start time'), Filter('state', help='task state'), Filter('update-time', help='most recent task update time')] LIST_TAGS = ['bundleInstanceTasksSet'] def print_result(self, result): for task in result.get('bundleInstanceTasksSet', []): self.print_bundle_task(task) euca2ools-3.3.1/euca2ools/commands/ec2/describeconversiontasks.py000066400000000000000000000034471267461563000251100ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg class DescribeConversionTasks(EC2Request): DESCRIPTION = 'Show information about import operations' ARGS = [Arg('ConversionTaskId', metavar='TASK', nargs='*', help='limit results to specific tasks')] LIST_TAGS = ['conversionTasks', 'volumes'] def print_result(self, result): for task in result.get('conversionTasks') or []: self.print_conversion_task(task) euca2ools-3.3.1/euca2ools/commands/ec2/describecustomergateways.py000066400000000000000000000052051267461563000252550ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, Filter, GenericTagFilter from euca2ools.commands.ec2 import EC2Request class DescribeCustomerGateways(EC2Request): DESCRIPTION = 'Show information about VPN customer gateways' ARGS = [Arg('CustomerGatewayId', metavar='CGATEWAY', nargs='*', help='limit results to specific customer gateways')] FILTERS = [Filter('bgp-asn', help='BGP AS number in use'), Filter('customer-gateway-id', help='customer gateway ID'), Filter('ip-address', help='''ID of the customer gateway's cloud-facing interface'''), Filter('state', help='''customer gateway state (pending, available, deleting, deleted)'''), Filter('tag-key', help='key of a tag assigned to the customer gateway'), Filter('tag-value', help='value of a tag assigned to the customer gateway'), GenericTagFilter('tag:KEY', help='specific tag key/value combination'), Filter('type', help='the type of customer gateway (ipsec.1)')] LIST_TAGS = ['customerGatewaySet', 'tagSet'] def print_result(self, result): for cgw in result.get('customerGatewaySet', []): self.print_customer_gateway(cgw) euca2ools-3.3.1/euca2ools/commands/ec2/describedhcpoptions.py000066400000000000000000000046631267461563000242100ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, Filter, GenericTagFilter from euca2ools.commands.ec2 import EC2Request class DescribeDhcpOptions(EC2Request): DESCRIPTION = 'Show information about VPC DHCP option sets' ARGS = [Arg('DhcpOptionsId', metavar='DHCPOPTS', nargs='*', help='limit results to specific DHCP option sets')] FILTERS = [Filter('dhcp-options-id', help='dhcp option set ID'), Filter('key', help='key for one of the options (e.g. domain-name)'), Filter('tag-key', help='key of a tag assigned to the DHCP option set'), Filter('tag-value', help='value of a tag assigned to the DHCP option set'), GenericTagFilter('tag:KEY', help='specific tag key/value combination'), Filter('value', help='value for one of the options')] LIST_TAGS = ['dhcpConfigurationSet', 'dhcpOptionsSet', 'tagSet', 'valueSet'] def print_result(self, result): for dopt in result.get('dhcpOptionsSet', []): self.print_dhcp_options(dopt) euca2ools-3.3.1/euca2ools/commands/ec2/describeimageattribute.py000066400000000000000000000106651267461563000246630ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, MutuallyExclusiveArgList from euca2ools.commands.ec2 import EC2Request class DescribeImageAttribute(EC2Request): DESCRIPTION = 'Show information about an attribute of an image' ARGS = [Arg('ImageId', metavar='IMAGE', help='image to describe'), MutuallyExclusiveArgList( Arg('-l', '--launch-permission', dest='Attribute', action='store_const', const='launchPermission', help='display launch permissions'), Arg('-p', '--product-codes', dest='Attribute', action='store_const', const='productCodes', help='list associated product codes'), Arg('-B', '--block-device-mapping', dest='Attribute', action='store_const', const='blockDeviceMapping', help='describe block device mappings'), Arg('--kernel', dest='Attribute', action='store_const', const='kernel', help='show associated kernel image ID'), Arg('--ramdisk', dest='Attribute', action='store_const', const='ramdisk', help='show associated ramdisk image ID'), Arg('--description', dest='Attribute', action='store_const', const='description', help="show the image's description")) .required()] LIST_TAGS = ['blockDeviceMapping', 'launchPermission', 'productCodes'] def print_result(self, result): image_id = result.get('imageId') for perm in result.get('launchPermission', []): for (entity_type, entity_name) in perm.items(): print self.tabify(('launchPermission', image_id, entity_type, entity_name)) for code in result.get('productCodes', []): if 'type' in code: code_str = '[{0}: {1}]'.format(code['type'], code.get('productCode')) else: code_str = code.get('productCode') print self.tabify(('productCodes', image_id, 'productCode', code_str)) for blockdev in result.get('blockDeviceMapping', []): blockdev_src = (blockdev.get('virtualName') or blockdev.get('ebs', {}).get('snapshotId')) blockdev_str = '{0}: {1}'.format(blockdev.get('deviceName'), blockdev_src) # TODO: figure out how to print mappings that create new volumes print self.tabify(('blockDeviceMapping', image_id, 'blockDeviceMap', blockdev_str)) if result.get('kernel'): print self.tabify(('kernel', image_id, None, result['kernel'].get('value'))) if result.get('ramdisk'): print self.tabify(('ramdisk', image_id, None, result['ramdisk'].get('value'))) if result.get('description'): print self.tabify(('description', image_id, None, result['description'].get('value'))) euca2ools-3.3.1/euca2ools/commands/ec2/describeimages.py000066400000000000000000000171551267461563000231230ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg, Filter, GenericTagFilter from requestbuilder.exceptions import ArgumentError class DescribeImages(EC2Request): DESCRIPTION = ('Show information about images\n\nBy default, only images ' 'your account owns and images for which your account has ' 'explicit launch permissions are shown.') ARGS = [Arg('ImageId', metavar='IMAGE', nargs='*', help='limit results to specific images'), Arg('-a', '--all', action='store_true', route_to=None, help='describe all images'), Arg('-o', '--owner', dest='Owner', metavar='ACCOUNT', action='append', help='describe images owned by the specified owner'), Arg('-x', '--executable-by', dest='ExecutableBy', metavar='ACCOUNT', action='append', help='''describe images for which the specified account has explicit launch permissions''')] FILTERS = [Filter('architecture', help='CPU architecture'), Filter('block-device-mapping.delete-on-termination', help='''whether a volume is deleted upon instance termination'''), Filter('block-device-mapping.device-name', help='device name for a volume mapped to the image'), Filter('block-device-mapping.snapshot-id', help='snapshot ID for a volume mapped to the image'), Filter('block-device-mapping.volume-size', help='volume size for a volume mapped to the image'), Filter('block-device-mapping.volume-type', help='volume type for a volume mapped to the image'), Filter('description', help='image description'), Filter('hypervisor', help='image\'s hypervisor type'), Filter('image-id'), Filter('image-type', help='image type ("machine", "kernel", or "ramdisk")'), Filter('is-public', help='whether the image is public'), Filter('kernel-id'), Filter('manifest-location'), Filter('name'), Filter('owner-alias', help="image owner's account alias"), Filter('owner-id', help="image owner's account ID"), Filter('platform', help='"windows" for Windows images'), Filter('product-code', help='product code associated with the image'), Filter('product-code.type', help='''type of product code associated with the image ("devpay", "marketplace")'''), Filter('ramdisk-id'), Filter('root-device-name'), Filter('root-device-type', help='root device type ("ebs" or "instance-store")'), Filter('state', help='''image state ("available", "pending", or "failed")'''), Filter('state-reason-code', help='reason code for the most recent state change'), Filter('state-reason-message', help='message for the most recent state change'), Filter('tag-key', help='key of a tag assigned to the image'), Filter('tag-value', help='value of a tag assigned to the image'), GenericTagFilter('tag:KEY', help='specific tag key/value combination'), Filter('virtualization-type', help='virtualization type ("paravirtual" or "hvm")')] LIST_TAGS = ['imagesSet', 'productCodes', 'blockDeviceMapping', 'tagSet'] # noinspection PyExceptionInherit def configure(self): EC2Request.configure(self) if self.args.get('all', False): if self.args.get('ImageId'): raise ArgumentError('argument -a/--all: not allowed with ' 'a list of images') if self.args.get('ExecutableBy'): raise ArgumentError('argument -a/--all: not allowed with ' 'argument -x/--executable-by') if self.args.get('Owner'): raise ArgumentError('argument -a/--all: not allowed with ' 'argument -o/--owner') def main(self): if not any(self.args.get(item) for item in ('all', 'ImageId', 'ExecutableBy', 'Owner')): # Default to owned images and images with explicit launch perms self.params['Owner'] = ['self'] owned = self.send() del self.params['Owner'] self.params['ExecutableBy'] = ['self'] executable = self.send() del self.params['ExecutableBy'] owned['imagesSet'] = (owned.get('imagesSet', []) + executable.get('imagesSet', [])) return owned else: return self.send() def print_result(self, result): images = {} for image in result.get('imagesSet', []): images.setdefault(image['imageId'], image) for _, image in sorted(images.iteritems()): self.print_image(image) def print_image(self, image): if image.get('rootDeviceType') == 'instance-store': imagename = image.get('imageLocation') else: imagename = '/'.join((image.get('imageOwnerId', ''), image.get('name'))) print self.tabify(( 'IMAGE', image.get('imageId'), imagename, image.get('imageOwnerAlias') or image.get('imageOwnerId'), image.get('imageState'), ('public' if image.get('isPublic') == 'true' else 'private'), image.get('architecture'), image.get('imageType'), image.get('kernelId'), image.get('ramdiskId'), image.get('platform'), image.get('rootDeviceType'), image.get('virtualizationType'), image.get('hypervisor'))) for mapping in image.get('blockDeviceMapping', []): self.print_blockdevice_mapping(mapping) for tag in image.get('tagSet', []): self.print_resource_tag(tag, image.get('imageId')) euca2ools-3.3.1/euca2ools/commands/ec2/describeinstanceattribute.py000066400000000000000000000146261267461563000254060ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import base64 from requestbuilder import Arg, MutuallyExclusiveArgList from euca2ools.commands.ec2 import EC2Request class DescribeInstanceAttribute(EC2Request): DESCRIPTION = ("Show one of an instance's attributes.\n\n" "Note that exactly one attribute may be shown at a time.") ARGS = [Arg('InstanceId', metavar='INSTANCE', help='ID of the instance to show info for (required)'), MutuallyExclusiveArgList( Arg('-b', '--block-device-mapping', dest='Attribute', action='store_const', const='blockDeviceMapping', help='show block device mappings'), Arg('--disable-api-termination', dest='Attribute', action='store_const', const='disableApiTermination', help='show whether termination is disabled'), Arg('--ebs-optimized', dest='Attribute', action='store_const', const='ebsOptimized', help='''show whether the root volume is optimized for EBS I/O'''), Arg('-g', '--group-id', dest='Attribute', action='store_const', const='groupSet', help='show the security groups the instance belongs to'), Arg('-p', '--product-code', dest='Attribute', action='store_const', const='productCodes', help='show any associated product codes'), Arg('--instance-initiated-shutdown-behavior', dest='Attribute', action='store_const', const='instanceInitiatedShutdownBehavior', help='''show whether the instance stops or terminates when shut down'''), Arg('-t', '--instance-type', dest='Attribute', action='store_const', const='instanceType', help="show the instance's type"), Arg('--kernel', dest='Attribute', action='store_const', const='kernel', help='''show the ID of the kernel image associated with the instance'''), Arg('--ramdisk', dest='Attribute', action='store_const', const='ramdisk', help='''show the ID of the ramdisk image associated with the instance'''), Arg('--root-device-name', dest='Attribute', action='store_const', const='rootDeviceName', help='''show the name of the instance's root device (e.g. '/dev/sda1')'''), Arg('--source-dest-check', dest='Attribute', action='store_const', const='sourceDestCheck', help='''[VPC only] show whether source/destination checking is enabled for the instance'''), Arg('--user-data', dest='Attribute', action='store_const', const='userData', help="show the instance's user-data")) .required()] LIST_TAGS = ['blockDeviceMapping', 'groupSet', 'productCodes'] def print_result(self, result): # Deal with complex data first if self.args['Attribute'] == 'blockDeviceMapping': for mapping in result.get('blockDeviceMapping', []): ebs = mapping.get('ebs', {}) print self.tabify(('BLOCKDEVICE', mapping.get('deviceName'), ebs.get('volumeId'), ebs.get('attachTime'), ebs.get('deleteOnTermination'))) # The EC2 tools have a couple more fields that I haven't been # able to identify. If you figure out what they are, please send # a patch. elif self.args['Attribute'] == 'groupSet': # TODO: test this in the wild (I don't have a VPC to work with) groups = (group.get('groupId') or group.get('groupName') for group in result.get('groupSet', [])) print self.tabify(('groupSet', result.get('instanceId'), ', '.join(groups))) elif self.args['Attribute'] == 'productCodes': # TODO: test this in the wild (I don't have anything I can test # it with) codes = (code.get('productCode') for code in result.get('productCodes', [])) print self.tabify(('productCodes', result.get('instanceId'), ', '.join(codes))) elif self.args['Attribute'] == 'userData': userdata = base64.b64decode(result.get('userData', {}) .get('value', '')) if userdata: print self.tabify(('userData', result.get('instanceId'))) print userdata else: print self.tabify(('userData', result.get('instanceId'), None)) else: attr = result.get(self.args['Attribute']) if isinstance(attr, dict) and 'value' in attr: attr = attr['value'] print self.tabify((self.args['Attribute'], result.get('instanceId'), attr)) euca2ools-3.3.1/euca2ools/commands/ec2/describeinstances.py000066400000000000000000000260731267461563000236440ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg, Filter, GenericTagFilter class DescribeInstances(EC2Request): DESCRIPTION = 'Show information about instances' ARGS = [Arg('InstanceId', metavar='INSTANCE', nargs='*', help='limit results to specific instances')] FILTERS = [Filter('architecture', help='CPU architecture'), Filter('association.allocation-id', help='''[VPC only] allocation ID bound to a network interface's elastic IP address'''), Filter('association.association-id', help='''[VPC only] association ID returned when an elastic IP was associated with a network interface'''), Filter('association.ip-owner-id', help='''[VPC only] ID of the owner of the elastic IP address associated with a network interface'''), Filter('association.public-ip', help='''[VPC only] address of the elastic IP address bound to a network interface'''), Filter('availability-zone'), Filter('block-device-mapping.attach-time', help='volume attachment time'), Filter('block-device-mapping.delete-on-termination', help='''whether a volume is deleted upon instance termination'''), Filter('block-device-mapping.device-name', help='volume device name (e.g. /dev/sdf)'), Filter('block-device-mapping.status', help='volume status'), Filter('block-device-mapping.volume-id', help='volume ID'), Filter('client-token', help='idempotency token provided at instance run time'), Filter('dns-name', help='public DNS name'), # EC2's documentation for "group-id" refers VPC users to # "instance.group-id", while their documentation for the latter # refers them to the former. Consequently, I'm not going to # document a difference for either. They both seem to work for # non-VPC instances. Filter('group-id', help='security group ID'), Filter('group-name', help='security group name'), Filter('hypervisor', help='hypervisor type'), Filter('iam-instance-profile.arn', help="ARN of the instance's instance profile"), Filter('image-id', help='machine image ID'), Filter('instance.group-id', help='security group ID'), Filter('instance.group-name', help='security group name'), Filter('instance-id'), Filter('instance-lifecycle', help='whether this is a spot instance'), Filter('instance-state-code', type=int, help='numeric code identifying instance state'), Filter('instance-state-name', help='instance state'), Filter('instance-type'), Filter('ip-address', help='public IP address'), Filter('kernel-id', help='kernel image ID'), Filter('key-name', help='key pair name provided at instance launch time'), Filter('launch-index', help='launch index within a reservation'), Filter('launch-time', help='instance launch time'), Filter('monitoring-state', help='monitoring state ("enabled" or "disabled")'), Filter('network-interface.addresses.association.ip-owner-id', help='''[VPC only] ID of the owner of the private IP address associated with a network interface'''), Filter('network-interface.addresses.association.public-ip', help='''[VPC only] ID of the association of an elastic IP address with a network interface'''), Filter('network-interface.addresses.primary', help='''[VPC only] whether the IP address of the VPC network interface is the primary private IP address ("true" or "false")'''), Filter('network-interface.addresses.private-ip-address', help='''[VPC only] network interface's private IP address'''), Filter('network-interface.attachment.device-index', type=int, help='''[VPC only] device index to which a network interface is attached'''), Filter('network-interface.attachment.attach-time', help='''[VPC only] time a network interface was attached to an instance'''), Filter('network-interface.attachment.attachment-id', help='''[VPC only] ID of a network interface's attachment'''), Filter('network-interface.attachment.delete-on-termination', help='''[VPC only] whether a network interface attachment is deleted when an instance is terminated ("true" or "false")'''), Filter('network-interface.attachment.instance-owner-id', help='''[VPC only] ID of the instance to which a network interface is attached'''), Filter('network-interface.attachment.status', help="[VPC only] network interface's attachment status"), Filter('network-interface.availability-zone', help="[VPC only] network interface's availability zone"), Filter('network-interface.description', help='[VPC only] description of a network interface'), Filter('network-interface.group-id', help="[VPC only] network interface's security group ID"), Filter('network-interface.group-name', help='''[VPC only] network interface's security group name'''), Filter('network-interface.mac-address', help="[VPC only] network interface's hardware address"), Filter('network-interface.network-interface.id', help='[VPC only] ID of a network interface'), Filter('network-interface.owner-id', help="[VPC only] ID of a network interface's owner"), Filter('network-interface.private-dns-name', help="[VPC only] network interface's private DNS name"), Filter('network-interface.requester-id', help="[VPC only] network interface's requester ID"), Filter('network-interface.requester-managed', help='''[VPC only] whether the network interface is managed by the service'''), Filter('network-interface.source-destination-check', help='''[VPC only] whether source/destination checking is enabled for a network interface ("true" or "false")'''), Filter('network-interface.status', help="[VPC only] network interface's status"), Filter('network-interface.subnet-id', help="[VPC only] ID of a network interface's subnet"), Filter('network-interface.vpc-id', help="[VPC only] ID of a network interface's VPC"), Filter('owner-id', help="instance owner's account ID"), Filter('placement-group-name'), Filter('platform', help='"windows" for Windows instances'), Filter('private-dns-name'), Filter('private-ip-address'), Filter('product-code'), Filter('product-code.type', help='type of product code ("devpay" or "marketplace")'), Filter('ramdisk-id', help='ramdisk image ID'), Filter('reason', help="reason for the instance's current state"), Filter('requester-id', help='ID of the entity that launched an instance'), Filter('reservation-id', help='''ID of the instance's reservation'''), Filter('root-device-name', help='root device name (e.g. /dev/sda1)'), Filter('root-device-type', help='root device type ("ebs" or "instance-store")'), Filter('spot-instance-request-id'), Filter('state-reason-code', help='reason code for the most recent state change'), Filter('state-reason-message', help='message describing the most recent state change'), Filter('subnet-id', help='[VPC only] ID of the subnet the instance is in'), Filter('tag-key', help='name of any tag assigned to the instance'), Filter('tag-value', help='value of any tag assigned to the instance'), GenericTagFilter('tag:KEY', help='specific tag key/value combination'), Filter('virtualization-type'), Filter('vpc-id', help='[VPC only] ID of the VPC the instance is in')] LIST_TAGS = ['reservationSet', 'instancesSet', 'groupSet', 'tagSet', 'blockDeviceMapping', 'productCodes', 'networkInterfaceSet', 'privateIpAddressesSet'] def print_result(self, result): for reservation in result.get('reservationSet'): self.print_reservation(reservation) euca2ools-3.3.1/euca2ools/commands/ec2/describeinstancestatus.py000066400000000000000000000143201267461563000247150ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import datetime from requestbuilder import Arg, Filter from euca2ools.commands.ec2 import EC2Request class DescribeInstanceStatus(EC2Request): DESCRIPTION = 'Show information about instance status and scheduled events' ARGS = [Arg('InstanceId', metavar='INSTANCE', nargs='*', help='limit results to specific instances'), Arg('--hide-healthy', action='store_true', route_to=None, help='hide instances where all status checks pass'), Arg('--include-all-instances', dest='IncludeAllInstances', action='store_true', help='show all instances, not just those that are running')] FILTERS = [Filter('availability-zone'), Filter('event.code', choices=('instance-reboot', 'instance-retirement', 'instance-stop', 'system-maintenance', 'instance-retirement'), help='the code identifying the type of event'), Filter('event.description', help="an event's description"), Filter('event.not-after', help="an event's latest possible end time"), Filter('event.not-before', help="an event's earliest possible start time"), Filter('instance-state-code', type=int, help='numeric code identifying instance state'), Filter('instance-state-name', help='instance state'), Filter('instance-status.status', help="instance's status", choices=('ok', 'impaired', 'initializing', 'insufficient-data', 'not-applicable')), Filter('instance-status.reachability', choices=('passed', 'failed', 'initializing', 'insufficient-data'), help="instance's reachability status"), Filter('system-status.status', help="instance's system status", choices=('ok', 'impaired', 'initializing', 'insufficient-data', 'not-applicable')), Filter('system-status.reachability', choices=('passed', 'failed', 'initializing', 'insufficient-data'), help="instance's system reachability status")] LIST_TAGS = ['instanceStatusSet', 'details', 'eventsSet'] def print_result(self, result): for sset in result.get('instanceStatusSet') or []: if (self.args.get('hide_healthy', False) and sset.get('systemStatus', {}).get('status') == 'ok' and sset.get('instanceStatus', {}).get('status') == 'ok'): continue print self.tabify(( 'INSTANCE', sset.get('instanceId'), sset.get('availabilityZone'), sset.get('instanceState', {}).get('name'), sset.get('instanceState', {}).get('code'), sset.get('instanceStatus', {}).get('status'), sset.get('systemStatus', {}).get('status'), get_retirement_status(sset), get_retirement_date(sset))) for sstatus in sset.get('systemStatus', {}).get('details') or []: print self.tabify(( 'SYSTEMSTATUS', sstatus.get('name'), sstatus.get('status'), sstatus.get('impairedSince'))) for istatus in sset.get('instanceStatus', {}).get('details') or []: print self.tabify(( 'INSTANCESTATUS', istatus.get('name'), istatus.get('status'), istatus.get('impairedSince'))) for event in sset.get('eventsSet') or []: print self.tabify(( 'EVENT', event.get('code'), event.get('notBefore'), event.get('notAfter'), event.get('description'))) def get_retirement_date(status_set): retirement_date = None for event in status_set.get('eventsSet', []): event_start = event.get('notBefore') if event_start is not None: if retirement_date is None: retirement_date = event_start else: date_format = '%Y-%m-%dT%H:%M:%S.%fZ' event_start_datetime = datetime.datetime.strptime( event.get(event_start), date_format) retirement_datetime = datetime.datetime.strptime( retirement_date, date_format) if event_start_datetime < retirement_datetime: retirement_date = event_start return retirement_date def get_retirement_status(status_set): # This is more or less a guess, since retirement status isn't part of the # EC2 API. The value seems to be chosen entirely client-side. if len(status_set.get('eventsSet', [])) > 0: return 'retiring' else: return 'active' euca2ools-3.3.1/euca2ools/commands/ec2/describeinstancetypes.py000066400000000000000000000134421267461563000245420ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin from euca2ools.commands.ec2 import EC2Request class DescribeInstanceTypes(EC2Request, TabifyingMixin): DESCRIPTION = '[Eucalyptus only] Show information about instance types' ARGS = [Arg('InstanceType', metavar='INSTANCETYPE', nargs='*', help='limit results to specific instance types'), Arg('--by-zone', dest='by_zone', action='store_true', route_to=None, help='show info for each availability zone separately'), Arg('--show-capacity', dest='Availability', action='store_true', help='show info about instance capacity')] LIST_TAGS = ['instanceTypeDetails', 'availability'] def configure(self): EC2Request.configure(self) if self.args.get('by_zone', False): self.params['Availability'] = True def print_result(self, result): vmtype_names = [] # Use a list since py2.6 lacks OrderedDict vmtypes = {} # vmtype -> info and total capacity zones = {} # zone -> vmtype -> info and zone capacity for vmtype in result.get('instanceTypeDetails', []): vmtype_names.append(vmtype['name']) vmtypes[vmtype['name']] = {'cpu': vmtype.get('cpu'), 'memory': vmtype.get('memory'), 'disk': vmtype.get('disk'), 'available': 0, 'max': 0} if self.params.get('Availability', False): for zone in vmtype.get('availability', []): available = int(zone.get('available', 0)) max_ = int(zone.get('max', 0)) vmtypes[vmtype['name']]['available'] += available vmtypes[vmtype['name']]['max'] += max_ zones.setdefault(zone['zoneName'], {}) zones[zone['zoneName']][vmtype['name']] = { 'cpu': vmtype.get('cpu'), 'memory': vmtype.get('memory'), 'disk': vmtype.get('disk'), 'available': available, 'max': max_} if self.args.get('by_zone'): for zone, zone_vmtypes in sorted(zones.iteritems()): print self.tabify(('AVAILABILITYZONE', zone)) self._print_vmtypes(zone_vmtypes, vmtype_names) print else: self._print_vmtypes(vmtypes, vmtype_names) def _print_vmtypes(self, vmtypes, vmtype_names): # Fields and column headers fields = {'name': 'Name', 'cpu': 'CPUs', 'memory': 'Memory (MiB)', 'disk': 'Disk (GiB)', 'used': 'Used', 'total': 'Total', 'used_pct': 'Used %'} field_lengths = dict((field, len(header)) for field, header in fields.iteritems()) vmtype_infos = [] for vmtype_name in vmtype_names: total = int(vmtypes[vmtype_name].get('max', 0)) used = total - int(vmtypes[vmtype_name].get('available', 0)) if total != 0: used_pct = '{0:.0%}'.format(float(used) / float(total)) else: used_pct = '' vmtype_info = {'name': vmtype_name, 'cpu': vmtypes[vmtype_name].get('cpu'), 'memory': vmtypes[vmtype_name].get('memory'), 'disk': vmtypes[vmtype_name].get('disk'), 'used': used, 'total': total, 'used_pct': used_pct} vmtype_infos.append(vmtype_info) for field in fields: if len(str(vmtype_info[field])) > field_lengths[field]: field_lengths[field] = len(str(vmtype_info[field])) type_template = ('{{name:<{name}}} {{cpu:>{cpu}}} ' '{{memory:>{memory}}} {{disk:>{disk}}}') if self.args.get('Availability', False): type_template += (' {{used:>{used}}} / {{total:>{total}}} ' '{{used_pct:>{used_pct}}}') type_template = type_template.format(**field_lengths) print 'INSTANCETYPE\t', type_template.format(**fields) for vmtype_info in vmtype_infos: print 'INSTANCETYPE\t', type_template.format(**vmtype_info) euca2ools-3.3.1/euca2ools/commands/ec2/describeinternetgateways.py000066400000000000000000000050511267461563000252430ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, Filter, GenericTagFilter from euca2ools.commands.ec2 import EC2Request class DescribeInternetGateways(EC2Request): DESCRIPTION = 'Describe one or more VPC Internet gateways' ARGS = [Arg('InternetGatewayId', metavar='IGATEWAY', nargs='*', help='limit results to one or more Internet gateways')] FILTERS = [Filter('attachment.state', help='''if the Internet gateway is attached to a VPC, its attachment state (available)'''), Filter('attachment.vpc-id', help='ID of the VPC the Internet gateway is attached to'), Filter('internet-gateway-id', "the Internet gateway's ID"), Filter('tag-key', help='key of a tag assigned to the Internet gateway'), Filter('tag-value', help='value of a tag assigned to the Internet gateway'), GenericTagFilter('tag:KEY', help='specific tag key/value combination')] LIST_TAGS = ['attachmentSet', 'internetGatewaySet', 'tagSet'] def print_result(self, result): for igw in result.get('internetGatewaySet') or []: self.print_internet_gateway(igw) euca2ools-3.3.1/euca2ools/commands/ec2/describekeypairs.py000066400000000000000000000037461267461563000235060ustar00rootroot00000000000000# Copyright 2009-2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg, Filter class DescribeKeyPairs(EC2Request): DESCRIPTION = 'Display information about available key pairs' ARGS = [Arg('KeyName', nargs='*', metavar='KEYPAIR', help='limit results to specific key pairs')] FILTERS = [Filter('fingerprint', help='fingerprint of the key pair'), Filter('key-name', help='name of the key pair')] LIST_TAGS = ['keySet'] def print_result(self, result): for key in result.get('keySet', []): print self.tabify(('KEYPAIR', key.get('keyName'), key.get('keyFingerprint'))) euca2ools-3.3.1/euca2ools/commands/ec2/describenetworkacls.py000066400000000000000000000075401267461563000242070ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, Filter, GenericTagFilter from euca2ools.commands.ec2 import EC2Request class DescribeNetworkAcls(EC2Request): DESCRIPTION = 'Describe one or more network ACLs' ARGS = [Arg('NetworkAclId', metavar='NACL', nargs='*', help='limit results to one or more network ACLs')] FILTERS = [Filter('association.association-id', help='ID of an association ID for a network ACL'), Filter('association.network-acl-id', help='''ID of the network ACL involved in an association'''), Filter('association.subnet-id', help='ID of the subnet involved in an association'), Filter('default', choices=('true', 'false'), help='''whether the network ACL is the default for its VPC'''), Filter('entry.cidr', help='CIDR range for a network ACL entry'), Filter('entry.egress', choices=('true', 'false'), help='whether an entry applies to egress traffic'), Filter('entry.icmp.code', type=int, help='ICMP code for a network ACL entry'), Filter('entry.icmp.type', type=int, help='ICMP type for a network ACL entry'), Filter('entry.port-range.from', type=int, help='start of the port range for a network ACL entry'), Filter('entry.port-range.to', type=int, help='end of the port range for a network ACL entry'), Filter('entry.protocol', help='protocol for a network ACL entry'), Filter('entry.rule-action', choices=('allow', 'deny'), help=''' whether a network ACL entry allows or denies traffic'''), Filter('entry.rule-number', type=int, help='rule number of a network ACL entry'), Filter('network-acl-id'), Filter('tag-key', help='key of a tag assigned to the network ACL'), Filter('tag-value', help='value of a tag assigned to the network ACL'), GenericTagFilter('tag:KEY', help='specific tag key/value combination'), Filter('vpc-id', help="the VPC's ID")] LIST_TAGS = ['associationSet', 'entrySet', 'networkAclSet', 'tagSet'] def print_result(self, result): for acl in result.get('networkAclSet') or []: self.print_network_acl(acl) euca2ools-3.3.1/euca2ools/commands/ec2/describenetworkinterfaceattribute.py000066400000000000000000000072341267461563000271510ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, MutuallyExclusiveArgList from euca2ools.commands.ec2 import EC2Request class DescribeNetworkInterfaceAttribute(EC2Request): DESCRIPTION = 'Show an attribute of a VPC network interface' ARGS = [Arg('NetworkInterfaceId', metavar='INTERFACE', help='ID of the network interface to show info for (required)'), MutuallyExclusiveArgList( Arg('-d', '--description', dest='Attribute', action='store_const', const='description', help="show the interface's description"), Arg('--source-dest-check', dest='Attribute', action='store_const', const='sourceDestCheck', help='show whether source/destination checking is enabled'), Arg('--group-set', dest='Attribute', action='store_const', const='groupSet', help='''show the security groups the network interface belongs to'''), Arg('-a', '--attachment', dest='Attribute', action='store_const', const='attachment', help='''show info about the interface's attachment (if any)''')) .required()] LIST_TAGS = ['groupSet'] def print_result(self, result): print self.tabify(('NETWORKINTERFACE', result.get('networkInterfaceId'), self.args['Attribute'])) if self.args['Attribute'] == 'description': print self.tabify(('DESCRIPTION', result['description'].get('value'))) elif self.args['Attribute'] == 'sourceDestCheck': print self.tabify(('SOURCEDESTCHECK', result['sourceDestCheck'].get('value'))) elif self.args['Attribute'] == 'groupSet': for group in result.get('groupSet') or []: print self.tabify(('GROUP', group.get('groupId'), group.get('groupName'))) elif self.args['Attribute'] == 'attachment': attachment = result.get('attachment') if attachment: attachment_info = [attachment.get(attr) for attr in ( 'attachmentID', 'deviceIndex', 'status', 'attachTime', 'deleteOnTermination')] print self.tabify(['ATTACHMENT'] + attachment_info) euca2ools-3.3.1/euca2ools/commands/ec2/describenetworkinterfaces.py000066400000000000000000000143251267461563000254070ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, Filter, GenericTagFilter from euca2ools.commands.ec2 import EC2Request class DescribeNetworkInterfaces(EC2Request): DESCRIPTION = 'Show information about VPC network interfaces' ARGS = [Arg('NetworkInterfaceId', metavar='INTERFACE', nargs='*', help='limit results to specific network interfaces')] FILTERS = [Filter('addresses.private-ip-addresses', help="the interface's private IP addresses"), Filter('addresses.primary', help='''whether the private IP address is the network interface's primary IP address'''), Filter('addresses.association.public-ip', help='''association ID for the network interface's elastic IP address'''), Filter('addresses.association.owner-id', help='''owner ID of the addresses associated with the network interface'''), Filter('association.association-id', help='''association ID of the network interface's IP Address'''), Filter('association.allocation-id', help='''allocation ID of the network interface's elastic IP address'''), Filter('association.ip-owner-id', help='''owner ID of the network interface's elastic IP address'''), Filter('association.public-ip', help="network interface's elastic IP address"), Filter('association.public-dns-name', help="network interface's public DNS name"), Filter('attachment.attachment-id', help="ID of the network interface's attachment"), Filter('attachment.instance-id', help='''ID of the instance the network interface is attached to'''), Filter('attachment.instance-owner-id', help='''owner ID of the instance the network interface is attached to'''), Filter('attachment.device-index', help='''device index to which the network interface is attached'''), Filter('attachment.status', help='''attachment status (attaching, attached, detaching, detached)'''), Filter('attachment.attach.time', help='time the network interface was attached'), Filter('attachment.delete-on-termination', help='''whether the attachment will be deleted when the associated instance is terminated'''), Filter('availability-zone', help='''availability zone in which the network interface resides'''), Filter('description', help="network interface's description"), Filter('group-id', help='''ID of a security group associated with the network interface'''), Filter('group-name', help='''name of a security group associated with the network interface'''), Filter('mac-address', help='MAC (hardware) address'), Filter('network-interface-id', help='ID of the network interface'), Filter('owner-id', help="account ID of the network interface's owner"), Filter('private-ip-address', help="the network interface's private address(es)"), Filter('private-dns-name', help="the network interface's private DNS name"), Filter('requester-id', help='''ID of the entity that created the network interface'''), Filter('requester-managed', help='''whether the network interface is being managed by one of the cloud's services'''), Filter('source-dest-check', help='''whether the network interface's traffic is subject to source/destination address checking'''), Filter('status', help="the interface's status (available, in-use)"), Filter('subnet-id', help='''ID of the subnet in which the network interface resides'''), Filter('tag-key', help='key of a tag assigned to the network interface'), Filter('tag-value', help='value of a tag assigned to the network interface'), GenericTagFilter('tag:KEY', help='specific tag key/value combination'), Filter('vpc-id', help='''ID of the VPC in which the network interface resides''')] LIST_TAGS = ['groupSet', 'networkInterfaceSet', 'privateIpAddressesSet', 'tagSet'] def print_result(self, result): for nic in result.get('networkInterfaceSet') or []: self.print_interface(nic) euca2ools-3.3.1/euca2ools/commands/ec2/describeregions.py000066400000000000000000000036531267461563000233220ustar00rootroot00000000000000# Copyright 2009-2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg, Filter class DescribeRegions(EC2Request): DESCRIPTION = 'Display information about regions' ARGS = [Arg('RegionName', nargs='*', metavar='REGION', help='limit results to specific regions')] FILTERS = [Filter('endpoint'), Filter('region-name')] LIST_TAGS = ['regionInfo'] def print_result(self, result): for region in result.get('regionInfo', []): print self.tabify(('REGION', region.get('regionName'), region.get('regionEndpoint'))) euca2ools-3.3.1/euca2ools/commands/ec2/describeroutetables.py000066400000000000000000000072661267461563000242110ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, Filter, GenericTagFilter from euca2ools.commands.ec2 import EC2Request class DescribeRouteTables(EC2Request): DESCRIPTION = 'Describe one or more VPC route tables' ARGS = [Arg('RouteTableId', metavar='RTABLE', nargs='*', help='limit results to specific route tables')] FILTERS = [Filter('association.route-table-association-id', help='ID of an association for the route table'), Filter('association.route-table-id', help='ID of a route table involved in an association'), Filter('association.subnet-id', help='ID of a subnet involved in an association'), Filter('association.main', choices=('true', 'false'), help='''whether the route table is the main route table for its VPC'''), Filter('route-table-id'), Filter('route.destination-cidr-block', help='''CIDR address block specified in one of the table's routes'''), Filter('route.gateway-id', help='''ID of a gateway specified by a route in the table'''), Filter('route.instance-id', help='''ID of an instance specified by a route in the table'''), Filter('route.vpc-peering-connection-id', help='''ID of a VPC peering connection specified by a route in the table'''), Filter('route.origin', help='which operation created a route in the table'), Filter('route.state', help='''whether a route in the table has state "active" or "blackhole"'''), Filter('tag-key', help='key of a tag assigned to the route table'), Filter('tag-value', help='value of a tag assigned to the route table'), GenericTagFilter('tag:KEY', help='specific tag key/value combination'), Filter('vpc-id', help="the associated VPC's ID")] LIST_TAGS = ['associationSet', 'propagatingVgwSet', 'routeTableSet', 'routeSet', 'tagSet'] def print_result(self, result): for table in result.get('routeTableSet') or []: self.print_route_table(table) euca2ools-3.3.1/euca2ools/commands/ec2/describesecuritygroups.py000066400000000000000000000143731267461563000247640ustar00rootroot00000000000000# Copyright (c) 2009-2016 Hewlett Packard Enterprise Development LP # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg, Filter, GenericTagFilter class DescribeSecurityGroups(EC2Request): DESCRIPTION = ('Show information about security groups\n\nNote that ' 'filters are matched on literal strings only, so ' '"--filter ip-permission.from-port=22" will *not* match a ' 'group with a port range of 20 to 30.') ARGS = [Arg('group', metavar='GROUP', nargs='*', route_to=None, default=[], help='limit results to specific security groups')] FILTERS = [Filter('description', help='group description'), Filter('group-id'), Filter('group-name'), Filter('ip-permission.cidr', help='CIDR IP range granted permission by the group'), Filter('ip-permission.from-port', help='start of TCP/UDP port range, or ICMP type number'), Filter('ip-permission.group-name', help='''name of another group granted permission by this group'''), Filter('ip-permission.group-id', help='''ID of another group granted permission by this group'''), Filter('ip-permission.protocol', help='IP protocol for the permission'), Filter('ip-permission.to-port', help='end of TCP/UDP port range, or ICMP code'), Filter('ip-permission.user-id', help='ID of an account granted permission'), Filter('owner-id', help="account ID of the group's owner"), Filter('tag-key', help='key of a tag assigned to the group'), Filter('tag-value', help='value of a tag assigned to the group'), GenericTagFilter('tag:KEY', help='specific tag key/value combination'), Filter('vpc-id', help='[VPC only] ID of a VPC the group belongs to')] LIST_TAGS = ['securityGroupInfo', 'ipPermissions', 'ipPermissionsEgress', 'groups', 'ipRanges', 'tagSet'] def preprocess(self): for group in self.args['group']: if group.startswith('sg-'): self.params.setdefault('GroupId', []) self.params['GroupId'].append(group) else: self.params.setdefault('GroupName', []) self.params['GroupName'].append(group) def print_result(self, result): for group in result.get('securityGroupInfo', []): self.print_group(group) def print_group(self, group): print self.tabify(('GROUP', group.get('groupId'), group.get('ownerId'), group.get('groupName'), group.get('groupDescription'), group.get('vpcId'))) for perm in group.get('ipPermissions', []): perm_base = ['PERMISSION', group.get('ownerId'), group.get('groupName'), 'ALLOWS', perm.get('ipProtocol'), perm.get('fromPort'), perm.get('toPort')] for cidr_range in perm.get('ipRanges', []): perm_item = ['FROM', 'CIDR', cidr_range.get('cidrIp'), 'ingress'] print self.tabify(perm_base + perm_item) for othergroup in perm.get('groups', []): perm_item = ['FROM', 'USER', othergroup.get('userId')] if othergroup.get('groupName'): perm_item.extend(['NAME', othergroup['groupName']]) if othergroup.get('groupId'): perm_item.extend(['ID', othergroup['groupId']]) perm_item.append('ingress') print self.tabify(perm_base + perm_item) for perm in group.get('ipPermissionsEgress', []): perm_base = ['PERMISSION', group.get('ownerId'), group.get('groupName'), 'ALLOWS', perm.get('ipProtocol'), perm.get('fromPort'), perm.get('toPort')] for cidr_range in perm.get('ipRanges', []): perm_item = ['TO', 'CIDR', cidr_range.get('cidrIp'), 'egress'] print self.tabify(perm_base + perm_item) for othergroup in perm.get('groups', []): perm_item = ['TO', 'USER', othergroup.get('userId')] if othergroup.get('groupName'): perm_item.extend(['NAME', othergroup['groupName']]) if othergroup.get('groupId'): perm_item.extend(['ID', othergroup['groupId']]) perm_item.append('egress') print self.tabify(perm_base + perm_item) for tag in group.get('tagSet', []): self.print_resource_tag(tag, (group.get('groupId') or group.get('groupName'))) euca2ools-3.3.1/euca2ools/commands/ec2/describesnapshotattribute.py000066400000000000000000000055511267461563000254360ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, MutuallyExclusiveArgList from euca2ools.commands.ec2 import EC2Request class DescribeSnapshotAttribute(EC2Request): DESCRIPTION = 'Show information about an attribute of a snapshot' ARGS = [Arg('SnapshotId', metavar='SNAPSHOT', help='snapshot to describe'), MutuallyExclusiveArgList( Arg('-c', '--create-volume-permission', dest='Attribute', action='store_const', const='createVolumePermission', help='display who can create volumes from the snapshot'), Arg('-p', '--product-codes', dest='Attribute', action='store_const', const='productCodes', help='list associated product codes')) .required()] LIST_TAGS = ['createVolumePermission', 'productCodes'] def print_result(self, result): snapshot_id = result.get('snapshotId') for perm in result.get('createVolumePermission', []): for (entity_type, entity_name) in perm.items(): print self.tabify(('createVolumePermission', snapshot_id, entity_type, entity_name)) for code in result.get('productCodes', []): if 'type' in code: code_str = '[{0}: {1}]'.format(code['type'], code.get('productCode')) else: code_str = code.get('productCode') print self.tabify(('productCodes', snapshot_id, 'productCode', code_str)) euca2ools-3.3.1/euca2ools/commands/ec2/describesnapshots.py000066400000000000000000000110261267461563000236670ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg, Filter, GenericTagFilter from requestbuilder.exceptions import ArgumentError class DescribeSnapshots(EC2Request): DESCRIPTION = ('Show information about snapshots\n\nBy default, only ' 'snapshots your account owns and snapshots for which your ' 'account has explicit restore permissions are shown.') ARGS = [Arg('SnapshotId', nargs='*', metavar='SNAPSHOT', help='limit results to specific snapshots'), Arg('-a', '--all', action='store_true', route_to=None, help='describe all snapshots'), Arg('-o', '--owner', dest='Owner', metavar='ACCOUNT', action='append', default=[], help='limit results to snapshots owned by specific accounts'), Arg('-r', '--restorable-by', dest='RestorableBy', action='append', metavar='ACCOUNT', default=[], help='''limit results to snapahots restorable by specific accounts''')] FILTERS = [Filter('description', help='snapshot description'), Filter('owner-alias', help="snapshot owner's account alias"), Filter('owner-id', help="snapshot owner's account ID"), Filter('progress', help='snapshot progress, in percentage'), Filter('snapshot-id'), Filter('start-time', help='snapshot initiation time'), Filter('status'), Filter('tag-key', help='key of a tag assigned to the snapshot'), Filter('tag-value', help='value of a tag assigned to the snapshot'), GenericTagFilter('tag:KEY', help='specific tag key/value combination'), Filter('volume-id', help='source volume ID'), Filter('volume-size', type=int)] LIST_TAGS = ['snapshotSet', 'tagSet'] # noinspection PyExceptionInherit def configure(self): EC2Request.configure(self) if self.args.get('all'): if self.args.get('Owner'): raise ArgumentError('argument -a/--all: not allowed with ' 'argument -o/--owner') if self.args.get('RestorableBy'): raise ArgumentError('argument -a/--all: not allowed with ' 'argument -r/--restorable-by') def main(self): if not any(self.args.get(item) for item in ('all', 'SnapshotId', 'Owner', 'RestorableBy')): # Default to owned snapshots and those with explicit restore perms self.params['Owner'] = ['self'] owned = self.send() del self.params['Owner'] self.params['RestorableBy'] = ['self'] restorable = self.send() del self.params['RestorableBy'] owned['snapshotSet'] = (owned.get('snapshotSet', []) + restorable.get('snapshotSet', [])) return owned else: return self.send() def print_result(self, result): for snapshot in result.get('snapshotSet', []): self.print_snapshot(snapshot) euca2ools-3.3.1/euca2ools/commands/ec2/describesubnets.py000066400000000000000000000052261267461563000233350ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, Filter, GenericTagFilter from euca2ools.commands.ec2 import EC2Request class DescribeSubnets(EC2Request): DESCRIPTION = 'Show information about one or more VPC subnets' ARGS = [Arg('SubnetId', metavar='SUBNET', nargs='*', help='limit results to specific subnets')] FILTERS = [Filter('availability-zone'), Filter('available-ip-address-count', help='the number of unused IP addresses in the subnet'), Filter('cidr-block', help="the subnet's CIDR address block"), Filter('default-for-az', choices=('true', 'false'), help='''whether this is the default subnet for the availability zone'''), Filter('state'), Filter('subnet-id'), Filter('tag-key', help='key of a tag assigned to the subnet'), Filter('tag-value', help='value of a tag assigned to the subnet'), GenericTagFilter('tag:KEY', help='specific tag key/value combination'), Filter('vpc-id', help="the associated VPC's ID")] LIST_TAGS = ['subnetSet', 'tagSet'] def print_result(self, result): for subnet in result.get('subnetSet') or []: self.print_subnet(subnet) euca2ools-3.3.1/euca2ools/commands/ec2/describetags.py000066400000000000000000000036551267461563000226140ustar00rootroot00000000000000# Copyright 2009-2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Filter from euca2ools.commands.ec2 import EC2Request class DescribeTags(EC2Request): DESCRIPTION = "List tags associated with your account's resources" FILTERS = [Filter('key'), Filter('resource-id'), Filter('resource-type'), Filter('value')] LIST_TAGS = ['tagSet'] def print_result(self, result): for tag in result.get('tagSet', []): print self.tabify(['TAG', tag.get('resourceType'), tag.get('resourceId'), tag.get('key'), tag.get('value')]) euca2ools-3.3.1/euca2ools/commands/ec2/describevolumes.py000066400000000000000000000057721267461563000233520ustar00rootroot00000000000000# Copyright 2009-2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg, Filter, GenericTagFilter class DescribeVolumes(EC2Request): DESCRIPTION = 'Display information about volumes' ARGS = [Arg('VolumeId', metavar='VOLUME', nargs='*', help='limit results to specific volumes')] FILTERS = [Filter('attachment.attach-time', help='attachment start time'), Filter('attachment.delete-on-termination', help='''whether the volume will be deleted upon instance termination'''), Filter('attachment.device', help='device node exposed to the instance'), Filter('attachment.instance-id', help='ID of the instance the volume is attached to'), Filter('attachment.status', help='attachment state'), Filter('availability-zone'), Filter('create-time', help='creation time'), Filter('size', type=int, help='size in GiB'), Filter('snapshot-id', help='snapshot from which the volume was created'), Filter('status'), Filter('tag-key', help='key of a tag assigned to the volume'), Filter('tag-value', help='value of a tag assigned to the volume'), GenericTagFilter('tag:KEY', help='specific tag key/value combination'), Filter(name='volume-id'), Filter(name='volume-type')] LIST_TAGS = ['volumeSet', 'attachmentSet', 'tagSet'] def print_result(self, result): for volume in result.get('volumeSet'): self.print_volume(volume) euca2ools-3.3.1/euca2ools/commands/ec2/describevpcattribute.py000066400000000000000000000047461267461563000243740ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, MutuallyExclusiveArgList from euca2ools.commands.ec2 import EC2Request class DescribeVpcAttribute(EC2Request): DESCRIPTION = 'Show an attribute of a VPC' ARGS = [Arg('VpcId', metavar='VPC', help='ID of the VPC to show info for (required)'), MutuallyExclusiveArgList( Arg('-d', '--dns-hostnames', dest='Attribute', action='store_const', const='enableDnsHostnames', help='''show whether instances in the VPC are assigned DNS hostnames'''), Arg('-s', '--dns-support', dest='Attribute', action='store_const', const='enableDnsSupport', help='show whether DNS resolution is enabled')) .required()] def print_result(self, result): if self.args['Attribute'] == 'enableDnsHostnames': print self.tabify(('RETURN', result['enableDnsHostnames'].get('value'))) elif self.args['Attribute'] == 'enableDnsSupport': print self.tabify(('RETURN', result['enableDnsSupport'].get('value'))) euca2ools-3.3.1/euca2ools/commands/ec2/describevpcpeeringconnections.py000066400000000000000000000064361267461563000262630ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, Filter, GenericTagFilter from euca2ools.commands.ec2 import EC2Request class DescribeVpcPeeringConnections(EC2Request): DESCRIPTION = 'Show information about VPC peering connections' ARGS = [Arg('VpcPeeringConnectionId', metavar='PEERCONN', nargs='*', help='limit results to specific VPC peering connections')] FILTERS = [Filter('accepter-vpc-info.cidr-block', help="the peer VPC's CIDR address block"), Filter('accepter-vpc-info.owner-id', help="the peer VPC's owner's account ID"), Filter('accepter-vpc-info.vpc-id', help="the peer VPC's ID"), Filter('expiration-time', help='when the peering connection request expires'), Filter('requester-vpc-info.cidr-block', help="the requester VPC's CIDR address block"), Filter('requester-vpc-info.owner-id', help="the requester VPC's owner's account ID"), Filter('requester-vpc-info.vpc-id', help="the requester VPC's ID"), Filter('status-code', help='''the peering connection's status (active, deleted, expired, failed, pending-acceptance, provisioning, rejected)'''), Filter('tag-key', help='key of a tag assigned to the peering connection'), Filter('tag-value', help='value of a tag assigned to the peering connection'), GenericTagFilter('tag:KEY', help='specific tag key/value combination'), Filter('vpc-peering-connection-id', help="the peering connection's ID")] LIST_TAGS = ['tagSet', 'vpcPeeringConnectionSet'] def print_result(self, result): for pcx in result.get('vpcPeeringConnectionSet') or []: self.print_peering_connection(pcx) euca2ools-3.3.1/euca2ools/commands/ec2/describevpcs.py000066400000000000000000000045111267461563000226210ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, Filter, GenericTagFilter from euca2ools.commands.ec2 import EC2Request class DescribeVpcs(EC2Request): DESCRIPTION = 'Show information about VPCs' ARGS = [Arg('VpcId', metavar='VPC', nargs='*', help='limit results to specific VPCs')] FILTERS = [Filter('cidr', help="the VPC's CIDR address block"), Filter('dhcp-options-id', help='ID of the set of DHCP options'), Filter('isDefault', help='whether the VPC is a default VPC'), Filter('state'), Filter('tag-key', help='key of a tag assigned to the VPC'), Filter('tag-value', help='value of a tag assigned to the VPC'), GenericTagFilter('tag:KEY', help='specific tag key/value combination'), Filter('vpc-id', help="the VPC's ID")] LIST_TAGS = ['tagSet', 'vpcSet'] def print_result(self, result): for vpc in result.get('vpcSet') or []: self.print_vpc(vpc) euca2ools-3.3.1/euca2ools/commands/ec2/describevpnconnections.py000066400000000000000000000122411267461563000247130ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import sys from requestbuilder import Arg, Filter, GenericTagFilter from euca2ools.commands.ec2 import EC2Request class DescribeVpnConnections(EC2Request): DESCRIPTION = 'Show information about VPN connections' ARGS = [Arg('VpnConnectionId', metavar='VPNCONN', nargs='*', help='limit results to specific VPN connections'), Arg('--format', route_to=None, help='''show connection information in a specific format (cisco-ios-isr, juniper-junos-j, juniper-screenos-6.1, juniper-screenos-6.2, generic, xml, none) (default: none)'''), Arg('--stylesheet', route_to=None, help='''format the connection information using an XSL stylesheet. If the value contains "{format}" it will be replaced with the format chosen by the --format option. If the value is an HTTP or HTTPS URL it will be downloaded as needed. (default: value of "vpn-stylesheet" region option)''')] FILTERS = [Filter('bgp-asn', help='''the BGP AS number advertised by the customer gateway router'''), Filter('customer-gateway-configuration', help='connection information for the customer gateway'), Filter('customer-gateway-id', help='ID of the connected customer gateway'), Filter('state', help='''the VPN connection's state (available, deleting, deleted, pending)'''), Filter('option.static-routes-only', help='''whether the VPN connection is restricted to static routes instead of using BGP'''), Filter('route.destination-cidr-block', help='''the address block corresponding to the subnet used in the data center behind the customer gateway router'''), Filter('tag-key', help='key of a tag assigned to the VPN connection'), Filter('tag-value', help='value of a tag assigned to the VPN connection'), GenericTagFilter('tag:KEY', help='specific tag key/value combination'), Filter('type', help='the type of virtual private gateway (ipsec.1)'), Filter('vpn-connection-id', help='ID of the VPN connection'), Filter('vpn-gateway-id', help='ID of the connected virtual private gateway')] LIST_TAGS = ['vpnConnectionSet', 'tagSet'] def print_result(self, result): if self.args.get('format') is None: stylesheet = self.args.get('stylesheet') show_conn_info = bool(stylesheet) elif self.args.get('format') == 'none': stylesheet = None show_conn_info = False elif self.args.get('format') == 'xml': stylesheet = None show_conn_info = True else: stylesheet = self.args.get('stylesheet') if not stylesheet: stylesheet = self.config.get_region_option('vpn-stylesheet') if stylesheet: stylesheet = stylesheet.format(format=self.args['format']) else: self.log.warn('current region has no stylesheet') msg = ('current region has no XSLT stylesheet to format ' 'output; connection info will not be shown (try ' 'specifying one with "--stylesheet" or using ' '"--format xml")') print >> sys.stderr, msg show_conn_info = bool(stylesheet) for vpn in result.get('vpnConnectionSet', []): self.print_vpn_connection(vpn, show_conn_info=show_conn_info, stylesheet=stylesheet) euca2ools-3.3.1/euca2ools/commands/ec2/describevpngateways.py000066400000000000000000000054001267461563000242140ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, Filter, GenericTagFilter from euca2ools.commands.ec2 import EC2Request class DescribeVpnGateways(EC2Request): DESCRIPTION = 'Show information about virtual private gateways' ARGS = [Arg('VpnGatewayId', metavar='VGATEWAY', nargs='*', help='limit results to specific virtual private gateways')] FILTERS = [Filter('attachment.state', help='state of attachment with a VPC'), Filter('attachment.vpc-id', help='''ID of a VPC the virtual private gateway is attached to'''), Filter('availability-zone', help='''availability zone in which the virtual private gateway resides'''), Filter('tag-key', help='key of a tag assigned to the customer gateway'), Filter('tag-value', help='value of a tag assigned to the customer gateway'), GenericTagFilter('tag:KEY', help='specific tag key/value combination'), Filter('type', help='the type of virtual private gateway (ipsec.1)'), Filter('vpn-gateway-id', help='ID of the virtual private gateway')] LIST_TAGS = ['attachments', 'vpnGatewaySet', 'tagSet'] def print_result(self, result): for vgw in result.get('vpnGatewaySet', []): self.print_vpn_gateway(vgw) euca2ools-3.3.1/euca2ools/commands/ec2/detachinternetgateway.py000066400000000000000000000035601267461563000245330ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class DetachInternetGateway(EC2Request): DESCRIPTION = ('Detach an Internet gateway from a VPC\n\nThe VPC must ' 'contain no running instances with elastic IP addresses.') ARGS = [Arg('-c', '--vpc', dest='VpcId', metavar='VPC', required=True, help='VPC to detach the Internet gateway from (required)'), Arg('InternetGatewayId', metavar='IGATEWAY', help='Internet gateway to detach (required)')] euca2ools-3.3.1/euca2ools/commands/ec2/detachnetworkinterface.py000066400000000000000000000034141267461563000246710ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class DetachNetworkInterface(EC2Request): DESCRIPTION = 'Detach a VPC network interface from an instance' ARGS = [Arg('AttachmentId', metavar='ATTACHMENT', help='ID of the network interface attachment (required)'), Arg('-f', '--force', dest='Force', action='store_true', help='force the network interface to detach immediately')] euca2ools-3.3.1/euca2ools/commands/ec2/detachvolume.py000066400000000000000000000040161267461563000226250ustar00rootroot00000000000000# Copyright 2009-2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg class DetachVolume(EC2Request): DESCRIPTION = 'Detach a volume from an instance' ARGS = [Arg('VolumeId', metavar='VOLUME', help='ID of the volume to detach (required)'), Arg('-i', '--instance', dest='InstanceId', metavar='INSTANCE', help='instance to detach from'), Arg('-d', '--device', dest='Device', help='device name'), Arg('-f', '--force', dest='Force', action='store_true', help='''detach without waiting for the instance. Data may be lost.''')] def print_result(self, result): self.print_attachment(result) euca2ools-3.3.1/euca2ools/commands/ec2/detachvpngateway.py000066400000000000000000000034361267461563000235100ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class DetachVpnGateway(EC2Request): DESCRIPTION = 'Detach a virtual private gateway from a VPC' ARGS = [Arg('-c', '--vpc', dest='VpcId', metavar='VPC', required=True, help='''VPC to attach the virtual private gateway from (required)'''), Arg('VpnGatewayId', metavar='VGATEWAY', help='virtual private gateway to detach (required)')] euca2ools-3.3.1/euca2ools/commands/ec2/disablevgwroutepropagation.py000066400000000000000000000036751267461563000256310ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class DisableVgwRoutePropagation(EC2Request): DESCRIPTION = ('Make a VPC route table stop obtaining routes from a ' 'virtual private gateway') ARGS = [Arg('--route-table', dest='RouteTableId', metavar='RTABLE', required=True, help='''ID of the route table to stop propagating routes to (required)'''), Arg('--vgw', dest='GatewayId', metavar='VGATEWAY', required=True, help='''ID of the virtual private gateway to stop obtaining routes from (required)''')] euca2ools-3.3.1/euca2ools/commands/ec2/disassociateaddress.py000066400000000000000000000053121267461563000241660ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg from requestbuilder.exceptions import ArgumentError class DisassociateAddress(EC2Request): DESCRIPTION = 'Disassociate an elastic IP address from an instance' ARGS = [Arg('PublicIp', metavar='ADDRESS', nargs='?', help='''[Non-VPC only] elastic IP address to disassociate (required)'''), Arg('-a', '--association-id', dest='AssociationId', metavar='ASSOC', help="[VPC only] address's association ID (required)")] # noinspection PyExceptionInherit def configure(self): EC2Request.configure(self) if self.args.get('PublicIp'): if self.args.get('AssociationId'): raise ArgumentError('argument -a/--association-id: not ' 'allowed with an IP address') elif self.args['PublicIp'].startswith('eipassoc'): raise ArgumentError('VPC elastic IP association IDs must be ' 'be specified with -a/--association-id') elif not self.args.get('AssociationId'): raise ArgumentError( 'argument -a/--association-id or an IP address is required') def print_result(self, _): target = self.args.get('PublicIp') or self.args.get('AssociationId') print self.tabify(('ADDRESS', target)) euca2ools-3.3.1/euca2ools/commands/ec2/disassociateroutetable.py000066400000000000000000000032111267461563000247030ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class DisassociateRouteTable(EC2Request): DESCRIPTION = 'Disassociate a VPC subnet from a route table' ARGS = [Arg('AssociationId', metavar='RTBASSOC', help='''ID of the routing table association to remove (required)''')] euca2ools-3.3.1/euca2ools/commands/ec2/enablevgwroutepropagation.py000066400000000000000000000036451267461563000254510ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class EnableVgwRoutePropagation(EC2Request): DESCRIPTION = ('Allow a VPC route table to obtain routes from a ' 'virtual private gateway') ARGS = [Arg('--route-table', dest='RouteTableId', metavar='RTABLE', required=True, help='ID of the route table to propagate routes to (required)'), Arg('--vgw', dest='GatewayId', metavar='VGATEWAY', required=True, help='''ID of the virtual private gateway to obtain routes from (required)''')] euca2ools-3.3.1/euca2ools/commands/ec2/getconsoleoutput.py000066400000000000000000000056011267461563000235710ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import base64 from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg import sys CHAR_ESCAPES = { u'\x00': u'^@', u'\x0c': u'^L', u'\x17': u'^W', u'\x01': u'^A', u'\x0e': u'^N', u'\x18': u'^X', u'\x02': u'^B', u'\x0f': u'^O', u'\x19': u'^Y', u'\x03': u'^C', u'\x10': u'^P', u'\x1a': u'^Z', u'\x04': u'^D', u'\x11': u'^Q', u'\x1b': u'^[', u'\x05': u'^E', u'\x12': u'^R', u'\x1c': u'^\\', u'\x06': u'^F', u'\x13': u'^S', u'\x1d': u'^]', u'\x07': u'^G', u'\x14': u'^T', u'\x1e': u'^^', u'\x08': u'^H', u'\x15': u'^U', u'\x1f': u'^_', u'\x0b': u'^K', u'\x16': u'^V', u'\x7f': u'^?', } class GetConsoleOutput(EC2Request): DESCRIPTION = 'Retrieve console output for the specified instance' ARGS = [Arg('InstanceId', metavar='INSTANCE', help='''ID of the instance to obtain console output from (required)'''), Arg('-r', '--raw-console-output', action='store_true', route_to=None, help='display raw output without escaping control characters')] def print_result(self, result): print result.get('instanceId', '') print result.get('timestamp', '') output = base64.b64decode(result.get('output') or '') output = output.decode(sys.stdout.encoding or 'utf-8', 'replace') output = output.replace(u'\ufffd', u'?') if not self.args['raw_console_output']: # Escape control characters for char, escape in CHAR_ESCAPES.iteritems(): output = output.replace(char, escape) print output euca2ools-3.3.1/euca2ools/commands/ec2/getpassword.py000066400000000000000000000046541267461563000225170ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import base64 from euca2ools.commands.ec2.getpassworddata import GetPasswordData from requestbuilder import Arg import subprocess class GetPassword(GetPasswordData): NAME = 'GetPasswordData' DESCRIPTION = ('Retrieve the administrator password for an instance ' 'running Windows') ARGS = [Arg('-k', '--priv-launch-key', metavar='FILE', required=True, route_to=None, help='''file containing the private key corresponding to the key pair supplied at instance launch time (required)''')] def print_result(self, result): try: pwdata = result['passwordData'] except AttributeError: # The reply didn't contain a passwordData element. raise AttributeError('no password data found for this instance') cmd = subprocess.Popen(['openssl', 'rsautl', '-decrypt', '-inkey', self.args['priv_launch_key']], stdin=subprocess.PIPE, stdout=subprocess.PIPE) stdout, _ = cmd.communicate(base64.b64decode(pwdata)) print stdout euca2ools-3.3.1/euca2ools/commands/ec2/getpassworddata.py000066400000000000000000000037231267461563000233450ustar00rootroot00000000000000# Copyright 2009-2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg class GetPasswordData(EC2Request): DESCRIPTION = ('Retrieve the encrypted administrator password for an ' 'instance running Windows. The encrypted password may be ' 'decrypted using the private key of the key pair given ' 'when launching the instance.') ARGS = [Arg('InstanceId', metavar='INSTANCE', help='''ID of the instance to obtain the initial password for (required)''')] def print_result(self, result): if result.get('passwordData'): print result['passwordData'] euca2ools-3.3.1/euca2ools/commands/ec2/importinstance.py000066400000000000000000000235231267461563000232100ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from __future__ import division import argparse import base64 import math import uuid from requestbuilder import Arg, MutuallyExclusiveArgList from requestbuilder.exceptions import ArgumentError from requestbuilder.mixins import FileTransferProgressBarMixin from euca2ools.commands.argtypes import b64encoded_file_contents, filesize from euca2ools.commands.ec2 import EC2Request from euca2ools.commands.ec2.mixins import S3AccessMixin from euca2ools.commands.ec2.resumeimport import ResumeImport from euca2ools.commands.s3.getobject import GetObject import euca2ools.util class ImportInstance(EC2Request, S3AccessMixin, FileTransferProgressBarMixin): DESCRIPTION = 'Import an instance into the cloud' ARGS = [Arg('source', metavar='FILE', route_to=None, help='file containing the disk image to import (required)'), Arg('-t', '--instance-type', metavar='INSTANCETYPE', required=True, dest='LaunchSpecification.InstanceType', help='the type of instance to import to (required)'), Arg('-f', '--format', dest='DiskImage.1.Image.Format', metavar='FORMAT', required=True, help='''the image's format ("vmdk", "raw", or "vhd") (required)'''), Arg('-a', '--architecture', metavar='ARCH', required=True, dest='LaunchSpecification.Architecture', help="the instance's processor architecture (required)"), Arg('-p', '--platform', dest='Platform', required=True, choices=('Windows', 'Linux'), help="the instance's operating system (required)"), MutuallyExclusiveArgList( Arg('-b', '--bucket', route_to=None, help='the bucket to upload the volume to'), Arg('--manifest-url', metavar='URL', dest='DiskImage.1.Image.ImportManifestUrl', help='''a pre-signed URL that points to the import manifest to use''')) .required(), Arg('--prefix', route_to=None, help='''a prefix to add to the names of the volume parts as they are uploaded'''), Arg('-x', '--expires', metavar='DAYS', type=int, default=30, route_to=None, help='''how long the import manifest should remain valid, in days (default: 30 days)'''), Arg('--no-upload', action='store_true', route_to=None, help='''start the import process, but do not actually upload the volume (see euca-resume-import)'''), Arg('-d', '--description', dest='Description', help='a description for the import task (not the volume)'), Arg('-g', '--group', metavar='GROUP', dest='LaunchSpecification.GroupName.1', help='name of the security group to create the instance in'), Arg('-z', '--availability-zone', metavar='ZONE', dest='LaunchSpecification.Placement.AvailabilityZone', help='the zone in which to create the instance'), Arg('-s', '--volume-size', metavar='GiB', type=int, dest='DiskImage.1.Volume.Size', help='size of the volume to import to, in GiB'), Arg('--image-size', dest='DiskImage.1.Image.Bytes', metavar='BYTES', type=filesize, help='size of the image (required for non-raw files'), MutuallyExclusiveArgList( Arg('--user-data', metavar='DATA', type=base64.b64encode, dest='LaunchSpecification.UserData', help='user data to supply to the instance'), Arg('--user-data-file', metavar='FILE', type=b64encoded_file_contents, dest='LaunchSpecification.UserData', help='''file containing user data to supply to the instance''')), Arg('--subnet', metavar='SUBNET', dest='LaunchSpecification.SubnetId', help='''[VPC only] subnet to create the instance's network interface in'''), Arg('--private-ip-address', metavar='ADDRESS', dest='LaunchSpecification.PrivateIpAddress', help='''[VPC only] assign a specific primary private IP address to the instance's interface'''), Arg('--monitor', action='store_true', dest='LaunchSpecification.Monitoring.Enabled', help='enable detailed monitoring for the instance'), Arg('--instance-initiated-shutdown-behavior', dest='LaunchSpecification.InstanceInitiatedShutdownBehavior', choices=('stop', 'terminate'), help='''whether to "stop" (default) or terminate the instance when it shuts down'''), Arg('--key', dest='LaunchSpecification.KeyName', metavar='KEYPAIR', help='''[Eucalyptus only] name of the key pair to use when running the instance'''), # This is not yet implemented Arg('--ignore-region-affinity', action='store_true', route_to=None, help=argparse.SUPPRESS), # This does no validation, but it does prevent taking action Arg('--dry-run', action='store_true', route_to=None, help=argparse.SUPPRESS), # This is not yet implemented Arg('--dont-verify-format', action='store_true', route_to=None, help=argparse.SUPPRESS)] LIST_TAGS = ['volumes'] def configure(self): EC2Request.configure(self) self.configure_s3_access() if (self.params['DiskImage.1.Image.Format'].upper() in ('VMDK', 'VHD', 'RAW')): self.params['DiskImage.1.Image.Format'] = \ self.params['DiskImage.1.Image.Format'].upper() if not self.params.get('DiskImage.1.Image.Bytes'): if self.params['DiskImage.1.Image.Format'] == 'RAW': image_size = euca2ools.util.get_filesize(self.args['source']) self.params['DiskImage.1.Image.Bytes'] = image_size elif self.params['DiskImage.1.Image.Format'] == 'VMDK': image_size = euca2ools.util.get_vmdk_image_size( self.args['source']) self.params['DiskImage.1.Image.Bytes'] = image_size else: raise ArgumentError( 'argument --image-size is required for {0} files' .format(self.params['DiskImage.1.Image.Format'])) if not self.params.get('DiskImage.1.Volume.Size'): vol_size = math.ceil(self.params['DiskImage.1.Image.Bytes'] / 2 ** 30) self.params['DiskImage.1.Volume.Size'] = int(vol_size) if not self.args.get('expires'): self.args['expires'] = 30 if self.args['expires'] < 1: raise ArgumentError( 'argument -x/--expires: value must be positive') def main(self): if self.args.get('dry_run'): return if self.args.get('bucket'): self.ensure_bucket_exists(self.args['bucket']) if not self.args.get('DiskImage.1.Image.ImportManifestUrl'): manifest_key = '{0}/{1}.manifest.xml'.format(uuid.uuid4(), self.args['source']) if self.args.get('prefix'): manifest_key = '/'.join((self.args['prefix'], manifest_key)) getobj = GetObject.from_other( self, service=self.args['s3_service'], auth=self.args['s3_auth'], source='/'.join((self.args['bucket'], manifest_key))) days = self.args.get('expires') or 30 get_url = getobj.get_presigned_url2(days * 86400) # in seconds self.log.info('generated manifest GET URL: %s', get_url) self.params['DiskImage.1.Image.ImportManifestUrl'] = get_url result = self.send() # The manifest creation and uploading parts are done by ResumeImport. if not self.args.get('no_upload'): resume = ResumeImport.from_other( self, source=self.args['source'], task=result['conversionTask']['conversionTaskId'], s3_service=self.args['s3_service'], s3_auth=self.args['s3_auth'], expires=self.args['expires'], show_progress=self.args.get('show_progress', False)) resume.main() return result def print_result(self, result): self.print_conversion_task(result['conversionTask']) euca2ools-3.3.1/euca2ools/commands/ec2/importkeypair.py000066400000000000000000000040701267461563000230440ustar00rootroot00000000000000# Copyright 2009-2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.argtypes import b64encoded_file_contents from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg class ImportKeyPair(EC2Request): DESCRIPTION = 'Import a public RSA key as a new key pair' ARGS = [Arg('KeyName', metavar='KEYPAIR', help='name for the new key pair (required)'), Arg('-f', '--public-key-file', dest='PublicKeyMaterial', metavar='FILE', type=b64encoded_file_contents, required=True, help='''name of a file containing the public key to import (required)''')] def print_result(self, result): print self.tabify(['KEYPAIR', result.get('keyName'), result.get('keyFingerprint')]) euca2ools-3.3.1/euca2ools/commands/ec2/importvolume.py000066400000000000000000000162171267461563000227150ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from __future__ import division import argparse import math import uuid from requestbuilder import Arg, MutuallyExclusiveArgList from requestbuilder.exceptions import ArgumentError from requestbuilder.mixins import FileTransferProgressBarMixin from euca2ools.commands.argtypes import filesize from euca2ools.commands.ec2 import EC2Request from euca2ools.commands.ec2.mixins import S3AccessMixin from euca2ools.commands.ec2.resumeimport import ResumeImport from euca2ools.commands.s3.getobject import GetObject import euca2ools.util class ImportVolume(EC2Request, S3AccessMixin, FileTransferProgressBarMixin): DESCRIPTION = 'Import a file to a volume in the cloud' ARGS = [Arg('source', metavar='FILE', route_to=None, help='file containing the disk image to import (required)'), Arg('-f', '--format', dest='Image.Format', metavar='FORMAT', required=True, help='''the image's format ("vmdk", "raw", or "vhd") (required)'''), Arg('-z', '--availability-zone', dest='AvailabilityZone', metavar='ZONE', required=True, help='the zone in which to create the volume (required)'), Arg('-s', '--volume-size', metavar='GiB', dest='Volume.Size', type=int, help='size of the volume to import to, in GiB'), Arg('--image-size', dest='Image.Bytes', metavar='BYTES', type=filesize, help='size of the image (required for non-raw files'), MutuallyExclusiveArgList( Arg('-b', '--bucket', route_to=None, help='the bucket to upload the volume to'), Arg('--manifest-url', dest='Image.ImportManifestUrl', metavar='URL', help='''a pre-signed URL that points to the import manifest to use''')) .required(), Arg('--prefix', route_to=None, help='''a prefix to add to the names of the volume parts as they are uploaded'''), Arg('-x', '--expires', metavar='DAYS', type=int, default=30, route_to=None, help='''how long the import manifest should remain valid, in days (default: 30 days)'''), Arg('--no-upload', action='store_true', route_to=None, help='''start the import process, but do not actually upload the volume (see euca-resume-import)'''), Arg('-d', '--description', dest='Description', help='a description for the import task (not the volume)'), # This is not yet implemented Arg('--ignore-region-affinity', action='store_true', route_to=None, help=argparse.SUPPRESS), # This does no validation, but it does prevent taking action Arg('--dry-run', action='store_true', route_to=None, help=argparse.SUPPRESS), # This is not yet implemented Arg('--dont-verify-format', action='store_true', route_to=None, help=argparse.SUPPRESS)] def configure(self): EC2Request.configure(self) self.configure_s3_access() if self.params['Image.Format'].upper() in ('VMDK', 'VHD', 'RAW'): self.params['Image.Format'] = self.params['Image.Format'].upper() if not self.params.get('Image.Bytes'): if self.params['Image.Format'] == 'RAW': image_size = euca2ools.util.get_filesize(self.args['source']) self.params['Image.Bytes'] = image_size elif self.params['Image.Format'] == 'VMDK': image_size = euca2ools.util.get_vmdk_image_size( self.args['source']) self.params['Image.Bytes'] = image_size else: raise ArgumentError( 'argument --image-size is required for {0} files' .format(self.params['Image.Format'])) if not self.params.get('Volume.Size'): vol_size = math.ceil(self.params['Image.Bytes'] / 2 ** 30) self.params['Volume.Size'] = int(vol_size) if not self.args.get('expires'): self.args['expires'] = 30 if self.args['expires'] < 1: raise ArgumentError( 'argument -x/--expires: value must be positive') def main(self): if self.args.get('dry_run'): return if self.args.get('bucket'): self.ensure_bucket_exists(self.args['bucket']) if not self.args.get('Image.ImportManifestUrl'): manifest_key = '{0}/{1}.manifest.xml'.format(uuid.uuid4(), self.args['source']) if self.args.get('prefix'): manifest_key = '/'.join((self.args['prefix'], manifest_key)) getobj = GetObject.from_other( self, service=self.args['s3_service'], auth=self.args['s3_auth'], source='/'.join((self.args['bucket'], manifest_key))) days = self.args.get('expires') or 30 get_url = getobj.get_presigned_url2(days * 86400) # in seconds self.log.info('generated manifest GET URL: %s', get_url) self.params['Image.ImportManifestUrl'] = get_url result = self.send() # The manifest creation and uploading parts are done by ResumeImport. if not self.args.get('no_upload'): resume = ResumeImport.from_other( self, source=self.args['source'], task=result['conversionTask']['conversionTaskId'], s3_service=self.args['s3_service'], s3_auth=self.args['s3_auth'], expires=self.args['expires'], show_progress=self.args.get('show_progress', False)) resume.main() return result def print_result(self, result): self.print_conversion_task(result['conversionTask']) euca2ools-3.3.1/euca2ools/commands/ec2/mixins.py000066400000000000000000000076471267461563000214710ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from requestbuilder import Arg from requestbuilder.exceptions import ArgumentError, ServerError from euca2ools.commands.s3 import S3, S3Request from euca2ools.commands.s3.checkbucket import CheckBucket from euca2ools.commands.s3.createbucket import CreateBucket class S3AccessMixin(object): ARGS = [Arg('--s3-url', metavar='URL', route_to=None, help='object storage service endpoint URL'), Arg('-o', '--owner-akid', metavar='KEY_ID', route_to=None, help='''access key to use for the object storage service (default: same as that for the compute service)'''), Arg('-w', '--owner-sak', metavar='KEY', route_to=None, help='''secret key to use for the object storage service (default: same as that for the compute service)'''), # Pass-throughs Arg('--s3-service', route_to=None, help=argparse.SUPPRESS), Arg('--s3-auth', route_to=None, help=argparse.SUPPRESS)] def configure_s3_access(self): if self.args.get('owner_akid') and not self.args.get('owner_sak'): raise ArgumentError('argument -o/--owner-akid also requires ' '-w/--owner-sak') if self.args.get('owner_sak') and not self.args.get('owner_akid'): raise ArgumentError('argument -w/--owner-sak also requires ' '-o/--owner-akid') if not self.args.get('s3_auth'): if self.args.get('owner_sak') and self.args.get('owner_akid'): self.args['s3_auth'] = S3Request.AUTH_CLASS.from_other( self.auth, key_id=self.args['owner_akid'], secret_key=self.args['owner_sak']) else: self.args['s3_auth'] = S3Request.AUTH_CLASS.from_other( self.auth) if not self.args.get('s3_service'): self.args['s3_service'] = S3.from_other( self.service, url=self.args.get('s3_url')) def ensure_bucket_exists(self, bucket): try: # Ensure the bucket exists req = CheckBucket.from_other(self, service=self.args['s3_service'], auth=self.args['s3_auth'], bucket=bucket) req.main() except ServerError as err: if err.status_code == 404: # No such bucket self.log.info("creating bucket: '%s'", bucket) req = CreateBucket.from_other(req, bucket=bucket) req.main() else: raise euca2ools-3.3.1/euca2ools/commands/ec2/modifyimageattribute.py000066400000000000000000000117511267461563000243670ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, MutuallyExclusiveArgList from requestbuilder.exceptions import ArgumentError from euca2ools.commands.ec2 import EC2Request class ModifyImageAttribute(EC2Request): DESCRIPTION = 'Modify an attribute of an image' ARGS = [Arg('ImageId', metavar='IMAGE', help='image to modify'), MutuallyExclusiveArgList( Arg('--description', dest='Description.Value', metavar='DESC', help="change the image's description"), Arg('-p', '--product-code', dest='ProductCode', metavar='CODE', action='append', help='''product code to add to the given instance-store image'''), Arg('-l', '--launch-permission', action='store_true', route_to=None, help='grant/revoke launch permissions with -a/-r')) .required(), Arg('-a', '--add', metavar='ENTITY', action='append', default=[], route_to=None, help='''account to grant launch permission, or "all" for all accounts'''), Arg('-r', '--remove', metavar='ENTITY', action='append', default=[], route_to=None, help='''account to remove launch permission from, or "all" for all accounts''')] # noinspection PyExceptionInherit def preprocess(self): if self.args.get('launch_permission'): lperm = {} for entity in self.args.get('add', []): lperm.setdefault('Add', []) if entity == 'all': lperm['Add'].append({'Group': entity}) else: lperm['Add'].append({'UserId': entity}) for entity in self.args.get('remove', []): lperm.setdefault('Remove', []) if entity == 'all': lperm['Remove'].append({'Group': entity}) else: lperm['Remove'].append({'UserId': entity}) if not lperm: raise ArgumentError('at least one entity must be specified ' 'with -a/--add or -r/--remove') self.params['LaunchPermission'] = lperm else: if self.args.get('add'): raise ArgumentError('argument -a/--add may only be used ' 'with -l/--launch-permission') if self.args.get('remove'): raise ArgumentError('argument -r/--remove may only be used ' 'with -l/--launch-permission') def print_result(self, _): if self.args.get('Description.Value'): print self.tabify(('description', self.args['ImageId'], None, self.args['Description.Value'])) if self.args.get('ProductCode'): for code in self.args['ProductCode']: print self.tabify(('productcodes', self.args['ImageId'], 'productCode', code)) if self.args.get('launch_permission'): for add in self.params['LaunchPermission'].get('Add', []): for (entity_type, entity_name) in add.items(): print self.tabify(('launchPermission', self.args['ImageId'], 'ADD', entity_type, entity_name)) for add in self.params['LaunchPermission'].get('Remove', []): for (entity_type, entity_name) in add.items(): print self.tabify(('launchPermission', self.args['ImageId'], 'REMOVE', entity_type, entity_name)) euca2ools-3.3.1/euca2ools/commands/ec2/modifyinstanceattribute.py000066400000000000000000000120251267461563000251040ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from requestbuilder import Arg, MutuallyExclusiveArgList from euca2ools.commands.argtypes import b64encoded_file_contents from euca2ools.commands.ec2 import EC2Request def _min_ec2_block_device_mapping(map_as_str): try: device, mapping = map_as_str.split('=') except ValueError: raise argparse.ArgumentTypeError( 'block device mapping "{0}" must have form DEVICE=::true or ' 'DEVICE=::false'.format(map_as_str)) mapping_bits = mapping.split(':') if (len(mapping_bits) != 3 or mapping_bits[0] or mapping_bits[1] or mapping_bits[2] not in ('true', 'false')): raise argparse.ArgumentTypeError( 'block device mapping "{0}" must be either {1}=::true or ' '{1}=::false'.format(map_as_str, device)) return {'DeviceName': device, 'Ebs': {'DeleteOnTermination': mapping_bits[2]}} class ModifyInstanceAttribute(EC2Request): DESCRIPTION = 'Modify an attribute of an instance' ARGS = [Arg('InstanceId', metavar='INSTANCE', help='ID of the instance to modify (required)'), MutuallyExclusiveArgList( Arg('-b', '--block-device-mapping', dest='BlockDeviceMapping', action='append', metavar='DEVICE=::(true|false)', type=_min_ec2_block_device_mapping, default=[], help='''change whether a volume attached to the instance will be deleted upon the instance's termination'''), Arg('--disable-api-termination', choices=('true', 'false'), dest='DisableApiTermination.Value', help='''change whether or not the instance may be terminated'''), Arg('--ebs-optimized', dest='EbsOptimized', choices=('true', 'false'), help='''change whether or not the instance should be optimized for EBS I/O'''), Arg('-g', '--group-id', dest='GroupId', metavar='GROUP', action='append', default=[], help='''[VPC only] Change the security group(s) the instance is in'''), Arg('--instance-initiated-shutdown-behavior', dest='InstanceInitiatedShutdownBehavior.Value', choices=('stop', 'terminate'), help='''whether to stop or terminate the EBS instance when it shuts down (instance-store instances are always terminated)'''), Arg('-t', '--instance-type', dest='InstanceType.Value', metavar='INSTANCETYPE', help="change the instance's type"), Arg('--kernel', dest='Kernel.Value', metavar='IMAGE', help="change the instance's kernel image"), Arg('--ramdisk', dest='Ramdisk.Value', metavar='IMAGE', help="change the instance's ramdisk image"), Arg('--source-dest-check', dest='SourceDestCheck.Value', choices=('true', 'false'), help='''change whether source/destination address checking is enabled'''), Arg('--sriov', dest='SriovNetSupport.Value', metavar='simple', choices=('simple',), help='''enable enhanced networking for the instance and its descendants'''), Arg('--user-data', dest='UserData.Value', metavar='DATA', help='''change the instance's user data (must be base64-encoded)'''), Arg('--user-data-file', dest='UserData.Value', metavar='FILE', type=b64encoded_file_contents, help='''change the instance's user data to the contents of a file''')) .required()] euca2ools-3.3.1/euca2ools/commands/ec2/modifyinstancetypeattribute.py000066400000000000000000000060201267461563000260040ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from requestbuilder.exceptions import ArgumentError from requestbuilder.mixins import TabifyingMixin from euca2ools.commands.ec2 import EC2Request class ModifyInstanceTypeAttribute(EC2Request, TabifyingMixin): DESCRIPTION = '[Eucalyptus cloud admin only] Modify an instance type' ARGS = [Arg('Name', metavar='INSTANCETYPE', help='name of the instance type to modify (required)'), Arg('-c', '--cpus', dest='Cpu', metavar='COUNT', type=int, help='number of virtual CPUs to allocate to each instance'), Arg('-d', '--disk', dest='Disk', metavar='GiB', type=int, help='amount of instance storage to allow each instance'), Arg('-m', '--memory', dest='Memory', metavar='MiB', type=int, help='amount of RAM to allocate to each instance'), Arg('--reset', dest='Reset', action='store_true', help='reset the instance type to its default configuration')] # noinspection PyExceptionInherit def configure(self): EC2Request.configure(self) if (self.args.get('Reset') and any(self.args.get(attr) is not None for attr in ('Cpu', 'Disk', 'Memory'))): # Basically, reset is mutually exclusive with everything else. raise ArgumentError('argument --reset may not be used with ' 'instance type attributes') def print_result(self, result): newtype = result.get('instanceType', {}) print self.tabify(('INSTANCETYPE', newtype.get('name'), newtype.get('cpu'), newtype.get('memory'), newtype.get('disk'))) euca2ools-3.3.1/euca2ools/commands/ec2/modifynetworkaclentry.py000066400000000000000000000130111267461563000246030ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import socket from requestbuilder import Arg, MutuallyExclusiveArgList from requestbuilder.exceptions import ArgumentError from euca2ools.commands.ec2 import EC2Request, parse_ports class _ModifyNetworkAclEntry(EC2Request): DESCRIPTION = ('Modify a network ACL entry\n\nThis is not an ' 'actual EC2 request -- see euca-create-network-acl-' 'entry(1) or euca-replace-network-acl-entry(1) for ' 'something usable.') ARGS = [Arg('NetworkAclId', metavar='NACL', help='ID of the network ACL to add the entry to (required)'), Arg('-n', '--rule-number', dest='RuleNumber', metavar='INT', required=True, type=int, help='rule number for the new entry (required)'), MutuallyExclusiveArgList( Arg('--allow', dest='RuleAction', action='store_const', const='allow', help='make the new entry allow the traffic it matches'), Arg('--deny', dest='RuleAction', action='store_const', const='deny', help='make the new entry block the traffic it matches')) .required(), Arg('-r', '--cidr', dest='CidrBlock', metavar='CIDR', required=True, help='CIDR address range the entry should affect (required)'), Arg('-P', '--protocol', dest='Protocol', default='-1', help='protocol the entry should apply to (default: all)'), Arg('--egress', dest='Egress', action='store_true', help='''make the entry affect outgoing (egress) network traffic (default: affect incoming (ingress) traffic)'''), Arg('-p', '--port-range', dest='port_range', metavar='RANGE', route_to=None, help='''range of ports (specified as "from-to") or a single port number (required for tcp and udp)'''), Arg('-t', '--icmp-type-code', dest='icmp_type_code', metavar='TYPE:CODE', route_to=None, help='''ICMP type and code (specified as "type:code") (required for icmp)''')] def process_cli_args(self): self.process_port_cli_args() def configure(self): EC2Request.configure(self) if not self.params.get('Egress'): self.params['Egress'] = False proto = self.args.get('Protocol') or -1 try: self.params['Protocol'] = int(proto) except ValueError: if proto.lower() == 'all': self.params['Protocol'] = -1 else: try: self.params['Protocol'] = socket.getprotobyname(proto) except socket.error: raise ArgumentError('argument -n/--rule-number: unknown ' 'protocol "{0}"'.format(proto)) from_port, to_port = parse_ports(proto, self.args.get('port_range'), self.args.get('icmp_type_code')) if self.params['Protocol'] == 1: # ICMP self.params['Icmp.Type'] = from_port self.params['Icmp.Code'] = to_port else: self.params['PortRange.From'] = from_port self.params['PortRange.To'] = to_port def print_result(self, _): if self.args.get('Egress'): direction = 'egress' else: direction = 'ingress' protocol = self.params['Protocol'] port_map = {-1: 'all', 1: 'icmp', 6: 'tcp', 17: 'udp', 132: 'sctp'} try: protocol = port_map.get(int(protocol), int(protocol)) except ValueError: pass print self.tabify(( 'ENTRY', direction, self.params.get('RuleNumber'), self.params.get('RuleAction'), self.params.get('CidrBlock'), protocol, self.params.get('Icmp.Type') or self.params.get('PortRange.From'), self.params.get('Icmp.Code') or self.params.get('PortRange.To'))) class CreateNetworkAclEntry(_ModifyNetworkAclEntry): DESCRIPTION = 'Create a new entry in a VPC network ACL' class ReplaceNetworkAclEntry(_ModifyNetworkAclEntry): DESCRIPTION = 'Replace an entry in a VPC network ACL' euca2ools-3.3.1/euca2ools/commands/ec2/modifynetworkinterfaceattribute.py000066400000000000000000000071721267461563000266610ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, MutuallyExclusiveArgList from requestbuilder.exceptions import ArgumentError from euca2ools.commands.argtypes import flexible_bool from euca2ools.commands.ec2 import EC2Request class ModifyNetworkInterfaceAttribute(EC2Request): DESCRIPTION = 'Modify an attribute of a VPC network interface' ARGS = [Arg('NetworkInterfaceId', metavar='INTERFACE', help='ID of the network interface to modify (required)'), MutuallyExclusiveArgList( Arg('-d', '--description', dest='Description.Value', metavar='DESC', help="set the interface's description"), Arg('--source-dest-check', dest='SourceDestCheck.Value', type=flexible_bool, metavar='(true|false)', help='set whether source/destination checking is enabled'), Arg('--group-id', dest='SecurityGroupId', action='append', metavar='GROUP', help='''set the security groups the network interface belongs to (use more than one to specify multiple groups)'''), Arg('-a', '--attachment', dest='Attachment.AttachmentId', metavar='ATTACHMENT', help='''the ID of an attachment to modify. --delete-on-termination is required when this option is used.''')) .required(), Arg('--delete-on-termination', metavar='(true|false)', type=flexible_bool, dest='Attachment.DeleteOnTermination', help='''set whether the interface's attachment will be deleted when the instance terminates (requires -a/--attachment)''')] def configure(self): EC2Request.configure(self) if (self.args.get('Attachment.DeleteOnTermination') is not None and not self.args.get('Attachment.AttachmentId')): raise ArgumentError('argument --delete-on-termination may only be ' 'used with -a/--attachment') if (self.args.get('Attachment.AttachmentId') and self.args.get('Attachment.DeleteOnTermination') is None): raise ArgumentError('argument -a/--attachment also requires ' '--delete-on-termination') euca2ools-3.3.1/euca2ools/commands/ec2/modifysecuritygrouprule.py000066400000000000000000000170741267461563000252010ustar00rootroot00000000000000# Copyright 2012-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import socket from requestbuilder import Arg, MutuallyExclusiveArgList from requestbuilder.exceptions import ArgumentError from euca2ools.commands.ec2 import EC2Request, parse_ports class _ModifySecurityGroupRule(EC2Request): """ The basis for security group-editing commands """ ARGS = [Arg('group', metavar='GROUP', route_to=None, help='name or ID of the security group to modify (required)'), Arg('--egress', action='store_true', route_to=None, help='''[VPC only] manage an egress rule, which controls traffic leaving the group'''), Arg('-P', '--protocol', dest='IpPermissions.1.IpProtocol', metavar='PROTOCOL', default='tcp', help='''the protocol to affect (Non-VPC: tcp, udp, icmp) (VPC only: tcp, udp, icmp, -1/all, other protocol numbers) (default: tcp)'''), Arg('-p', '--port-range', dest='port_range', metavar='RANGE', route_to=None, help='''range of ports (specified as "from-to") or a single port number (required for tcp and udp)'''), Arg('-t', '--icmp-type-code', dest='icmp_type_code', metavar='TYPE:CODE', route_to=None, help='''ICMP type and code (specified as "type:code") (required for icmp)'''), MutuallyExclusiveArgList( Arg('-s', '--cidr', metavar='CIDR', dest='IpPermissions.1.IpRanges.1.CidrIp', help='''IP range (default: 0.0.0.0/0)'''), # ^ default is added by main() Arg('-o', dest='target_group', metavar='GROUP', route_to=None, help='''[Non-VPC only] name of a security group with which to affect network communication''')), Arg('-u', metavar='ACCOUNT', dest='IpPermissions.1.Groups.1.UserId', help='''ID of the account that owns the security group specified with -o''')] def process_cli_args(self): self.process_port_cli_args() # noinspection PyExceptionInherit def configure(self): EC2Request.configure(self) if self.args['group'].startswith('sg-'): # The check could probably be a little better, but meh. Fix if # needed. self.params['GroupId'] = self.args['group'] else: if self.args['egress']: raise ArgumentError('egress rules must use group IDs, not ' 'names') self.params['GroupName'] = self.args['group'] target_group = self.args.get('target_group') if target_group is not None: if target_group.startswith('sg-'): # Same note as above self.params['IpPermissions.1.Groups.1.GroupId'] = target_group else: if self.args['egress']: raise ArgumentError('argument -o: egress rules must use ' 'group IDs, not names') self.params['IpPermissions.1.Groups.1.GroupName'] = target_group protocol = self.args.get('IpPermissions.1.IpProtocol') if str(protocol).lower() in ('icmp', 'tcp', 'udp', '1', '6', '17'): from_port, to_port = parse_ports( protocol, self.args.get('port_range'), self.args.get('icmp_type_code')) self.params['IpPermissions.1.FromPort'] = from_port self.params['IpPermissions.1.ToPort'] = to_port elif str(protocol).lower() in ('all', '-1'): self.params['IpPermissions.1.IpProtocol'] = -1 elif not str(protocol).isdigit(): try: self.params['IpPermissions.1.IpProtocol'] = \ socket.getprotobyname(protocol) except socket.error: raise ArgumentError('argument -P: no such protocol: {0}' .format(protocol)) if (not self.args.get('IpPermissions.1.IpRanges.1.GroupName') and not self.args.get('IpPermissions.1.IpRanges.1.CidrIp')): # Default rule target is the entire Internet self.params['IpPermissions.1.IpRanges.1.CidrIp'] = '0.0.0.0/0' if (self.params.get('IpPermissions.1.Groups.1.GroupName') and not self.args.get('IpPermissions.1.Groups.1.UserId')): raise ArgumentError('argument -u is required when -o names a ' 'security group by name') def print_result(self, _): print self.tabify(['GROUP', self.args.get('group')]) perm_str = ['PERMISSION', self.args.get('group'), 'ALLOWS', self.params.get('IpPermissions.1.IpProtocol'), self.params.get('IpPermissions.1.FromPort'), self.params.get('IpPermissions.1.ToPort')] if self.params.get('IpPermissions.1.Groups.1.UserId'): perm_str.append('USER') perm_str.append(self.params.get('IpPermissions.1.Groups.1.UserId')) if self.params.get('IpPermissions.1.Groups.1.GroupName'): perm_str.append('NAME') perm_str.append(self.params.get( 'IpPermissions.1.Groups.1.GroupName')) if self.params.get('IpPermissions.1.Groups.1.GroupId'): perm_str.append('ID') perm_str.append(self.params.get( 'IpPermissions.1.Groups.1.GroupId')) if self.params.get('IpPermissions.1.IpRanges.1.CidrIp'): perm_str.extend(['FROM', 'CIDR']) perm_str.append(self.params.get( 'IpPermissions.1.IpRanges.1.CidrIp')) print self.tabify(perm_str) class AuthorizeSecurityGroupRule(_ModifySecurityGroupRule): DESCRIPTION = 'Add a rule to a security group that allows traffic to pass' @property def action(self): if self.args['egress']: return 'AuthorizeSecurityGroupEgress' else: return 'AuthorizeSecurityGroupIngress' class RevokeSecurityGroupRule(_ModifySecurityGroupRule): DESCRIPTION = 'Remove a rule from a security group' @property def action(self): if self.args['egress']: return 'RevokeSecurityGroupEgress' else: return 'RevokeSecurityGroupIngress' euca2ools-3.3.1/euca2ools/commands/ec2/modifysnapshotattribute.py000066400000000000000000000104231267461563000251370ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg from requestbuilder.exceptions import ArgumentError class ModifySnapshotAttribute(EC2Request): DESCRIPTION = 'Modify an attribute of a snapshot' ARGS = [Arg('SnapshotId', metavar='SNAPSHOT', help='ID of the snapshot to modify'), Arg('-c', '--create-volume-permission', action='store_true', required=True, route_to=None, help='grant/revoke volume creation permission with -a/-r'), Arg('-a', '--add', metavar='ENTITY', action='append', default=[], route_to=None, help='account to grant permission, or "all" for all accounts'), Arg('-r', '--remove', metavar='ENTITY', action='append', default=[], route_to=None, help='''account to remove permission from, or "all" for all accounts''')] # noinspection PyExceptionInherit def preprocess(self): if self.args.get('create_volume_permission'): cvperm = {} for entity in self.args.get('add', []): cvperm.setdefault('Add', []) if entity == 'all': cvperm['Add'].append({'Group': entity}) else: cvperm['Add'].append({'UserId': entity}) for entity in self.args.get('remove', []): cvperm.setdefault('Remove', []) if entity == 'all': cvperm['Remove'].append({'Group': entity}) else: cvperm['Remove'].append({'UserId': entity}) if not cvperm: raise ArgumentError('at least one entity must be specified ' 'with -a/--add or -r/--remove') self.params['CreateVolumePermission'] = cvperm else: if self.args.get('add'): raise ArgumentError('argument -a/--add may only be used ' 'with -c/--create-volume-permission') if self.args.get('remove'): raise ArgumentError('argument -r/--remove may only be used ' 'with -c/--create-volume-permission') def print_result(self, _): if self.args.get('create_volume_permission'): for add in self.params['CreateVolumePermission'].get('Add', []): for (entity_type, entity_name) in add.items(): print self.tabify(('createVolumePermission', self.args['SnapshotId'], 'ADD', entity_type, entity_name)) for add in self.params['CreateVolumePermission'].get('Remove', []): for (entity_type, entity_name) in add.items(): print self.tabify(('createVolumePermission', self.args['SnapshotId'], 'REMOVE', entity_type, entity_name)) euca2ools-3.3.1/euca2ools/commands/ec2/modifysubnetattribute.py000066400000000000000000000036521267461563000246060ustar00rootroot00000000000000# Copyright 2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.argtypes import flexible_bool from euca2ools.commands.ec2 import EC2Request class ModifySubnetAttribute(EC2Request): DESCRIPTION = 'Modify an attribute of a subnet' ARGS = [Arg('SubnetId', metavar='SUBNET', help='ID of the subnet to modify (required)'), Arg('-m', '--map-public-ip-on-launch', metavar='(true|false)', dest='MapPublicIpOnLaunch.Value', type=flexible_bool, required=True, help='''whether or not new instances in the subnet should be assigned public addresses''')] euca2ools-3.3.1/euca2ools/commands/ec2/modifyvpcattribute.py000066400000000000000000000055041267461563000240740ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from requestbuilder import Arg, MutuallyExclusiveArgList from requestbuilder.exceptions import ArgumentError from euca2ools.commands.argtypes import flexible_bool from euca2ools.commands.ec2 import EC2Request class ModifyVpcAttribute(EC2Request): DESCRIPTION = 'Modify an attribute of a VPC' ARGS = [Arg('-c', '--vpc', dest='VpcId', metavar='VPC', help='ID of the VPC to modify (required)'), Arg('positional_vpc', nargs='?', route_to=None, help=argparse.SUPPRESS), MutuallyExclusiveArgList( Arg('-d', '--dns-hostnames', dest='EnableDnsHostnames.Value', metavar='(true|false)', type=flexible_bool, help='''enable or disable assignment of DNS names to instances'''), Arg('-s', '--dns-support', dest='EnableDnsSupport.Value', metavar='(true|false)', type=flexible_bool, help='enable or disable DNS resolution')) .required()] def configure(self): EC2Request.configure(self) if self.args.get('positional_vpc'): if self.params.get('VpcId'): # Shouldn't be supplied both positionally and optionally raise ArgumentError('unrecognized arguments: {0}'.format( self.args['positional_vpc'])) self.params['VpcId'] = self.args['positional_vpc'] if not self.params.get('VpcId'): raise ArgumentError('argument -c/--vpc is required') euca2ools-3.3.1/euca2ools/commands/ec2/monitorinstances.py000066400000000000000000000037061267461563000235510ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg class MonitorInstances(EC2Request): DESCRIPTION = 'Enable monitoring for one or more instances' ARGS = [Arg('InstanceId', metavar='INSTANCE', nargs='+', help='''ID(s) of the instance(s) to begin monitoring (at least 1 required)''')] LIST_TAGS = ['instancesSet'] def print_result(self, result): for instance in result.get('instancesSet', []): mon_state = 'monitoring-{0}'.format( instance.get('monitoring', {}).get('state')) print self.tabify((instance.get('instanceId'), mon_state)) euca2ools-3.3.1/euca2ools/commands/ec2/rebootinstances.py000066400000000000000000000031711267461563000233500ustar00rootroot00000000000000# Copyright 2009-2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg class RebootInstances(EC2Request): DESCRIPTION = 'Reboot one or more instances' ARGS = [Arg('InstanceId', metavar='INSTANCE', nargs='+', help='''ID(s) of the instance(s) to reboot (at least 1 required)''')] euca2ools-3.3.1/euca2ools/commands/ec2/registerimage.py000066400000000000000000000130311267461563000227710ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from requestbuilder.exceptions import ArgumentError from euca2ools.commands.argtypes import ec2_block_device_mapping from euca2ools.commands.ec2 import EC2Request class RegisterImage(EC2Request): DESCRIPTION = 'Register a new image' ARGS = [Arg('ImageLocation', metavar='MANIFEST', nargs='?', help='''location of the image manifest in S3 storage (required for instance-store images)'''), Arg('-n', '--name', dest='Name', required=True, help='name of the new image (required)'), Arg('-d', '--description', dest='Description', help='description of the new image'), Arg('-a', '--architecture', dest='Architecture', choices=('i386', 'x86_64', 'armhf'), help='CPU architecture of the new image'), Arg('--kernel', dest='KernelId', metavar='KERNEL', help='ID of the kernel to associate with the new image'), Arg('--ramdisk', dest='RamdiskId', metavar='RAMDISK', help='ID of the ramdisk to associate with the new image'), Arg('--root-device-name', dest='RootDeviceName', metavar='DEVICE', help='root device name (default: /dev/sda1)'), # ^ default is added by main() Arg('-s', '--snapshot', route_to=None, help='snapshot to use for the root device'), Arg('-b', '--block-device-mapping', metavar='DEVICE=MAPPED', dest='BlockDeviceMapping', action='append', type=ec2_block_device_mapping, default=[], help='''define a block device mapping for the image, in the form DEVICE=MAPPED, where "MAPPED" is "none", "ephemeral(0-3)", or "[SNAP-ID]:[GiB]:[true|false]:[standard|VOLTYPE[:IOPS]]"'''), Arg('--virtualization-type', dest='VirtualizationType', choices=('paravirtual', 'hvm'), help='virtualization type for the new image'), Arg('--platform', dest='Platform', metavar='windows', choices=('windows',), help="[Privileged] the new image's platform (windows)")] # noinspection PyExceptionInherit def preprocess(self): if self.args.get('ImageLocation'): # instance-store image if self.args.get('RootDeviceName'): raise ArgumentError('argument --root-device-name: not allowed ' 'with argument MANIFEST') if self.args.get('snapshot'): raise ArgumentError('argument --snapshot: not allowed with ' 'argument MANIFEST') else: # Try for an EBS image if not self.params.get('RootDeviceName'): self.params['RootDeviceName'] = '/dev/sda1' snapshot = self.args.get('snapshot') # Look for a mapping for the root device for mapping in self.args['BlockDeviceMapping']: if mapping.get('DeviceName') == self.params['RootDeviceName']: if (snapshot != mapping.get('Ebs', {}).get('SnapshotId') and snapshot): # The mapping's snapshot differs or doesn't exist raise ArgumentError( 'snapshot ID supplied with --snapshot conflicts ' 'with block device mapping for root device {0}' .format(mapping['DeviceName'])) else: # No need to apply --snapshot since the mapping is # already there break else: if snapshot: self.params['BlockDeviceMapping'].append( {'DeviceName': self.params['RootDeviceName'], 'Ebs': {'SnapshotId': snapshot}}) else: raise ArgumentError( 'either a manifest location or a root device snapshot ' 'mapping must be specified') def print_result(self, result): print self.tabify(('IMAGE', result.get('imageId'))) euca2ools-3.3.1/euca2ools/commands/ec2/rejectvpcpeeringconnection.py000066400000000000000000000035161267461563000255700ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class RejectVpcPeeringConnection(EC2Request): DESCRIPTION = ('Reject a request for a VPC peering connection\n\nTo ' 'delete an active VPC peering connection or a ' 'peering connection request you created, use ' 'euca-delete-vpc-peering-connection(1).') ARGS = [Arg('VpcPeeringConnectionId', metavar='PEERCON', help='the VPC peering connection to reject (required)')] euca2ools-3.3.1/euca2ools/commands/ec2/releaseaddress.py000066400000000000000000000051521267461563000231350ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg from requestbuilder.exceptions import ArgumentError class ReleaseAddress(EC2Request): DESCRIPTION = 'Release an elastic IP address' ARGS = [Arg('PublicIp', metavar='ADDRESS', nargs='?', help='[Non-VPC only] address to release (required)'), Arg('-a', '--allocation-id', dest='AllocationId', metavar='ALLOC', help='''[VPC only] allocation ID for the address to release (required)''')] # noinspection PyExceptionInherit def configure(self): EC2Request.configure(self) if (self.args.get('PublicIp') is not None and self.args.get('AllocationId') is not None): # Can't be both EC2 and VPC raise ArgumentError( 'argument -a/--allocation-id: not allowed with an IP address') if (self.args.get('PublicIp') is None and self.args.get('AllocationId') is None): # ...but we still have to be one of them raise ArgumentError( 'argument -a/--allocation-id or an IP address is required') def print_result(self, _): print self.tabify(('ADDRESS', self.args.get('PublicIp'), self.args.get('AllocationId'))) euca2ools-3.3.1/euca2ools/commands/ec2/replacenetworkaclassociation.py000066400000000000000000000037721267461563000261170ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class ReplaceNetworkAclAssociation(EC2Request): DESCRIPTION = 'Associate a new VPC network ACL with a subnet' ARGS = [Arg('AssociationId', metavar='ACLASSOC', help='''ID of the network ACL association to replace (required)'''), Arg('-a', '--network-acl', dest='NetworkAclId', metavar='ACL', required=True, help='''ID of the network ACL to associate with the subnet (required)''')] def print_result(self, result): print self.tabify(('ASSOCIATION', result.get('newAssociationId'), self.args['NetworkAclId'])) euca2ools-3.3.1/euca2ools/commands/ec2/replaceroute.py000066400000000000000000000054011267461563000226360ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, MutuallyExclusiveArgList from euca2ools.commands.ec2 import EC2Request class ReplaceRoute(EC2Request): DESCRIPTION = 'Replace a route in a VPC route table' ARGS = [Arg('RouteTableId', metavar='RTABLE', help='ID of the route table to affect (required)'), Arg('-r', '--cidr', dest='DestinationCidrBlock', metavar='CIDR', required=True, help='destination prefix for route lookup'), MutuallyExclusiveArgList( Arg('-g', '--gateway-id', dest='GatewayId', metavar='GATEWAY', help='ID of an Internet gateway to target'), Arg('-i', '--instance', dest='InstanceId', metavar='INSTANCE', help='ID of a NAT instance to target'), Arg('-n', '--network-interface', dest='NetworkInterfaceId', help='ID of a network interface to target'), Arg('-p', '--vpc-peering-connection', metavar='PEERCON', dest='VpcPeeringConnectionId', help='ID of a VPC peering connection to target')) .required()] def print_result(self, _): target = (self.args.get('GatewayId') or self.args.get('InstanceId') or self.args.get('NetworkInterfaceId') or self.args.get('VpcPeeringConnectionId')) print self.tabify(('ROUTE', target, self.args['DestinationCidrBlock'])) euca2ools-3.3.1/euca2ools/commands/ec2/replaceroutetableassociation.py000066400000000000000000000037241267461563000261110ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class ReplaceRouteTableAssociation(EC2Request): DESCRIPTION = 'Change the route table associated with a VPC subnet' ARGS = [Arg('AssociationId', metavar='RTBASSOC', help='''ID of the route table association to replace (required)'''), Arg('-r', dest='RouteTableId', metavar='RTABLE', required=True, help='route table to associate with the subnet (required)')] def print_result(self, result): print self.tabify(('ASSOCIATION', result.get('newAssociationId'), self.args['RouteTableId'])) euca2ools-3.3.1/euca2ools/commands/ec2/resetimageattribute.py000066400000000000000000000036641267461563000242260ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class ResetImageAttribute(EC2Request): DESCRIPTION = 'Reset an attribute of an image to its default value' ARGS = [Arg('ImageId', metavar='IMAGE', help='''ID of the image whose attribute should be reset (required)'''), Arg('-l', '--launch-permission', dest='Attribute', action='store_const', const='launchPermission', required=True, help='reset launch permissions')] def print_result(self, _): print self.tabify(('launchPermission', self.args['ImageId'], 'RESET')) euca2ools-3.3.1/euca2ools/commands/ec2/resetinstanceattribute.py000066400000000000000000000043701267461563000247430ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, MutuallyExclusiveArgList from euca2ools.commands.ec2 import EC2Request class ResetInstanceAttribute(EC2Request): DESCRIPTION = 'Reset an attribute of an instance to its default value' ARGS = [Arg('InstanceId', metavar='INSTANCE', help='ID of the instance to modify (required)'), MutuallyExclusiveArgList( Arg('--kernel', dest='Attribute', action='store_const', const='kernel', help="reset the instance's kernel image ID"), Arg('--ramdisk', dest='Attribute', action='store_const', const='ramdisk', help="reset the instance's ramdisk image ID"), Arg('--source-dest-check', dest='Attribute', action='store_const', const='sourceDestCheck', help="reset the instance's SourceDestCheck to true")) .required()] euca2ools-3.3.1/euca2ools/commands/ec2/resetnetworkinterfaceattribute.py000066400000000000000000000037461267461563000265170ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class ResetNetworkInterfaceAttribute(EC2Request): DESCRIPTION = 'Reset an attribute of a VPC network interface' ARGS = [Arg('NetworkInterfaceId', metavar='INTERFACE', help='ID of the network interface to reset (required)'), Arg('--source-dest-check', dest='Attribute', required=True, action='store_const', const='sourceDestCheck', help='enable source/destination checking')] def print_result(self, _): print self.tabify((self.params['Attribute'], self.params['NetworkInterfaceId'], 'RESET')) euca2ools-3.3.1/euca2ools/commands/ec2/resetsnapshotattribute.py000066400000000000000000000040461267461563000247760ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.ec2 import EC2Request class ResetSnapshotAttribute(EC2Request): DESCRIPTION = 'Reset an attribute of a snapshot to its default value' ARGS = [Arg('SnapshotId', metavar='SNAPSHOT', help='''ID of the snapshot whose attribute should be reset (required)'''), Arg('-c', '--create-volume-permission', dest='Attribute', action='store_const', const='createVolumePermission', required=True, help='''clear the list of users and groups allowed to create volumes''')] def print_result(self, _): print self.tabify(('createVolumePermission', self.args['SnapshotId'], 'RESET')) euca2ools-3.3.1/euca2ools/commands/ec2/resumeimport.py000066400000000000000000000233041267461563000227010ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse import os.path import tempfile from requestbuilder import Arg from requestbuilder.exceptions import ArgumentError, ServerError from requestbuilder.mixins import FileTransferProgressBarMixin from euca2ools.commands.ec2 import EC2Request from euca2ools.commands.ec2.describeconversiontasks import \ DescribeConversionTasks from euca2ools.commands.ec2.mixins import S3AccessMixin from euca2ools.commands.ec2.structures import ImportManifest, ImportImagePart from euca2ools.commands.s3.deleteobject import DeleteObject from euca2ools.commands.s3.headobject import HeadObject from euca2ools.commands.s3.getobject import GetObject from euca2ools.commands.s3.putobject import PutObject from euca2ools.exceptions import AWSError import euca2ools.util class ResumeImport(EC2Request, S3AccessMixin, FileTransferProgressBarMixin): DESCRIPTION = 'Perform the upload step of an import task' ARGS = [Arg('source', metavar='FILE', help='file containing the disk image to import (required)'), Arg('-t', '--task', required=True, help='the ID of the import task to resume (required)'), Arg('-x', '--expires', metavar='DAYS', type=int, default=30, help='''how long the import manifest should remain valid, in days (default: 30 days)'''), # This is documented, but not implemented in ec2-resume-import Arg('--part-size', metavar='MiB', type=int, default=10, help=argparse.SUPPRESS), # These are not implemented Arg('--user-threads', type=int, help=argparse.SUPPRESS), Arg('--dont-verify-format', action='store_true', help=argparse.SUPPRESS), # This does no validation, but it does prevent taking action Arg('--dry-run', action='store_true', help=argparse.SUPPRESS)] def configure(self): EC2Request.configure(self) self.configure_s3_access() if not self.args.get('expires'): self.args['expires'] = 30 if self.args['expires'] < 1: raise ArgumentError( 'argument -x/--expires: value must be positive') def main(self): if self.args.get('dry_run'): return if self.args.get('show_progress', False): print 'Uploading image for task', self.args['task'] # Manifest desc_conv = DescribeConversionTasks.from_other( self, ConversionTaskId=[self.args['task']]) task = desc_conv.main()['conversionTasks'][0] assert task['conversionTaskId'] == self.args['task'] if task.get('importVolume'): vol_container = task['importVolume'] else: vol_container = task['importInstance']['volumes'][0] file_size = euca2ools.util.get_filesize(self.args['source']) manifest = self.__get_or_create_manifest(vol_container, file_size) file_size_from_manifest = manifest.image_parts[-1].end + 1 if file_size_from_manifest != file_size: raise ArgumentError( 'file "{0}" is not the same size as the file the import ' 'started with (expected: {1}, actual: {2})' .format(self.args['source'], file_size_from_manifest, file_size)) # Now we have a manifest; check to see what parts are already uploaded _, bucket, _ = self.args['s3_service'].resolve_url_to_location( vol_container['image']['importManifestUrl']) pbar_label_template = euca2ools.util.build_progressbar_label_template( [os.path.basename(part.key) for part in manifest.image_parts]) for part in manifest.image_parts: part_s3path = '/'.join((bucket, part.key)) head_req = HeadObject.from_other( self, service=self.args['s3_service'], auth=self.args['s3_auth'], path=part_s3path) try: head_req.main() except AWSError as err: if err.status_code == 404: self.__upload_part(part, part_s3path, pbar_label_template) else: raise # If it is already there we skip it def __get_or_create_manifest(self, vol_container, file_size): _, bucket, key = self.args['s3_service'].resolve_url_to_location( vol_container['image']['importManifestUrl']) manifest_s3path = '/'.join((bucket, key)) try: with tempfile.SpooledTemporaryFile(max_size=1024000) as \ manifest_destfile: get_req = GetObject.from_other( self, service=self.args['s3_service'], auth=self.args['s3_auth'], source=manifest_s3path, dest=manifest_destfile, show_progress=False) get_req.main() self.log.info('using existing import manifest from the server') manifest_destfile.seek(0) manifest = ImportManifest.read_from_fileobj( manifest_destfile) except ServerError as err: if err.status_code == 404: self.log.info('creating new import manifest') manifest = self.__generate_manifest(vol_container, file_size) tempdir = tempfile.mkdtemp() manifest_filename = os.path.join(tempdir, os.path.basename(key)) with open(manifest_filename, 'w') as manifest_file: manifest.dump_to_fileobj(manifest_file, pretty_print=True) put_req = PutObject.from_other( get_req, source=manifest_filename, dest=manifest_s3path, show_progress=False) put_req.main() os.remove(manifest_filename) os.rmdir(tempdir) else: raise return manifest def __generate_manifest(self, vol_container, file_size): days = self.args.get('expires') or 30 timeout = days * 86400 # in seconds _, bucket, key = self.args['s3_service'].resolve_url_to_location( vol_container['image']['importManifestUrl']) key_prefix = key.rsplit('/', 1)[0] manifest = ImportManifest(loglevel=self.log.level) manifest.file_format = vol_container['image']['format'] delete_req = DeleteObject.from_other( self, service=self.args['s3_service'], auth=self.args['s3_auth'], path='/'.join((bucket, key))) manifest.self_destruct_url = delete_req.get_presigned_url2(timeout) manifest.image_size = int(vol_container['image']['size']) manifest.volume_size = int(vol_container['volume']['size']) part_size = (self.args.get('part_size') or 10) * 2 ** 20 # MiB for index, part_start in enumerate(xrange(0, file_size, part_size)): part = ImportImagePart() part.index = index part.start = part_start part.end = min(part_start + part_size, file_size) - 1 part.key = '{0}/{1}.part.{2}'.format( key_prefix, os.path.basename(self.args['source']), index) part_path = '/'.join((bucket, part.key)) head_req = HeadObject.from_other(delete_req, path=part_path) get_req = GetObject.from_other(delete_req, source=part_path) delete_req = DeleteObject.from_other(delete_req, path=part_path) part.head_url = head_req.get_presigned_url2(timeout) part.get_url = get_req.get_presigned_url2(timeout) part.delete_url = delete_req.get_presigned_url2(timeout) manifest.image_parts.append(part) return manifest def __upload_part(self, part, part_s3path, pbar_label_template): self.log.info('Uploading part %s (bytes %i-%i)', part_s3path, part.start, part.end) part_pbar_label = pbar_label_template.format( fname=os.path.basename(part.key), index=(part.index + 1)) with open(self.args['source']) as source: source.seek(part.start) put_req = PutObject.from_other( self, service=self.args['s3_service'], auth=self.args['s3_auth'], source=source, dest=part_s3path, size=(part.end - part.start + 1), show_progress=self.args.get('show_progress', False), progressbar_label=part_pbar_label) return put_req.main() euca2ools-3.3.1/euca2ools/commands/ec2/runinstances.py000066400000000000000000000347571267461563000227000ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import base64 import os.path from requestbuilder import Arg, MutuallyExclusiveArgList from requestbuilder.exceptions import ArgumentError from euca2ools.commands.argtypes import (ec2_block_device_mapping, flexible_bool, vpc_interface) from euca2ools.commands.ec2 import EC2Request class RunInstances(EC2Request): DESCRIPTION = 'Launch instances of a machine image' ARGS = [Arg('ImageId', metavar='IMAGE', help='ID of the image to instantiate (required)'), Arg('-n', '--instance-count', dest='count', metavar='MIN[-MAX]', default='1', route_to=None, help='''number of instances to launch. If this number of instances cannot be launched, no instances will launch. If specified as a range (min-max), the server will attempt to launch the maximum number, but no fewer than the minimum number.'''), Arg('-g', '--group', action='append', default=[], route_to=None, help='security group(s) in which to launch the instances'), Arg('-k', '--key', dest='KeyName', metavar='KEYPAIR', help='name of the key pair to use'), MutuallyExclusiveArgList( Arg('-d', '--user-data', metavar='DATA', route_to=None, help='''user data to make available to instances in this reservation'''), Arg('--user-data-force', metavar='DATA', route_to=None, help='''same as -d/--user-data, but without checking if a file by that name exists first'''), Arg('-f', '--user-data-file', metavar='FILE', route_to=None, help='''file containing user data to make available to the instances in this reservation''')), Arg('--addressing', dest='AddressingType', choices=('public', 'private'), help='''[Eucalyptus only, non-VPC only] addressing scheme to launch the instance with. Use "private" to run an instance with no public address.'''), Arg('-t', '--instance-type', dest='InstanceType', help='type of instance to launch'), Arg('-z', '--availability-zone', metavar='ZONE', dest='Placement.AvailabilityZone'), Arg('--kernel', dest='KernelId', metavar='KERNEL', help='ID of the kernel to launch the instance(s) with'), Arg('--ramdisk', dest='RamdiskId', metavar='RAMDISK', help='ID of the ramdisk to launch the instance(s) with'), Arg('-b', '--block-device-mapping', metavar='DEVICE=MAPPED', dest='BlockDeviceMapping', action='append', type=ec2_block_device_mapping, default=[], help='''define a block device mapping for the instances, in the form DEVICE=MAPPED, where "MAPPED" is "none", "ephemeral(0-3)", or "[SNAP-ID]:[GiB]:[true|false]:[standard|VOLTYPE[:IOPS]]"'''), Arg('-m', '--monitor', dest='Monitoring.Enabled', action='store_const', const='true', help='enable detailed monitoring for the instance(s)'), Arg('--disable-api-termination', dest='DisableApiTermination', action='store_const', const='true', help='prevent API users from terminating the instance(s)'), Arg('--instance-initiated-shutdown-behavior', dest='InstanceInitiatedShutdownBehavior', choices=('stop', 'terminate'), help=('whether to "stop" (default) or terminate EBS instances ' 'when they shut down')), Arg('--placement-group', dest='Placement.GroupName', metavar='PLGROUP', help='''name of a placement group to launch into'''), Arg('--tenancy', dest='Placement.Tenancy', choices=('default', 'dedicated'), help='''[VPC only] "dedicated" to run on single-tenant hardware'''), Arg('--client-token', dest='ClientToken', metavar='TOKEN', help='unique identifier to ensure request idempotency'), Arg('-s', '--subnet', metavar='SUBNET', route_to=None, help='''[VPC only] subnet to create the instance's network interface in'''), Arg('--associate-public-ip-address', type=flexible_bool, route_to=None, help='''[VPC only] assign a public address to the instance's network interface'''), Arg('--private-ip-address', metavar='ADDRESS', route_to=None, help='''[VPC only] assign a specific primary private IP address to an instance's interface'''), MutuallyExclusiveArgList( Arg('--secondary-address', '--secondary-private-ip-address', metavar='ADDRESS', action='append', route_to=None, help='''[VPC only] assign a specific secondary private IP address to an instance's network interface. Use this option multiple times to add additional addresses.'''), Arg('--secondary-count', '--secondary-private-ip-address-count', metavar='COUNT', type=int, route_to=None, help='''[VPC only] automatically assign a specific number of secondary private IP addresses to an instance's network interface''')), Arg('-a', '--network-interface', dest='NetworkInterface', metavar='INTERFACE', action='append', type=vpc_interface, help=('[VPC only] add a network interface to the new ' 'instance. If the interface already exists, supply its ' 'ID and a numeric index for it, separated by ":", in ' 'the form "eni-NNNNNNNN:INDEX". To create a new ' 'interface, supply a numeric index and subnet ID for ' 'it, along with (in order) an optional description, a ' 'primary private IP address, a list of security group ' 'IDs to associate with the interface, whether to delete ' 'the interface upon instance termination ("true" or ' '"false"), a number of secondary private IP addresses ' 'to create automatically, and a list of secondary ' 'private IP addresses to assign to the interface, ' 'separated by ":", in the form ":INDEX:SUBNET:' '[DESCRIPTION]:[PRIV_IP]:[GROUP1,GROUP2,...]:[true|' 'false]:[SEC_IP_COUNT|:SEC_IP1,SEC_IP2,...]". You ' 'cannot specify both of the latter two. This option ' 'may be used multiple times. Each adds another network ' 'interface.')), Arg('-p', '--iam-profile', metavar='IPROFILE', route_to=None, help='''name or ARN of the IAM instance profile to associate with the new instance(s)'''), Arg('--ebs-optimized', dest='EbsOptimized', action='store_const', const='true', help='optimize the new instance(s) for EBS I/O')] LIST_TAGS = ['reservationSet', 'instancesSet', 'groupSet', 'tagSet', 'blockDeviceMapping', 'productCodes', 'networkInterfaceSet', 'privateIpAddressesSet'] # noinspection PyExceptionInherit def configure(self): EC2Request.configure(self) if self.args.get('user_data'): if os.path.isfile(self.args['user_data']): raise ArgumentError( 'argument -d/--user-data: to pass the contents of a file ' 'as user data, use -f/--user-data-file. To pass the ' "literal value '{0}' as user data even though it matches " 'the name of a file, use --user-data-force.') else: self.params['UserData'] = base64.b64encode( self.args['user_data']) elif self.args.get('user_data_force'): self.params['UserData'] = base64.b64encode( self.args['user_data_force']) elif self.args.get('user_data_file'): with open(self.args['user_data_file']) as user_data_file: self.params['UserData'] = base64.b64encode( user_data_file.read()) if self.args.get('KeyName') is None: default_key_name = self.config.get_region_option( 'ec2-default-keypair') if default_key_name: self.log.info("using default key pair '%s'", default_key_name) self.params['KeyName'] = default_key_name # noinspection PyExceptionInherit def preprocess(self): counts = self.args['count'].split('-') if len(counts) == 1: try: self.params['MinCount'] = int(counts[0]) self.params['MaxCount'] = int(counts[0]) except ValueError: raise ArgumentError('argument -n/--instance-count: instance ' 'count must be an integer') elif len(counts) == 2: try: self.params['MinCount'] = int(counts[0]) self.params['MaxCount'] = int(counts[1]) except ValueError: raise ArgumentError('argument -n/--instance-count: instance ' 'count range must be must be comprised of ' 'integers') else: raise ArgumentError('argument -n/--instance-count: value must ' 'have format "1" or "1-2"') if self.params['MinCount'] < 1 or self.params['MaxCount'] < 1: raise ArgumentError('argument -n/--instance-count: instance count ' 'must be positive') if self.params['MinCount'] > self.params['MaxCount']: self.log.debug('MinCount > MaxCount; swapping') self.params.update({'MinCount': self.params['MaxCount'], 'MaxCount': self.params['MinCount']}) iprofile = self.args.get('iam_profile') if iprofile: if iprofile.startswith('arn:'): self.params['IamInstanceProfile.Arn'] = iprofile else: self.params['IamInstanceProfile.Name'] = iprofile if self.args.get('subnet') or self.args.get('NetworkInterface'): # This is going into a VPC. # We can't mix top-level and interface-level parameters, so # build an interface out of all the network-related options # to make the split-up, "friendlier" options work. cli_iface = {} for group in self.args['group']: if not group.startswith('sg-'): raise ArgumentError('argument -g/--group: groups must be ' 'specified by ID when using VPC') cli_iface.setdefault('SecurityGroupId', []) cli_iface['SecurityGroupId'].append(group) if self.args.get('associate_public_ip_address') is not None: cli_iface['AssociatePublicIpAddress'] = \ self.args['associate_public_ip_address'] if self.args.get('private_ip_address'): cli_iface['PrivateIpAddresses'] = [ {'PrivateIpAddress': self.args['private_ip_address'], 'Primary': 'true'}] if self.args.get('secondary_address'): sec_ips = [{'PrivateIpAddress': addr} for addr in self.args['secondary_address']] if not cli_iface.get('PrivateIpAddresses'): cli_iface['PrivateIpAddresses'] = [] cli_iface['PrivateIpAddresses'].extend(sec_ips) if self.args.get('secondary_count'): sec_ip_count = self.args['secondary_count'] cli_iface['SecondaryPrivateIpAddressCount'] = sec_ip_count if self.args.get('subnet'): cli_iface['SubnetId'] = self.args['subnet'] if cli_iface: cli_iface['DeviceIndex'] = 0 if not self.params.get('NetworkInterface'): self.params['NetworkInterface'] = [] self.params['NetworkInterface'].append(cli_iface) self.log.debug('built network interface from CLI options: {0}' .format(cli_iface)) else: # Non-VPC for group in self.args['group']: if group.startswith('sg-'): if not self.params.get('SecurityGroupId'): self.params['SecurityGroupId'] = [] self.params['SecurityGroupId'].append(group) else: if not self.params.get('SecurityGroup'): self.params['SecurityGroup'] = [] self.params['SecurityGroup'].append(group) def print_result(self, result): self.print_reservation(result) euca2ools-3.3.1/euca2ools/commands/ec2/startinstances.py000066400000000000000000000037051267461563000232160ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg class StartInstances(EC2Request): DESCRIPTION = 'Start one or more stopped instances' ARGS = [Arg('InstanceId', metavar='INSTANCE', nargs='+', help='ID(s) of the instance(s) to start')] LIST_TAGS = ['instancesSet'] def print_result(self, result): for instance in result.get('instancesSet', []): print self.tabify(('INSTANCE', instance.get('instanceId'), instance.get('previousState', {}).get('name'), instance.get('currentState', {}).get('name'))) euca2ools-3.3.1/euca2ools/commands/ec2/stopinstances.py000066400000000000000000000041611267461563000230430ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg class StopInstances(EC2Request): DESCRIPTION = 'Stop one or more running instances' ARGS = [Arg('InstanceId', metavar='INSTANCE', nargs='+', help='ID(s) of the instance(s) to stop'), Arg('-f', '--force', dest='Force', action='store_const', const='true', help='immediately stop the instance(s). Data may be lost')] LIST_TAGS = ['instancesSet'] def print_result(self, result): for instance in result.get('instancesSet', []): print self.tabify(('INSTANCE', instance.get('instanceId'), instance.get('previousState', {}).get('name'), instance.get('currentState', {}).get('name'))) euca2ools-3.3.1/euca2ools/commands/ec2/structures.py000066400000000000000000000124131267461563000223700ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import logging import lxml.etree import lxml.objectify import euca2ools class ImportManifest(object): def __init__(self, loglevel=None): self.log = logging.getLogger(self.__class__.__name__) if loglevel is not None: self.log.level = loglevel self.file_format = None self.self_destruct_url = None self.image_size = None self.volume_size = None self.image_parts = [] @classmethod def read_from_file(cls, manifest_filename): with open(manifest_filename) as manifest_fileobj: return cls.read_from_fileobj(manifest_fileobj) @classmethod def read_from_fileobj(cls, manifest_fileobj): xml = lxml.objectify.parse(manifest_fileobj).getroot() manifest = cls() manifest.file_format = xml['file-format'].text manifest.self_destruct_url = xml['self-destruct-url'].text manifest.image_size = int(xml['import'].size) manifest.volume_size = int(xml['import']['volume-size']) manifest.image_parts = [None] * int(xml['import']['parts'] .get('count')) for part in xml['import']['parts']['part']: part_index = int(part.get('index')) part_obj = ImportImagePart() part_obj.index = part_index part_obj.start = int(part['byte-range'].get('start')) part_obj.end = int(part['byte-range'].get('end')) part_obj.key = part['key'].text part_obj.head_url = part['head-url'].text part_obj.get_url = part['get-url'].text part_obj.delete_url = part['delete-url'].text manifest.image_parts[part_index] = part_obj assert None not in manifest.image_parts, 'part missing from manifest' return manifest def dump_to_str(self, pretty_print=False): xml = lxml.objectify.Element('manifest') # Manifest version xml.version = '2010-11-15' # File format xml['file-format'] = self.file_format # Our version xml.importer = None xml.importer.name = 'euca2ools' xml.importer.version = euca2ools.__version__ xml.importer.release = 0 # Import and image part info xml['self-destruct-url'] = self.self_destruct_url xml['import'] = None xml['import']['size'] = self.image_size xml['import']['volume-size'] = self.volume_size xml['import']['parts'] = None xml['import']['parts'].set('count', str(len(self.image_parts))) for part in self.image_parts: xml['import']['parts'].append(part.dump_to_xml()) # Cleanup lxml.objectify.deannotate(xml, xsi_nil=True) lxml.etree.cleanup_namespaces(xml) self.log.debug('-- manifest content --\n', extra={'append': True}) pretty_manifest = lxml.etree.tostring(xml, pretty_print=True).strip() self.log.debug('%s', pretty_manifest, extra={'append': True}) self.log.debug('-- end of manifest content --') return lxml.etree.tostring(xml, pretty_print=pretty_print, encoding='UTF-8', standalone=True, xml_declaration=True).strip() def dump_to_fileobj(self, fileobj, pretty_print=False): fileobj.write(self.dump_to_str(pretty_print=pretty_print)) class ImportImagePart(object): def __init__(self): self.index = None self.start = None self.end = None self.key = None self.head_url = None self.get_url = None self.delete_url = None def dump_to_xml(self): xml = lxml.objectify.Element('part', index=str(self.index)) xml['byte-range'] = None xml['byte-range'].set('start', str(self.start)) xml['byte-range'].set('end', str(self.end)) xml['key'] = self.key xml['head-url'] = self.head_url xml['get-url'] = self.get_url xml['delete-url'] = self.delete_url return xml euca2ools-3.3.1/euca2ools/commands/ec2/terminateinstances.py000066400000000000000000000037111267461563000240460ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg class TerminateInstances(EC2Request): DESCRIPTION = 'Terminate one or more instances' ARGS = [Arg('InstanceId', metavar='INSTANCE', nargs='+', help='ID(s) of the instance(s) to terminate')] LIST_TAGS = ['instancesSet'] def print_result(self, result): for instance in result.get('instancesSet', []): print self.tabify(('INSTANCE', instance.get('instanceId'), instance.get('previousState', {}).get('name'), instance.get('currentState', {}).get('name'))) euca2ools-3.3.1/euca2ools/commands/ec2/unassignprivateipaddresses.py000066400000000000000000000055221267461563000256210ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from requestbuilder import Arg from requestbuilder.exceptions import ArgumentError from euca2ools.commands.ec2 import EC2Request class UnassignPrivateIpAddresses(EC2Request): DESCRIPTION = ('Remove one or more private IP addresses from a ' 'network interface') ARGS = [Arg('-n', '--network-interface', metavar='INTERFACE', dest='NetworkInterfaceId', help='''ID of the network interface to remove addresses from (required)'''), Arg('positional_interface', nargs='?', route_to=None, help=argparse.SUPPRESS), Arg('--secondary-address', '--secondary-private-ip-address', metavar='ADDRESS', dest='PrivateIpAddress', action='append', required=True, help='''an IP address to remove from the network interface. Use this option multiple times to remove additional addresses.''')] def configure(self): EC2Request.configure(self) if self.args.get('positional_interface'): if self.params.get('NetworkInterfaceId'): # Shouldn't be supplied both positionally and optionally raise ArgumentError('unrecognized arguments: {0}'.format( self.args['positional_interface'])) self.params['NetworkInterfaceId'] = \ self.args['positional_interface'] if not self.params.get('NetworkInterfaceId'): raise ArgumentError('argument -n/--network-interface is required') euca2ools-3.3.1/euca2ools/commands/ec2/unmonitorinstances.py000066400000000000000000000037101267461563000241070ustar00rootroot00000000000000# Copyright 2009-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.ec2 import EC2Request from requestbuilder import Arg class UnmonitorInstances(EC2Request): DESCRIPTION = 'Disable monitoring for one or more instances' ARGS = [Arg('InstanceId', metavar='INSTANCE', nargs='+', help='''ID(s) of the instance(s) to stop monitoring (at least 1 required)''')] LIST_TAGS = ['instancesSet'] def print_result(self, result): for instance in result.get('instancesSet', []): mon_state = 'monitoring-{0}'.format( instance.get('monitoring', {}).get('state')) print self.tabify((instance.get('instanceId'), mon_state)) euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/000077500000000000000000000000001267461563000232445ustar00rootroot00000000000000euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/__init__.py000066400000000000000000000050021267461563000253520ustar00rootroot00000000000000# Copyright 2013-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os import sys from requestbuilder import Arg import requestbuilder.auth.aws import requestbuilder.service import requestbuilder.request from euca2ools.commands import Euca2ools from euca2ools.exceptions import AWSError from euca2ools.util import strip_response_metadata, add_fake_region_name class ELB(requestbuilder.service.BaseService): NAME = 'elasticloadbalancing' DESCRIPTION = 'Load balancing service' API_VERSION = '2012-06-01' REGION_ENVVAR = 'AWS_DEFAULT_REGION' URL_ENVVAR = 'AWS_ELB_URL' ARGS = [Arg('-U', '--url', metavar='URL', help='load balancing service endpoint URL')] def configure(self): requestbuilder.service.BaseService.configure(self) add_fake_region_name(self) def handle_http_error(self, response): raise AWSError(response) class ELBRequest(requestbuilder.request.AWSQueryRequest): SUITE = Euca2ools SERVICE_CLASS = ELB AUTH_CLASS = requestbuilder.auth.aws.HmacV4Auth METHOD = 'POST' def parse_response(self, response): response_dict = requestbuilder.request.AWSQueryRequest.parse_response( self, response) return strip_response_metadata(response_dict) euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/addtags.py000066400000000000000000000036011267461563000252250ustar00rootroot00000000000000# Copyright 2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.argtypes import binary_tag_def from euca2ools.commands.elasticloadbalancing import ELBRequest class AddTags(ELBRequest): DESCRIPTION = 'Add one or more tags to a load balancer' ARGS = [Arg('LoadBalancerNames.member.1', metavar='ELB', help='name of the load balancer to tag (required)'), Arg('-t', '--tag', dest='Tags.member', required=True, action='append', metavar='KEY=VALUE', type=binary_tag_def, help='key and value of each tag to add (required)')] euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/applysecuritygroupstoloadbalancer.py000066400000000000000000000045331267461563000326730ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.argtypes import delimited_list from euca2ools.commands.elasticloadbalancing import ELBRequest from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin class ApplySecurityGroupsToLoadBalancer(ELBRequest, TabifyingMixin): DESCRIPTION = ('[VPC only] Associate one or more security groups with a ' 'load balancer. All previous associations with security ' 'groups will be replaced.') ARGS = [Arg('LoadBalancerName', metavar='ELB', help='name of the load balancer to modify (required)'), Arg('-g', '--security-groups', dest='SecurityGroups.member', metavar='GROUP1,GROUP2,...', type=delimited_list(','), required=True, help='''security groups to associate the load balancer with (required)''')] LIST_TAGS = ['SecurityGroups'] def print_result(self, result): print self.tabify(('SECURITY_GROUPS', ', '.join(result.get('SecurityGroups', [])))) euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/argtypes.py000066400000000000000000000113011267461563000254500ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse def listener(listener_str): pairs = {} for pair_str in listener_str.strip().split(','): if pair_str: try: key, val = pair_str.split('=') except ValueError: raise argparse.ArgumentTypeError( "listener '{0}': element '{1}' must have format KEY=VALUE" .format(listener_str, pair_str)) pairs[key.strip()] = val.strip() extra_keys = (set(pairs.keys()) - set(('protocol', 'lb-port', 'instance-port', 'instance-protocol', 'cert-id'))) if len(extra_keys) > 0: raise argparse.ArgumentTypeError( "listener '{0}': invalid element(s): {1}".format( listener_str, ', '.join("'{0}'".format(key) for key in extra_keys))) listener_dict = {} if 'protocol' in pairs: if pairs['protocol'].upper() in ('HTTP', 'HTTPS', 'SSL', 'TCP'): listener_dict['Protocol'] = pairs['protocol'].upper() else: raise argparse.ArgumentTypeError( "listener '{0}': protocol '{1}' is invalid (choose from " "'HTTP', 'HTTPS', 'SSL', 'TCP')" .format(listener_str, pairs['protocol'])) else: raise argparse.ArgumentTypeError( "listener '{0}': protocol is required".format(listener_str)) if 'lb-port' in pairs: try: listener_dict['LoadBalancerPort'] = int(pairs['lb-port']) except ValueError: raise argparse.ArgumentTypeError( "listener '{0}': lb-port must be an integer" .format(listener_str)) else: raise argparse.ArgumentTypeError( "listener '{0}': lb-port is required".format(listener_str)) if 'instance-port' in pairs: try: listener_dict['InstancePort'] = int(pairs['instance-port']) except ValueError: raise argparse.ArgumentTypeError( "listener '{0}': instance-port must be an integer" .format(listener_str)) else: raise argparse.ArgumentTypeError( "listener '{0}': instance-port is required".format(listener_str)) if 'instance-protocol' in pairs: if pairs['instance-protocol'].upper() in ('HTTP', 'HTTPS'): if pairs['protocol'].upper() not in ('HTTP', 'HTTPS'): raise argparse.ArgumentTypeError( "listener '{0}': instance-protocol must be 'HTTP' or " "'HTTPS' when protocol is 'HTTP' or 'HTTPS'" .format(listener_str)) elif pairs['instance-protocol'].upper() in ('SSL', 'TCP'): if pairs['protocol'].upper() not in ('SSL', 'TCP'): raise argparse.ArgumentTypeError( "listener '{0}': instance-protocol must be 'SSL' or " "'TCP' when protocol is 'SSL' or 'TCP'" .format(listener_str)) else: raise argparse.ArgumentTypeError( "listener '{0}': instance-protocol '{1}' is invalid (choose " "from 'HTTP', 'HTTPS', 'SSL', 'TCP')" .format(listener_str, pairs['instance-protocol'])) listener_dict['InstanceProtocol'] = pairs['instance-protocol'].upper() if 'cert-id' in pairs: listener_dict['SSLCertificateId'] = pairs['cert-id'] return listener_dict euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/attachloadbalancertosubnets.py000066400000000000000000000042211267461563000313600ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.argtypes import delimited_list from euca2ools.commands.elasticloadbalancing import ELBRequest from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin class AttachLoadBalancerToSubnets(ELBRequest, TabifyingMixin): DESCRIPTION = '[VPC only] Add a load balancer to one or more subnets' ARGS = [Arg('LoadBalancerName', metavar='ELB', help='name of the load balancer to modify (required)'), Arg('-s', '--subnets', dest='Subnets.member', required=True, metavar='SUBNET1,SUBNET2,...', type=delimited_list(','), help='''IDs of the subnets to add the load balancer to (required)''')] LIST_TAGS = ['Subnets'] def print_result(self, result): print self.tabify(('SUBNETS', ', '.join(result.get('Subnets', [])))) euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/configurehealthcheck.py000066400000000000000000000101751267461563000277670ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.elasticloadbalancing import ELBRequest from requestbuilder import Arg from requestbuilder.exceptions import ArgumentError from requestbuilder.mixins import TabifyingMixin class ConfigureHealthCheck(ELBRequest, TabifyingMixin): DESCRIPTION = ('Configure health checking for instance registerd with a ' 'load balancer') ARGS = [Arg('LoadBalancerName', metavar='ELB', help='name of the load balancer to modify (required)'), Arg('--healthy-threshold', dest='HealthCheck.HealthyThreshold', metavar='COUNT', type=int, required=True, help='''number of consecutive successful health checks that will mark instances as Healthy (required)'''), Arg('--interval', dest='HealthCheck.Interval', metavar='SECONDS', type=int, required=True, help='approximate interval between health checks (required)'), Arg('-t', '--target', dest='HealthCheck.Target', metavar='PROTOCOL:PORT[/PATH]', required=True, help='connection target for health checks (required)'), Arg('--timeout', dest='HealthCheck.Timeout', metavar='SECONDS', type=int, required=True, help='maximum health check duration (required)'), Arg('--unhealthy-threshold', dest='HealthCheck.UnhealthyThreshold', metavar='COUNT', type=int, required=True, help='''number of consecutive failed health checks that will mark instances as Unhealthy (required)''')] # noinspection PyExceptionInherit def configure(self): ELBRequest.configure(self) target = self.args['HealthCheck.Target'] protocol, _, rest = target.partition(':') if not rest: raise ArgumentError('argument -t/--target: must have form ' 'PROTOCOL:PORT[/PATH]') if protocol.lower() in ('http', 'https') and '/' not in rest: raise ArgumentError('argument -t/--target: path is required for ' "protocol '{0}'".format(protocol)) def preprocess(self): # Be nice and auto-capitalize known protocols for people target = self.args['HealthCheck.Target'] protocol = target.split(':', 1)[0] if protocol.lower() in ('http', 'https', 'ssl', 'tcp'): self.params['HealthCheck.Target'] = target.replace( protocol, protocol.upper(), 1) def print_result(self, result): check = result.get('HealthCheck', {}) print self.tabify(('HEALTH_CHECK', check.get('Target'), check.get('Interval'), check.get('Timeout'), check.get('HealthyThreshold'), check.get('UnhealthyThreshold'))) euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/createappcookiestickinesspolicy.py000066400000000000000000000045611267461563000323020ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.elasticloadbalancing import ELBRequest from requestbuilder import Arg class CreateAppCookieStickinessPolicy(ELBRequest): DESCRIPTION = ('Create a new stickiness policy for a load balancer, ' 'whereby the server application generates a cookie and ' 'adds it to its responses. The load balancer will then ' 'use this cookie to route requests from each user to the ' 'same back end instance. This type of policy can only be ' 'associated with HTTP or HTTPS listeners,') ARGS = [Arg('LoadBalancerName', metavar='ELB', help='name of the load balancer to modify (required)'), # -c is for cookie. That's good enough for me. Arg('-c', '--cookie-name', dest='CookieName', required=True, help='name of the cookie used for stickiness (required)'), Arg('-p', '--policy-name', dest='PolicyName', metavar='POLICY', required=True, help='name of the new policy (required)')] euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/createlbcookiestickinesspolicy.py000066400000000000000000000045601267461563000321160ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.elasticloadbalancing import ELBRequest from requestbuilder import Arg class CreateLBCookieStickinessPolicy(ELBRequest): DESCRIPTION = ('Create a new stickiness policy for a load balancer, ' 'whereby the load balancer automatically generates cookies ' 'that it uses to route requests from each user to the same ' 'back end instance. This type of policy can only be ' 'associated with HTTP or HTTPS listeners.') ARGS = [Arg('LoadBalancerName', metavar='ELB', help='name of the load balancer to modify (required)'), Arg('-e', '--expiration-period', dest='CookieExpirationPeriod', metavar='SECONDS', type=int, required=True, help='''time period after which cookies should be considered stale (default: user's session length) (required)'''), Arg('-p', '--policy-name', dest='PolicyName', metavar='POLICY', required=True, help='name of the new policy (required)')] euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/createloadbalancer.py000066400000000000000000000103261267461563000274130ustar00rootroot00000000000000# Copyright (c) 2013-2016 Hewlett Packard Enterprise Development LP # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, MutuallyExclusiveArgList from requestbuilder.mixins import TabifyingMixin from euca2ools.commands.argtypes import binary_tag_def, delimited_list from euca2ools.commands.elasticloadbalancing import ELBRequest from euca2ools.commands.elasticloadbalancing.argtypes import listener class CreateLoadBalancer(ELBRequest, TabifyingMixin): DESCRIPTION = ('Create a load balancer\n\nAfter the load balancer is ' 'created, instances must be registered with it separately.') ARGS = [Arg('LoadBalancerName', metavar='ELB', help='name of the new load balancer (required)'), MutuallyExclusiveArgList( Arg('-s', '--subnets', metavar='SUBNET1,SUBNET2,...', dest='Subnets.member', type=delimited_list(','), help='''[VPC only] subnets the load balancer should run in (required)'''), Arg('-z', '--availability-zones', metavar='ZONE1,ZONE2,...', dest='AvailabilityZones.member', type=delimited_list(','), help='''[Non-VPC only] availability zones the load balancer should run in (required)''')) .required(), Arg('-l', '--listener', dest='Listeners.member', action='append', metavar=('"lb-port=PORT, protocol={HTTP,HTTPS,SSL,TCP}, ' 'instance-port=PORT, instance-protocol={HTTP,HTTPS,' 'SSL,TCP}, cert-id=ARN"'), required=True, type=listener, help='''port/protocol settings for the load balancer, where lb-port is the external port number, protocol is the external protocol, instance-port is the back end server port number, instance-protocol is the protocol to use for routing traffic to back end instances, and cert-id is the ARN of the server certificate to use for encrypted connections. lb-port, protocol, and instance-port are required. This option may be used multiple times. (at least 1 required)'''), Arg('-i', '--scheme', dest='Scheme', choices=('internal',), metavar='internal', help='''[VPC only] "internal" to make the new load balancer private to a VPC'''), Arg('-g', '--security-groups', dest='SecurityGroups.member', metavar='GROUP1,GROUP2,...', type=delimited_list(','), help='''[VPC only] IDs of the security groups to assign to the new load balancer'''), Arg('-t', '--tag', dest='Tags.member', action='append', metavar='KEY=VALUE', type=binary_tag_def, help='key and value of a tag to add to the new load balancer')] def print_result(self, result): print self.tabify(('DNS_NAME', result.get('DNSName'))) euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/createloadbalancerlisteners.py000066400000000000000000000051551267461563000313500ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.elasticloadbalancing import ELBRequest from euca2ools.commands.elasticloadbalancing.argtypes import listener from requestbuilder import Arg class CreateLoadBalancerListeners(ELBRequest): DESCRIPTION = 'Add one or more listeners to a load balancer' ARGS = [Arg('LoadBalancerName', metavar='ELB', help='name of the load balancer to modify (required)'), Arg('-l', '--listener', dest='Listeners.member', action='append', metavar=('"lb-port=PORT, protocol={HTTP,HTTPS,SSL,TCP}, ' 'instance-port=PORT, instance-protocol={HTTP,HTTPS,' 'SSL,TCP}, cert-id=ARN"'), required=True, type=listener, help='''port/protocol settings for the load balancer, where lb-port is the external port number, protocol is the external protocol, instance-port is the back end server port number, instance-protocol is the protocol to use for routing traffic to back end instances, and cert-id is the ARN of the server certificate to use for encrypted connections. lb-port, protocol, and instance-port are required. This option may be used multiple times. (at least 1 required)''')] euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/createloadbalancerpolicy.py000066400000000000000000000133141267461563000306330ustar00rootroot00000000000000# Copyright 2013-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import sys from requestbuilder import Arg from requestbuilder.exceptions import ArgumentError from euca2ools.commands.argtypes import delimited_list from euca2ools.commands.elasticloadbalancing import ELBRequest def attribute(attr_as_str): attr = {} for pair in attr_as_str.split(','): key, val = pair.split('=', 1) if key.strip() == 'name': attr['AttributeName'] = val.strip() elif key.strip() == 'value': attr['AttributeValue'] = val.strip() else: raise ArgumentError( "attribute '{0}': '{1}' is not a valid part of an attribute " "(choose from 'name', 'value')".format(attr_as_str, key.strip())) if 'AttributeName' not in attr: raise ArgumentError( "attribute '{0}': name is required".format(attr_as_str)) if 'AttributeValue' not in attr: raise ArgumentError( "attribute '{0}': value is required".format(attr_as_str)) return attr def key_value_attribute(attr_as_str): if '=' not in attr_as_str: raise ArgumentError( "attribute '{0}' must have format NAME=VALUE".format(attr_as_str)) key, val = attr_as_str.split('=', 1) if not key: raise ArgumentError( "attribute '{0}' must have a name".format(attr_as_str)) return {'AttributeName': key.strip(), 'AttributeValue': val.strip()} # Improve the output of argparse's TypeError/ValueError handling key_value_attribute.__name__ = 'attribute' class CreateLoadBalancerPolicy(ELBRequest): DESCRIPTION = 'Add a new policy to a load balancer' ARGS = [Arg('LoadBalancerName', metavar='ELB', help='name of the load balancer to modify (required)'), Arg('-n', '--policy-name', dest='PolicyName', metavar='POLICY', required=True, help='name of the new policy (required)'), Arg('-t', '--policy-type', dest='PolicyTypeName', metavar='POLTYPE', required=True, help='''type of the new policy. For a list of policy types, use eulb-describe-lb-policy-types. (required)'''), Arg('-a', '--attribute', dest='PolicyAttributes.member', action='append', metavar='"name=NAME, value=VALUE"', type=attribute, help='''name and value for each attribute associated with the new policy. Use this option multiple times to supply multiple attributes.'''), Arg('-A', '--attributes', dest='new_attr_lists', route_to=None, metavar='NAME=VALUE,...', action='append', type=delimited_list(',', item_type=key_value_attribute), help='''a comma-delimited list of attribute names and values to associate with the new policy, each pair of which is separated by "=". This is a more concise alternative to the -a/--attribute option.'''), Arg('--attributes-from-file', dest='attr_filename', metavar='FILE', route_to=None, help='''a file containing attribute names and values to associate with the new policy, one per line, each pair of which is separated by "=". Lines that are blank or begin with "#" are ignored.''')] def preprocess(self): if not self.params.get('PolicyAttributes.member'): self.params['PolicyAttributes.member'] = [] for attr_list in self.args.get('new_attr_lists') or []: self.params['PolicyAttributes.member'].extend(attr_list or []) if self.args.get('attr_filename'): if self.args['attr_filename'] == '-': attr_file = sys.stdin else: attr_file = open(self.args['attr_filename']) with attr_file: for line_no, line in enumerate(attr_file, 1): if line.strip() and not line.startswith('#'): try: self.params['PolicyAttributes.member'].append( key_value_attribute(line.strip())) except ArgumentError as err: raise ValueError( 'error on {0} line {1}: {2}' .format(self.args['attr_filename'], line_no, err.args[0])) euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/deleteloadbalancer.py000066400000000000000000000035241267461563000274140ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from euca2ools.commands.elasticloadbalancing import ELBRequest from requestbuilder import Arg class DeleteLoadBalancer(ELBRequest): DESCRIPTION = ('Delete a load balancer\n\nIf the load balancer does not ' 'exist, this command still succeeds.') ARGS = [Arg('LoadBalancerName', metavar='ELB', help='name of the load balancer to delete (required)'), Arg('--force', action='store_true', route_to=None, help=argparse.SUPPRESS)] # for compatibility euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/deleteloadbalancerlisteners.py000066400000000000000000000043331267461563000313440ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from euca2ools.commands.argtypes import delimited_list from euca2ools.commands.elasticloadbalancing import ELBRequest from requestbuilder import Arg class DeleteLoadBalancerListeners(ELBRequest): DESCRIPTION = ('Delete one or more listeners from a load balancer\n\nIf ' 'a listener named with -l/--lb-ports does not exist, this ' 'command still succeeds.') ARGS = [Arg('LoadBalancerName', metavar='ELB', help='name of the load balancer to modify (required)'), Arg('-l', '--lb-ports', dest='LoadBalancerPorts.member', metavar='PORT1,PORT2,...', required=True, type=delimited_list(',', item_type=int), help='port numbers of the listeners to remove (required)'), Arg('--force', action='store_true', route_to=None, help=argparse.SUPPRESS)] # for compatibility euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/deleteloadbalancerpolicy.py000066400000000000000000000034321267461563000306320ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.elasticloadbalancing import ELBRequest from requestbuilder import Arg class DeleteLoadBalancerPolicy(ELBRequest): DESCRIPTION = 'Delete a policy from a load balancer' ARGS = [Arg('LoadBalancerName', metavar='ELB', help='name of the load balancer to modify (required)'), Arg('-p', '--policy-name', dest='PolicyName', metavar='POLICY', required=True, help='name of the policy to delete (required)')] euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/deregisterinstancesfromloadbalancer.py000066400000000000000000000044761267461563000331120ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.argtypes import delimited_list from euca2ools.commands.elasticloadbalancing import ELBRequest from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin def instance_id(inst_as_str): return {'InstanceId': inst_as_str} class DeregisterInstancesFromLoadBalancer(ELBRequest, TabifyingMixin): DESCRIPTION = 'Remove one or more instances from a load balancer' ARGS = [Arg('LoadBalancerName', metavar='ELB', help='name of the load balancer to modify (required)'), Arg('--instances', dest='Instances.member', required=True, metavar='INSTANCE1,INSTANCE2,...', type=delimited_list(',', item_type=instance_id), help='''IDs of the instances to remove from the load balancer (required)''')] LIST_TAGS = ['Instances'] def print_result(self, result): for instance in result.get('Instances', []): print self.tabify(('INSTANCE', instance.get('InstanceId'))) euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/describeinstancehealth.py000066400000000000000000000051601267461563000303130ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.argtypes import delimited_list from euca2ools.commands.elasticloadbalancing import ELBRequest from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin def instance_id(inst_as_str): return {'InstanceId': inst_as_str} class DescribeInstanceHealth(ELBRequest, TabifyingMixin): DESCRIPTION = 'Show the state of instances registered with a load balancer' ARGS = [Arg('LoadBalancerName', metavar='ELB', help='''name of the load balancer to describe instances for (required)'''), Arg('--instances', dest='Instances.member', metavar='INSTANCE1,INSTANCE2,...', type=delimited_list(',', item_type=instance_id), help='limit results to specific instances'), Arg('--show-long', action='store_true', route_to=None, help="show all of the instances' info")] LIST_TAGS = ['InstanceStates'] def print_result(self, result): for instance in result.get('InstanceStates', []): bits = ['INSTANCE', instance.get('InstanceId'), instance.get('State')] if self.args['show_long']: bits.append(instance.get('Description')) bits.append(instance.get('ReasonCode')) print self.tabify(bits) euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/describeloadbalancerattributes.py000066400000000000000000000053571267461563000320470ustar00rootroot00000000000000# Copyright 2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin from euca2ools.commands.elasticloadbalancing import ELBRequest class DescribeLoadBalancerAttributes(ELBRequest, TabifyingMixin): DESCRIPTION = "Show a load balancer's attributes" ARGS = [Arg('LoadBalancerName', metavar='ELB', help='the load balancer to describe (required)')] def print_result(self, result): attrs = result.get('LoadBalancerAttributes') or {} for key, val in sorted(flatten(attrs)): print self.tabify((key, val)) return for policy in result.get('PolicyDescriptions', []): bits = ['POLICY', policy.get('PolicyName'), policy.get('PolicyTypeName')] if self.args['show_long']: attrs = [] for attr in policy.get('PolicyAttributeDescriptions', []): attrs.append('{{name={0},value={1}}}'.format( attr.get('AttributeName'), attr.get('AttributeValue'))) if len(attrs) > 0: bits.append(','.join(attrs)) else: bits.append(None) print self.tabify(bits) def flatten(attrs): for key, val in attrs.items(): if isinstance(val, dict): for subkey, subval in flatten(val): yield '{0}.{1}'.format(key, subkey), subval else: yield key, val euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/describeloadbalancerpolicies.py000066400000000000000000000056221267461563000314630ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.argtypes import delimited_list from euca2ools.commands.elasticloadbalancing import ELBRequest from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin class DescribeLoadBalancerPolicies(ELBRequest, TabifyingMixin): DESCRIPTION = 'Show information about load balancer policies' ARGS = [Arg('LoadBalancerName', metavar='ELB', nargs='?', help='''show policies associated with a specific load balancer (default: only describe sample policies provided by the service)'''), Arg('-p', '--policy-names', dest='PolicyNames.member', metavar='POLICY1,POLICY2,...', type=delimited_list(','), help='limit results to specific policies'), Arg('--show-long', action='store_true', route_to=None, help="show all of the policies' info")] LIST_TAGS = ['PolicyDescriptions', 'PolicyAttributeDescriptions'] def print_result(self, result): for policy in result.get('PolicyDescriptions', []): bits = ['POLICY', policy.get('PolicyName'), policy.get('PolicyTypeName')] if self.args['show_long']: attrs = [] for attr in policy.get('PolicyAttributeDescriptions', []): attrs.append('{{name={0},value={1}}}'.format( attr.get('AttributeName'), attr.get('AttributeValue'))) if len(attrs) > 0: bits.append(','.join(attrs)) else: bits.append(None) print self.tabify(bits) euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/describeloadbalancerpolicytypes.py000066400000000000000000000057001267461563000322350ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.elasticloadbalancing import ELBRequest from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin class DescribeLoadBalancerPolicyTypes(ELBRequest, TabifyingMixin): DESCRIPTION = 'Show information about load balancer policy types' ARGS = [Arg('PolicyTypeNames.member', metavar='POLTYPE', nargs='*', help='limit results to specific policy types'), Arg('--show-long', action='store_true', route_to=None, help="show all of the policy types' info")] LIST_TAGS = ['PolicyTypeDescriptions', 'PolicyAttributeTypeDescriptions'] def print_result(self, result): for poltype in result.get('PolicyTypeDescriptions', []): bits = ['POLICY_TYPE', poltype.get('PolicyTypeName'), poltype.get('Description')] if self.args['show_long']: attrs = [] for attr in poltype.get('PolicyAttributeTypeDescriptions', []): elem_map = (('name', 'AttributeName'), ('description', 'Description'), ('type', 'AttributeType'), ('default-value', 'DefaultValue'), ('cardinality', 'Cardinality')) attr_bits = [] for name, xmlname in elem_map: attr_bits.append('='.join((name, attr.get(xmlname) or ''))) attrs.append('{' + ','.join(attr_bits) + '}') bits.append(','.join(attrs)) print self.tabify(bits) euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/describeloadbalancers.py000066400000000000000000000170531267461563000301170ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.elasticloadbalancing import ELBRequest from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin class DescribeLoadBalancers(ELBRequest, TabifyingMixin): DESCRIPTION = 'Show information about load balancers' ARGS = [Arg('LoadBalancerNames.member', metavar='ELB', nargs='*', help='limit results to specific load balancers'), Arg('--show-long', action='store_true', route_to=None, help="show all of the load balancers' info")] LIST_TAGS = ['LoadBalancerDescriptions', 'AvailabilityZones', 'BackendServerDescriptions', 'Instances', 'ListenerDescriptions', 'PolicyNames', 'AppCookieStickinessPolicies', 'LBCookieStickinessPolicies', 'OtherPolicies', 'SecurityGroups', 'Subnets'] def print_result(self, result): for desc in result.get('LoadBalancerDescriptions', []): bits = ['LOAD_BALANCER', desc.get('LoadBalancerName'), desc.get('DNSName')] if self.args['show_long']: bits.append(desc.get('CanonicalHostedZoneName')) bits.append(desc.get('CanonicalHostedZoneNameID')) check = desc.get('HealthCheck') if check is not None: check_str_bits = [] elem_map = (('interval', 'Interval'), ('target', 'Target'), ('timeout', 'Timeout'), ('healthy-threshold', 'HealthyThreshold'), ('unhealthy-threshold', 'UnhealthyThreshold')) for name, xmlname in elem_map: if check.get(xmlname): check_str_bits.append(name + '=' + check[xmlname]) if len(check_str_bits) > 0: bits.append('{' + ','.join(check_str_bits) + '}') else: bits.append(None) else: bits.append(None) bits.append(','.join(zone for zone in desc.get('AvailabilityZones', []))) bits.append(','.join(net for net in desc.get('Subnets', []))) bits.append(desc.get('VPCId')) bits.append(','.join(instance.get('InstanceId') for instance in desc.get('Instances', []))) listeners = [] for listenerdesc in desc.get('ListenerDescriptions', []): listener = listenerdesc.get('Listener', {}) listener_str_bits = [] elem_map = (('protocol', 'Protocol'), ('lb-port', 'LoadBalancerPort'), ('instance-protocol', 'InstanceProtocol'), ('instance-port', 'InstancePort'), ('cert-id', 'SSLCertificateId')) for name, xmlname in elem_map: if listener.get(xmlname): listener_str_bits.append(name + '=' + listener[xmlname]) if listenerdesc.get('PolicyNames'): listener_str_bits.append( '{' + ','.join(listenerdesc['PolicyNames']) + '}') listeners.append('{' + ','.join(listener_str_bits) + '}') if len(listeners) > 0: bits.append(','.join(listeners)) else: bits.append(None) beservers = [] for bedesc in desc.get('BackendServerDescriptions', []): beserver_str_bits = [] if 'InstancePort' in bedesc: beserver_str_bits.append('instance-port=' + bedesc['InstancePort']) if 'PolicyNames' in bedesc: policies = ','.join(policy for policy in bedesc['PolicyNames']) beserver_str_bits.append('policies={' + policies + '}') beservers.append('{' + ','.join(beserver_str_bits) + '}') if len(beservers) > 0: bits.append(','.join(beservers)) else: bits.append(None) all_policies = desc.get('Policies') or {} app_policies = all_policies.get( 'AppCookieStickinessPolicies') or {} app_policy_strs = ['{{policy-name={0},cookie-name={1}}}' .format(policy.get('PolicyName'), policy.get('CookieName')) for policy in app_policies] bits.append(','.join(app_policy_strs) or None) lb_policies = all_policies.get( 'LBCookieStickinessPolicies') or {} lb_policy_strs = ['{{policy-name={0},expiration-period={1}}}' .format(policy.get('PolicyName'), policy.get('CookieExpirationPeriod')) for policy in lb_policies] bits.append(','.join(lb_policy_strs) or None) other_policies = all_policies.get('OtherPolicies') or {} if other_policies: bits.append('{' + ','.join(other_policies) + '}') else: bits.append(None) group = desc.get('SourceSecurityGroup') if group: bits.append('{{owner-alias={0},group-name={1}}}'.format( group.get('OwnerAlias', ''), group.get('GroupName', ''))) else: bits.append(None) if desc.get('SecurityGroups'): bits.append('{' + ','.join(desc['SecurityGroups']) + '}') else: bits.append(None) bits.append(desc.get('CreatedTime')) bits.append(desc.get('Scheme')) print self.tabify(bits) euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/describetags.py000066400000000000000000000042621267461563000262610ustar00rootroot00000000000000# Copyright 2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from requestbuilder.mixins.formatting import TableOutputMixin from euca2ools.commands.elasticloadbalancing import ELBRequest class DescribeTags(ELBRequest, TableOutputMixin): DESCRIPTION = 'Show the tags associated with one or more load balancers' ARGS = [Arg('LoadBalancerNames.member', metavar='ELB', nargs='+', help='load balancer(s) to show tags for (required)')] LIST_TAGS = ['TagDescriptions', 'Tags'] def print_result(self, result): table = self.get_table(('TAG', 'type', 'name', 'key', 'value')) for desc in result.get('TagDescriptions') or []: lb_name = desc.get('LoadBalancerName') for tag in desc.get('Tags') or []: table.add_row(('TAG', 'load-balancer', lb_name, tag.get('Key'), tag.get('Value'))) print table euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/detachloadbalancerfromsubnets.py000066400000000000000000000042341267461563000316710ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.argtypes import delimited_list from euca2ools.commands.elasticloadbalancing import ELBRequest from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin class DetachLoadBalancerFromSubnets(ELBRequest, TabifyingMixin): DESCRIPTION = '[VPC only] Remove a load balancer from one or more subnets' ARGS = [Arg('LoadBalancerName', metavar='ELB', help='name of the load balancer to modify (required)'), Arg('-s', '--subnets', dest='Subnets.member', required=True, metavar='SUBNET1,SUBNET2,...', type=delimited_list(','), help='''IDs of the subnets to remove the load balancer from (required)''')] LIST_TAGS = ['Subnets'] def print_result(self, result): print self.tabify(('SUBNETS', ','.join(result.get('Subnets', [])))) euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/disableavailabilityzonesforloadbalancer.py000066400000000000000000000043621267461563000337370ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.argtypes import delimited_list from euca2ools.commands.elasticloadbalancing import ELBRequest from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin class DisableAvailabilityZonesForLoadBalancer(ELBRequest, TabifyingMixin): DESCRIPTION = 'Remove a load balancer from one or more availability zones' ARGS = [Arg('LoadBalancerName', metavar='ELB', help='name of the load balancer to modify (required)'), Arg('-z', '--availability-zones', dest='AvailabilityZones.member', metavar='ZONE1,ZONE2,...', type=delimited_list(','), required=True, help='''availability zones to remove the load balancer from (required)''')] LIST_TAGS = ['AvailabilityZones'] def print_result(self, result): print self.tabify(('AVAILABILITY_ZONES', ', '.join(result.get('AvailabilityZones', [])))) euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/enableavailabilityzonesforloadbalancer.py000066400000000000000000000043471267461563000335650ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.argtypes import delimited_list from euca2ools.commands.elasticloadbalancing import ELBRequest from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin class EnableAvailabilityZonesForLoadBalancer(ELBRequest, TabifyingMixin): DESCRIPTION = 'Add a load balancer to one or more availability zones' ARGS = [Arg('LoadBalancerName', metavar='ELB', help='name of the load balancer to modify (required)'), Arg('-z', '--availability-zones', dest='AvailabilityZones.member', metavar='ZONE1,ZONE2,...', type=delimited_list(','), required=True, help='''availability zones to add the load balancer to (required)''')] LIST_TAGS = ['AvailabilityZones'] def print_result(self, result): print self.tabify(('AVAILABILITY_ZONES', ', '.join(result.get('AvailabilityZones', [])))) euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/modifyloadbalancerattributes.py000066400000000000000000000043431267461563000315500ustar00rootroot00000000000000# Copyright 2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from requestbuilder import Arg from euca2ools.commands.elasticloadbalancing import ELBRequest def key_value(arg_val): if '=' not in arg_val: raise argparse.ArgumentTypeError('invalid ATTR=VALUE pair: {0}' .format(arg_val)) return dict([arg_val.split('=', 1)]) class ModifyLoadBalancerAttributes(ELBRequest): DESCRIPTION = "Modify a load balancer's attributes" ARGS = [Arg('LoadBalancerName', metavar='ELB', help='the load balancer to describe (required)'), Arg('attrs', metavar='ATTR=VALUE', nargs='+', type=key_value, route_to=None, help='''name and new value of each attribute to modify (required)''')] def preprocess(self): self.params['LoadBalancerAttributes'] = {} for attr in self.args['attrs']: self.params['LoadBalancerAttributes'].update(attr) euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/registerinstanceswithloadbalancer.py000066400000000000000000000044711267461563000326040ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.argtypes import delimited_list from euca2ools.commands.elasticloadbalancing import ELBRequest from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin def instance_id(inst_as_str): return {'InstanceId': inst_as_str} class RegisterInstancesWithLoadBalancer(ELBRequest, TabifyingMixin): DESCRIPTION = 'Add one or more instances to a load balancer' ARGS = [Arg('LoadBalancerName', metavar='ELB', help='name of the load balancer to modify (required)'), Arg('--instances', dest='Instances.member', required=True, metavar='INSTANCE1,INSTANCE2,...', type=delimited_list(',', item_type=instance_id), help='''IDs of the instances to register with the load balancer (required)''')] LIST_TAGS = ['Instances'] def print_result(self, result): for instance in result.get('Instances', []): print self.tabify(('INSTANCE', instance.get('InstanceId'))) euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/removetags.py000066400000000000000000000035661267461563000260040ustar00rootroot00000000000000# Copyright 2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.elasticloadbalancing import ELBRequest def _tag_key_only(key): return {'Key': key} class RemoveTags(ELBRequest): DESCRIPTION = 'Remove one or more tags from a load balancer' ARGS = [Arg('LoadBalancerNames.member.1', metavar='ELB', help='name of the load balancer to untag (required)'), Arg('-t', '--tag', dest='Tags.member', required=True, action='append', metavar='KEY', type=_tag_key_only, help='name of each tag to add (required)')] euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/setloadbalancerlistenersslcertificate.py000066400000000000000000000041031267461563000334320ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.elasticloadbalancing import ELBRequest from requestbuilder import Arg class SetLoadBalancerListenerSSLCertificate(ELBRequest): DESCRIPTION = ("Change the certificate that terminates a load balancer's" "listener's SSL connections") ARGS = [Arg('LoadBalancerName', metavar='ELB', help='name of the load balancer to modify (required)'), Arg('-l', '--lb-port', dest='LoadBalancerPort', metavar='PORT', type=int, required=True, help='port that should use the certificate (required)'), Arg('-c', '--cert-id', dest='SSLCertificateId', metavar='ARN', required=True, help='ARN for the server certificate to use (required)')] euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/setloadbalancerpoliciesforbackendserver.py000066400000000000000000000045371267461563000337500ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.argtypes import delimited_list from euca2ools.commands.elasticloadbalancing import ELBRequest from requestbuilder import Arg, EMPTY class SetLoadBalancerPoliciesForBackendServer(ELBRequest): DESCRIPTION = ('Change the policies associated with a port on which load-' 'balanced back end servers listen.') ARGS = [Arg('LoadBalancerName', metavar='ELB', help='name of the load balancer to modify (required)'), Arg('-i', '--instance-port', dest='InstancePort', metavar='PORT', type=int, required=True, help='port number of the back end server (required)'), Arg('-p', '--policy-names', dest='PolicyNames.member', metavar='POLICY1,POLICY2,...', type=delimited_list(','), required=True, help='''list of policies to associate with the back end server (required)''')] def preprocess(self): if not self.args.get('PolicyNames.member'): self.params['PolicyNames'] = EMPTY euca2ools-3.3.1/euca2ools/commands/elasticloadbalancing/setloadbalancerpoliciesoflistener.py000066400000000000000000000044241267461563000325700ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.argtypes import delimited_list from euca2ools.commands.elasticloadbalancing import ELBRequest from requestbuilder import Arg, EMPTY class SetLoadBalancerPoliciesOfListener(ELBRequest): DESCRIPTION = 'Change the policy associated with a load balancer listener' ARGS = [Arg('LoadBalancerName', metavar='ELB', help='name of the load balancer to modify (required)'), Arg('-l', '--lb-port', dest='LoadBalancerPort', metavar='PORT', type=int, required=True, help='port of the listener to modify (required)'), Arg('-p', '--policy-names', dest='PolicyNames.member', metavar='POLICY1,POLICY2,...', type=delimited_list(','), required=True, help='''list of policies to associate with the listener (required)''')] def preprocess(self): if not self.args.get('PolicyNames.member'): self.params['PolicyNames'] = EMPTY euca2ools-3.3.1/euca2ools/commands/euimage/000077500000000000000000000000001267461563000205355ustar00rootroot00000000000000euca2ools-3.3.1/euca2ools/commands/euimage/__init__.py000066400000000000000000000025011267461563000226440ustar00rootroot00000000000000# (C) Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. euca2ools-3.3.1/euca2ools/commands/euimage/describepackedimage.py000066400000000000000000000046661267461563000250560ustar00rootroot00000000000000# (C) Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from requestbuilder.command import BaseCommand from requestbuilder.mixins import TabifyingMixin import euca2ools.commands from euca2ools.commands.euimage.pack import ImagePack class DescribePackedImage(BaseCommand, TabifyingMixin): SUITE = euca2ools.commands.Euca2ools DESCRIPTION = '***TECH PREVIEW***\n\nShow info about an image pack' ARGS = [Arg('pack_filename', metavar='FILE', help='the image pack to show info for (required)')] def main(self): return ImagePack.open(self.args['pack_filename']) def print_result(self, pack): print self.tabify(('Name:', pack.image_md.name)) print self.tabify(('Architecture:', pack.image_md.arch)) if pack.image_md.epoch: print self.tabify(('Epoch:', pack.image_md.epoch)) print self.tabify(('Version:', pack.image_md.version)) print self.tabify(('Release:', pack.image_md.release)) for profile_name in sorted(pack.image_md.profiles): print self.tabify(('Profile:', profile_name)) print 'Description:' print pack.image_md.description euca2ools-3.3.1/euca2ools/commands/euimage/installpackedimage.py000066400000000000000000000145521267461563000247370ustar00rootroot00000000000000# Copyright 2014-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse import hashlib import tempfile from requestbuilder import Arg from requestbuilder.auth.aws import HmacV4Auth from requestbuilder.mixins import FileTransferProgressBarMixin, TabifyingMixin import euca2ools from euca2ools.commands.ec2 import EC2 from euca2ools.commands.euimage.pack import ImagePack from euca2ools.commands.s3 import S3Request class InstallPackedImage(S3Request, FileTransferProgressBarMixin, TabifyingMixin): DESCRIPTION = '***TECH PREVIEW***\n\nInstall a packed image into the cloud' ARGS = [Arg('pack_filename', metavar='FILE', help='the pack to install (required)'), Arg('--profile', help='''which of the image's profiles to install (default: "default")'''), # Upload stuff (for bundle pieces or imported disk image pieces) Arg('-b', '--bucket', metavar='BUCKET[/PREFIX]', help='bucket to upload the image to (required)'), Arg('--location', help='''location constraint of the destination bucket (default: inferred from s3-location-constraint in configuration, or otherwise none'''), # Bundle stuff Arg('--privatekey', metavar='FILE', help='''file containing your private key to sign the bundle's manifest with. This private key will also be required to unbundle the bundle in the future. (instance-store only)'''), Arg('--cert', metavar='FILE', help='''file containing your X.509 certificate (instance-store only)'''), Arg('--ec2cert', metavar='FILE', help='''file containing the cloud's X.509 certificate (instance-store only)'''), Arg('--user', metavar='ACCOUNT', help='your account ID (instance-store only)'), # Registration stuff Arg('--kernel', metavar='IMAGE', help='''ID of the kernel image to associate with this machine image (paravirtual only)'''), Arg('--ramdisk', metavar='IMAGE', help='''ID of the ramdisk image to associate with this machine image (paravirtual only)'''), Arg('--ec2-url', help='compute service endpoint URL'), Arg('--ec2-auth', help=argparse.SUPPRESS), Arg('--ec2-service', help=argparse.SUPPRESS)] def configure(self): S3Request.configure(self) if not self.args.get('ec2_service'): self.args['ec2_service'] = EC2.from_other( self.service, url=self.args.get('ec2_url')) if not self.args.get('ec2_auth'): self.args['ec2_auth'] = HmacV4Auth.from_other(self.auth) if not self.args.get('profile'): self.args['profile'] = 'default' def main(self): services = {'s3': {'service': self.service, 'auth': self.auth}, 'ec2': {'service': self.args['ec2_service'], 'auth': self.args['ec2_auth']}} unpacked_image = tempfile.TemporaryFile() with ImagePack.open(self.args['pack_filename']) as pack: if self.args['profile'] not in pack.image_md.profiles: raise ValueError( 'no such profile: "{0}" (choose from {1})'.format( self.args['profile'], ', '.join(pack.image_md.profiles.keys()))) with pack.open_image() as image: # We could technically hand the image file object # directly to the installation process and calculate # checksums on fly, but that would mean we error out # only after everything finishes and force people to # clean up after if the checksum happens to be bad. # We thus do this in two steps instead. digest = hashlib.sha256() bytes_written = 0 pbar = self.get_progressbar(label='Decompressing', maxval=pack.pack_md.image_size) pbar.start() while True: chunk = image.read(euca2ools.BUFSIZE) if not chunk: break digest.update(chunk) unpacked_image.write(chunk) bytes_written += len(chunk) pbar.update(bytes_written) pbar.finish() if digest.hexdigest() != pack.pack_md.image_sha256sum: raise RuntimeError('image appears to be corrupt ' '(expected SHA256: {0}, actual: {1})', pack.pack_md.image_sha256sum, digest.hexdigest()) unpacked_image.seek(0) image_id = pack.image_md.install_profile( self.args['profile'], services, unpacked_image, pack.pack_md.image_size, self.args) unpacked_image.close() return image_id def print_result(self, image_id): print self.tabify(('IMAGE', image_id)) euca2ools-3.3.1/euca2ools/commands/euimage/pack/000077500000000000000000000000001267461563000214535ustar00rootroot00000000000000euca2ools-3.3.1/euca2ools/commands/euimage/pack/__init__.py000066400000000000000000000025751267461563000235750ustar00rootroot00000000000000# (C) Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.euimage.pack.pack import ImagePack euca2ools-3.3.1/euca2ools/commands/euimage/pack/metadata.py000066400000000000000000000173711267461563000236160ustar00rootroot00000000000000# (C) Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import yaml from euca2ools.commands.euimage.pack.profiles import build_image_profile from euca2ools.util import check_dict_whitelist class ImagePackMetadata(object): def __init__(self): self.image_sha256sum = None self.image_size = None self.image_md_sha256sum = None self.version = 1 # Bump this with each incompatible change @classmethod def from_fileobj(cls, fileobj): new_md = cls() metadata = yaml.safe_load(fileobj) check_dict_whitelist(metadata, 'pack', ['image', 'image_metadata', 'version']) if metadata.get('version'): # This is the version of the pack metadata, not the image. # If we make backwards-incompatible changes this allows us # to tell what to expect so we can continue to handle packs # that precede those changes. # # Because there is only one metadata version right now this # method is rather dumb -- it accepts only version 1. if int(metadata['version']) != 1: raise ValueError('pack has metadata version {0}; expected 1' .format(metadata['version'])) image_info = metadata.get('image') or {} if not image_info.get('sha256sum'): raise ValueError('pack: image.sha256sum is missing or empty') new_md.image_sha256sum = image_info['sha256sum'] if not image_info.get('size'): raise ValueError('pack: image.size is missing or zero') new_md.image_size = int(image_info['size']) image_md_info = metadata.get('image_metadata') or {} if not image_md_info.get('sha256sum'): raise ValueError( 'pack: image_metadata.sha256sum is missing or empty') new_md.image_md_sha256sum = image_md_info['sha256sum'] return new_md @classmethod def from_file(cls, filename): with open(filename) as fileobj: return cls.from_fileobj(fileobj) def dump_to_fileobj(self, fileobj): yaml.safe_dump(self.__serialize_as_dict(), fileobj, default_flow_style=False) def dump_to_file(self, filename): with open(filename, 'w') as fileobj: self.dump_to_fileobj(fileobj) def __serialize_as_dict(self): return {'image': {'sha256sum': self.image_sha256sum, 'size': self.image_size}, 'image_metadata': {'sha256sum': self.image_md_sha256sum}, 'version': self.version} class ImageMetadata(object): def __init__(self): self.name = None self.version = None self.release = None self.epoch = 0 self.arch = None self.description = None self.profiles = {} @classmethod def from_fileobj(cls, fileobj): new_md = cls() metadata = yaml.safe_load(fileobj) check_dict_whitelist(metadata, 'image', ['name', 'version', 'release', 'arch', 'description', 'profiles']) if not metadata.get('name'): raise ValueError('name is missing or empty') new_md.name = metadata['name'] if not metadata.get('version'): raise ValueError('image "{0}": version is missing or empty' .format(new_md.name)) new_md.version = metadata['version'] if not metadata.get('release'): raise ValueError('image "{0}": release is missing or empty' .format(new_md.name)) new_md.release = metadata['release'] if metadata.get('epoch'): try: new_md.epoch = int(metadata['epoch']) except ValueError: raise ValueError('image "{0}": epoch must be an integer' .format(new_md.name)) if new_md.epoch < 0: raise ValueError('image "{0}": epoch must not be negative' .format(new_md.name)) if not metadata.get('arch'): raise ValueError('image "{0}": arch is missing or empty' .format(new_md.name)) new_md.arch = metadata['arch'] if not metadata.get('description'): raise ValueError('image "{0}": description is missing or empty' .format(new_md.name)) new_md.description = metadata['description'].rstrip() profiles = metadata.get('profiles') if not profiles: raise ValueError('image "{0}" must have at least one profile ' '(use "default" for a single-profile image)' .format(new_md.name)) if not isinstance(profiles, dict): raise ValueError('image "{0}": profiles must be an associative ' 'array'.format(new_md.name)) for profile_name, profile_info in profiles.iteritems(): new_md.profiles[profile_name] = build_image_profile(profile_info, new_md.arch) return new_md @classmethod def from_file(cls, filename): with open(filename) as fileobj: return cls.from_fileobj(fileobj) def install_profile(self, profile_name, services, image_fileobj, image_size, args): # Since different profiles can require different args to install # correctly, we can't easily pick out the correct ones ahead # of time. For simplicity's sake, we just pass everything and # let the profile grab what it needs. Validation is the job of # the profile, which will probably simply delegate that work to # the commands it runs. euimage_tags = {'euimage:name': self.name, 'euimage:version': self.version, 'euimage:release': self.release, 'euimage:profile': profile_name} if self.epoch: euimage_tags['euimage:epoch'] = self.epoch if profile_name not in self.profiles: raise ValueError('no such profile: "{0}"'.format(profile_name)) return self.profiles[profile_name].install( self, services, image_fileobj, image_size, args, tags=euimage_tags) def get_nvra(self): return '{0}-{1}-{2}.{3}'.format(self.name, self.version, self.release, self.arch) euca2ools-3.3.1/euca2ools/commands/euimage/pack/pack.py000066400000000000000000000201401267461563000227400ustar00rootroot00000000000000# (C) Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import contextlib import hashlib import os import shutil import signal import subprocess import tarfile import tempfile import euca2ools from euca2ools.bundle.util import open_pipe_fileobjs from euca2ools.commands.euimage.pack.metadata import (ImagePackMetadata, ImageMetadata) IMAGE_ARCNAME = 'image.xz' IMAGE_MD_ARCNAME = 'image-md.yml' PACK_MD_ARCNAME = 'pack-md.yml' class ImagePack(object): def __init__(self, filename=None): self.pack_md = None self.image_md = None self.filename = filename self.__tarball = None @classmethod def open(cls, filename): with ImagePack(filename=filename) as pack: member = pack.__tarball.getmember(PACK_MD_ARCNAME) with contextlib.closing(pack.__tarball.extractfile(member)) \ as md_file: pack.pack_md = ImagePackMetadata.from_fileobj(md_file) member = pack.__tarball.getmember(IMAGE_MD_ARCNAME) with contextlib.closing(pack.__tarball.extractfile(member)) \ as md_file: pack.image_md = ImageMetadata.from_fileobj(md_file) md_file.seek(0) image_md_sha256sum = hashlib.sha256(md_file.read()).hexdigest() if image_md_sha256sum != pack.pack_md.image_md_sha256sum: raise RuntimeError('image metadata appears to be corrupt ' '(expected SHA256: {0}, actual: {1})', pack.pack_md.image_md_sha256sum, image_md_sha256sum) return pack @classmethod def build(cls, image_md_filename, image_filename, destdir='', progressbar=None): pack = ImagePack() pack.image_md = ImageMetadata.from_file(image_md_filename) pack.pack_md = ImagePackMetadata() if destdir != '' and not os.path.isdir(destdir): raise ValueError('"{0}" is not a directory'.format(destdir)) pack.filename = os.path.join(destdir, '{0}.euimage'.format( pack.image_md.get_nvra())) with open(image_md_filename) as image_md_file: digest = hashlib.sha256(image_md_file.read()) pack.pack_md.image_md_sha256sum = digest.hexdigest() # Since we have to know the size of the compressed image ahead # of time to write tarinfo headers we have to spool the whole # thing to disk. :-\ with tempfile.NamedTemporaryFile() as compressed_image: # Feed stuff to a subprocess to checksum and compress in one pass digest = hashlib.sha256() bytes_read = 0 with open(image_filename, 'rb') as original_image: xz_proc = subprocess.Popen(('xz', '-c'), stdin=subprocess.PIPE, stdout=compressed_image) if progressbar: progressbar.start() while True: chunk = original_image.read(euca2ools.BUFSIZE) if not chunk: break digest.update(chunk) xz_proc.stdin.write(chunk) bytes_read += len(chunk) if progressbar: progressbar.update(bytes_read) xz_proc.stdin.close() xz_proc.wait() if progressbar: progressbar.finish() pack.pack_md.image_sha256sum = digest.hexdigest() pack.pack_md.image_size = bytes_read # Write metadata and pack everything up with contextlib.closing(tarfile.open(pack.filename, 'w', dereference=True)) as tarball: with tempfile.NamedTemporaryFile() as pack_md_file: pack.pack_md.dump_to_fileobj(pack_md_file) tarball.add(pack_md_file.name, arcname=PACK_MD_ARCNAME) tarball.add(image_md_filename, arcname=IMAGE_MD_ARCNAME) tarball.add(compressed_image.name, arcname=IMAGE_ARCNAME) return pack def close(self): if self.__tarball: self.__tarball.close() self.__tarball = None def __enter__(self): assert self.filename self.__tarball = tarfile.open(name=self.filename, mode='r') return self def __exit__(self, type_, value, tbk): self.close() def open_image(self): """ Return a file-like object that transparently yields the packed image. """ assert self.filename with contextlib.closing(tarfile.open(name=self.filename, mode='r')) \ as tarball: # This looks like it will return a file handle that will run out of # data as soon as we leave this with block, but since what we return # actually uses the read end of an os.pipe that reads from a forked # process things should Just Work (tm). return _PackedImageWrapper(tarball) class _PackedImageWrapper(object): """ A file-like object that transparently unpacks and decompresses the image from an image pack """ def __init__(self, tarball): """ This method takes a tarfile.TarFile object and spawns *two* new processes: an xz process for decompression and an additional python process that simply feeds data from the TarFile to it. The latter is necessary because the file-like object we get from TarFile.extractfile cannot be passed to a subprocess directly. For that reason, one is also free to close the tarball after this object is created. """ self.__subp_pid = None self.__read_fh = None member = tarball.getmember(IMAGE_ARCNAME) compressed_image = tarball.extractfile(member) pipe_r, pipe_w = open_pipe_fileobjs() self.__subp_pid = os.fork() if self.__subp_pid == 0: os.setpgrp() pipe_r.close() self.__xz_proc = subprocess.Popen( ('xz', '-d'), stdin=subprocess.PIPE, stdout=pipe_w, close_fds=True) pipe_w.close() shutil.copyfileobj(compressed_image, self.__xz_proc.stdin) self.__xz_proc.stdin.close() self.__xz_proc.wait() os._exit(os.EX_OK) else: self.__read_fh = pipe_r def close(self): if self.__subp_pid: # Kill the process group os.kill(-os.getpgid(self.__subp_pid), signal.SIGTERM) self.__read_fh.close() else: os._exit(os.EX_OK) def __enter__(self): return self def __exit__(self, type_, value, tbk): self.close() def read(self, size=-1): return self.__read_fh.read(size) euca2ools-3.3.1/euca2ools/commands/euimage/pack/profiles.py000066400000000000000000000167751267461563000236700ustar00rootroot00000000000000# (C) Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import datetime import six from euca2ools.commands.bundle.bundleanduploadimage import BundleAndUploadImage from euca2ools.commands.ec2.createtags import CreateTags from euca2ools.commands.ec2.registerimage import RegisterImage from euca2ools.util import check_dict_whitelist, transform_dict def build_image_profile(profile_dict, arch): """ This is a factory method that takes a dict with image profile information and returns a profile object. While it currently always returns instance-store images, it is meant to handle multiple types in the future. """ if 'bundle' in profile_dict: return InstanceStoreImageProfile(profile_dict, arch) class InstanceStoreImageProfile(object): def __init__(self, profile_dict, arch): check_dict_whitelist(profile_dict, 'profile', ['bundle', 'provides', 'register', 'tag']) self.bundle_args = {} self.register_args = {} self.tag_args = {} bundle_args = profile_dict.get('bundle') or {} bundle_args.setdefault('arch', arch) self.__load_bundle_args(bundle_args) register_args = profile_dict.get('register') or {} register_args.setdefault('arch', arch) self.__load_register_args(register_args) self.__load_tag_args(profile_dict.get('tag') or {}) def __load_bundle_args(self, args): check_dict_whitelist(args, 'bundle', ['arch']) self.bundle_args.update(args) if not self.bundle_args.get('arch'): raise ValueError('register: arch is required') def __load_register_args(self, args): check_dict_whitelist(args, 'register', ['arch', 'block-device-mappings', 'description', 'platform', 'virtualization-type']) self.register_args.update(transform_dict( args, {'arch': 'Architecture', 'description': 'Description', 'platform': 'Platform', 'virtualization-type': 'VirtualizationType'})) if not self.register_args.get('Architecture'): raise ValueError('register: arch is required') mappings = self.register_args.pop('block-device-mappings', None) or {} if not isinstance(mappings, dict): raise ValueError('register: block-device-mappings must be an ' 'associative array') for device, mapping_info in mappings.iteritems(): mapping = {'DeviceName': device} if mapping_info == 'none': mapping['NoDevice'] = 'true' elif (isinstance(mapping_info, six.string_types) and mapping_info.startswith('ephemeral')): mapping['VirtualName'] = mapping_info elif isinstance(mapping_info, dict): mapping['Ebs'] = transform_dict( mapping_info, {'snapshot-id': 'SnapshotId', 'volume-size': 'VolumeSize', 'delete-on-termination': 'DeleteOnTermination'}) if (not mapping['Ebs'].get('SnapshotId') and not mapping['Ebs'].get('VolumeSize')): raise ValueError('register: block device mapping {0} ' 'requires a volume-size') else: raise ValueError('register: unreadable block device mapping') def __load_tag_args(self, args): check_dict_whitelist(args, 'tag') tags = [] for key, val in args.iteritems(): tags.append({'Key': key, 'Value': val}) if tags: self.tag_args.setdefault('Tag', []) self.tag_args['Tag'].extend(tags) def install(self, image_md, services, image_fileobj, image_size, args, tags=None): # If you're curious why this uses a generic "args" dict, see # ImageMetadata.install_profile's commentary. bundle_args = dict(self.bundle_args) for argname in ('privatekey', 'cert', 'ec2cert', 'user', 'bucket', 'location', 'kernel', 'ramdisk'): if args.get(argname): bundle_args[argname] = args[argname] req = BundleAndUploadImage( service=services['s3']['service'], config=services['s3']['service'].config, loglevel=services['s3']['service'].log.level, auth=services['s3']['auth'], image=image_fileobj, prefix=image_md.get_nvra(), image_type='machine', # We only support machine images for now image_size=image_size, show_progress=args.get('show_progress'), max_pending_parts=2, part_size=10485760, **bundle_args) try: bundle_info = req.main() except KeyError as err: raise ValueError('{0} is required'.format(err.args[0])) register_args = dict(self.register_args) if args.get('kernel'): register_args['KernelId'] = args['kernel'] if args.get('ramdisk'): register_args['RamdiskId'] = args['ramdisk'] if not register_args.get('Description'): register_args['Description'] = image_md.description req = RegisterImage( service=services['ec2']['service'], config=services['ec2']['service'].config, loglevel=services['ec2']['service'].log.level, auth=services['ec2']['auth'], ImageLocation=bundle_info['manifests'][0]['key'], Name='{0}-{1}'.format( image_md.get_nvra(), datetime.datetime.utcnow().strftime('%F-%H-%m-%s')), **register_args) register_response = req.main() image_id = register_response['imageId'] tag_args = dict(self.tag_args) tag_args['ResourceId'] = [image_id] tag_args.setdefault('Tag', []) if tags: for key, val in tags.iteritems(): tag_args['Tag'].append({'Key': key, 'Value': val}) req = CreateTags( service=services['ec2']['service'], config=services['ec2']['service'].config, loglevel=services['ec2']['service'].log.level, auth=services['ec2']['auth'], **tag_args) req.main() return image_id euca2ools-3.3.1/euca2ools/commands/euimage/packimage.py000066400000000000000000000045761267461563000230440ustar00rootroot00000000000000# (C) Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os.path from requestbuilder import Arg from requestbuilder.command import BaseCommand from requestbuilder.mixins import FileTransferProgressBarMixin import euca2ools.commands from euca2ools.commands.euimage.pack import ImagePack class PackImage(BaseCommand, FileTransferProgressBarMixin): SUITE = euca2ools.commands.Euca2ools DESCRIPTION = ('***TECH PREVIEW***\n\nPack an image for simple ' 'installation in a cloud') ARGS = [Arg('image_filename', metavar='IMAGE_FILE', help='the image to pack (required)'), Arg('md_filename', metavar='MD_FILE', help='metadata for the image to pack (required)')] def main(self): pbar = self.get_progressbar( label='Compressing', maxval=os.path.getsize(self.args['image_filename'])) pack = ImagePack.build(self.args['md_filename'], self.args['image_filename'], progressbar=pbar) return pack.filename def print_result(self, pack_filename): print 'Wrote', pack_filename euca2ools-3.3.1/euca2ools/commands/iam/000077500000000000000000000000001267461563000176675ustar00rootroot00000000000000euca2ools-3.3.1/euca2ools/commands/iam/__init__.py000066400000000000000000000115741267461563000220100ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse import os import sys from requestbuilder import Arg import requestbuilder.auth.aws import requestbuilder.request import requestbuilder.service from euca2ools.commands import Euca2ools from euca2ools.exceptions import AWSError from euca2ools.util import strip_response_metadata, add_fake_region_name class IAM(requestbuilder.service.BaseService): NAME = 'iam' DESCRIPTION = 'Identity and access management service' API_VERSION = '2010-05-08' REGION_ENVVAR = 'AWS_DEFAULT_REGION' URL_ENVVAR = 'AWS_IAM_URL' ARGS = [Arg('-U', '--url', metavar='URL', help='identity service endpoint URL')] def configure(self): requestbuilder.service.BaseService.configure(self) add_fake_region_name(self) def handle_http_error(self, response): raise AWSError(response) class IAMRequest(requestbuilder.request.AWSQueryRequest): SUITE = Euca2ools SERVICE_CLASS = IAM AUTH_CLASS = requestbuilder.auth.aws.HmacV4Auth METHOD = 'POST' def parse_response(self, response): response_dict = requestbuilder.request.AWSQueryRequest.parse_response( self, response) # EUARE responses enclose their useful data inside FooResponse # elements. If that's all we have after stripping out ResponseMetadata # then just return its contents. return strip_response_metadata(response_dict) AS_ACCOUNT = Arg('--as-account', dest='DelegateAccount', metavar='ACCOUNT', help='''[Eucalyptus cloud admin only] run this command as the administrator of another account''') def arg_account_name(**kwargs): return [Arg('AccountName', metavar='ACCOUNT', **kwargs), Arg('-a', '--account-name', action='store_true', dest='dummy', route_to=None, help=argparse.SUPPRESS)] def arg_account_alias(**kwargs): return [Arg('AccountAlias', metavar='ACCOUNT', **kwargs), Arg('-a', '--account-alias', action='store_true', dest='dummy', route_to=None, help=argparse.SUPPRESS)] def arg_user(**kwargs): return [Arg('UserName', metavar='USER', **kwargs), Arg('-u', '--user-name', action='store_true', dest='dummy', route_to=None, help=argparse.SUPPRESS)] def arg_group(**kwargs): return [Arg('GroupName', metavar='GROUP', **kwargs), Arg('-g', '--group-name', action='store_true', dest='dummy', route_to=None, help=argparse.SUPPRESS)] def arg_role(**kwargs): return [Arg('RoleName', metavar='ROLE', **kwargs), Arg('-r', '--role-name', action='store_true', dest='dummy', route_to=None, help=argparse.SUPPRESS)] def arg_iprofile(**kwargs): return [Arg('InstanceProfileName', metavar='IPROFILE', **kwargs), Arg('-s', '--instance-profile-name', action='store_true', dest='dummy', route_to=None, help=argparse.SUPPRESS)] def arg_key_id(**kwargs): return [Arg('AccessKeyId', metavar='KEY_ID', **kwargs), Arg('-k', '--user-key-id', action='store_true', dest='dummy', route_to=None, help=argparse.SUPPRESS)] def arg_signing_cert(**kwargs): return [Arg('CertificateId', metavar='CERT', **kwargs), Arg('-c', '--certificate-id', action='store_true', dest='dummy', route_to=None, help=argparse.SUPPRESS)] def arg_server_cert(**kwargs): return [Arg('ServerCertificateName', metavar='CERT', **kwargs), Arg('-s', '--server-certificate-name', action='store_true', dest='dummy', route_to=None, help=argparse.SUPPRESS)] euca2ools-3.3.1/euca2ools/commands/iam/addgrouppolicy.py000066400000000000000000000063361267461563000232760ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import json from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_group from euca2ools.commands.iam.putgrouppolicy import PutGroupPolicy from euca2ools.util import build_iam_policy class AddGroupPolicy(IAMRequest): DESCRIPTION = ('Add a new policy to a group. To add more complex policies ' 'than this tool supports, see euare-groupuploadpolicy(1).') ARGS = [arg_group(help='group to attach the policy to (required)'), Arg('-p', '--policy-name', metavar='POLICY', required=True, help='name of the new policy (required)'), Arg('-e', '--effect', choices=('Allow', 'Deny'), required=True, help='whether the new policy should Allow or Deny (required)'), Arg('-a', '--action', dest='actions', action='append', required=True, help='''action(s) the policy should apply to (at least one required)'''), Arg('-r', '--resource', dest='resources', action='append', required=True, help='''resource(s) the policy should apply to (at least one required)'''), Arg('-o', '--output', action='store_true', help='display the newly-created policy'), AS_ACCOUNT] def main(self): policy = build_iam_policy(self.args['effect'], self.args['resources'], self.args['actions']) policy_doc = json.dumps(policy) req = PutGroupPolicy.from_other( self, GroupName=self.args['GroupName'], PolicyName=self.args['policy_name'], PolicyDocument=policy_doc, DelegateAccount=self.params['DelegateAccount']) response = req.main() response['PolicyDocument'] = policy_doc return response def print_result(self, result): if self.args['output']: print result['PolicyDocument'] euca2ools-3.3.1/euca2ools/commands/iam/addrolepolicy.py000066400000000000000000000063311267461563000230760ustar00rootroot00000000000000# Copyright 2014-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import json from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_role from euca2ools.commands.iam.putrolepolicy import PutRolePolicy from euca2ools.util import build_iam_policy class AddRolePolicy(IAMRequest): DESCRIPTION = ('Add a new policy to a role. To add more complex policies ' 'than this tool supports, see euare-roleuploadpolicy(1).') ARGS = [arg_role(help='role to attach the policy to (required)'), Arg('-p', '--policy-name', metavar='POLICY', required=True, help='name of the new policy (required)'), Arg('-e', '--effect', choices=('Allow', 'Deny'), required=True, help='whether the new policy should Allow or Deny (required)'), Arg('-a', '--action', dest='actions', action='append', required=True, help='''action(s) the policy should apply to (at least one required)'''), Arg('-c', '--resource', dest='resources', action='append', required=True, help='''resource(s) the policy should apply to (at least one required)'''), Arg('-o', '--output', action='store_true', help='also display the newly-created policy'), AS_ACCOUNT] def main(self): policy = build_iam_policy(self.args['effect'], self.args['resources'], self.args['actions']) policy_doc = json.dumps(policy) req = PutRolePolicy.from_other( self, RoleName=self.args['RoleName'], PolicyName=self.args['policy_name'], PolicyDocument=policy_doc, DelegateAccount=self.params['DelegateAccount']) response = req.main() response['PolicyDocument'] = policy_doc return response def print_result(self, result): if self.args['output']: print result['PolicyDocument'] euca2ools-3.3.1/euca2ools/commands/iam/addroletoinstanceprofile.py000066400000000000000000000033761267461563000253350ustar00rootroot00000000000000# Copyright 2014-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_iprofile class AddRoleToInstanceProfile(IAMRequest): DESCRIPTION = 'Add a role to an instance profile' ARGS = [Arg('-r', '--role-name', dest='RoleName', required=True, help='role to add (required)'), arg_iprofile( help='instance profile to add the role to (required)'), AS_ACCOUNT] euca2ools-3.3.1/euca2ools/commands/iam/adduserpolicy.py000066400000000000000000000063071267461563000231160ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import json from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_user from euca2ools.commands.iam.putuserpolicy import PutUserPolicy from euca2ools.util import build_iam_policy class AddUserPolicy(IAMRequest): DESCRIPTION = ('Add a new policy to a user. To add more complex policies ' 'than this tool supports, see euare-useruploadpolicy(1).') ARGS = [arg_user(help='user to attach the policy to (required)'), Arg('-p', '--policy-name', metavar='POLICY', required=True, help='name of the new policy (required)'), Arg('-e', '--effect', choices=('Allow', 'Deny'), required=True, help='whether the new policy should Allow or Deny (required)'), Arg('-a', '--action', dest='actions', action='append', required=True, help='''action(s) the policy should apply to (at least one required)'''), Arg('-r', '--resource', dest='resources', action='append', required=True, help='''resource(s) the policy should apply to (at least one required)'''), Arg('-o', '--output', action='store_true', help='display the newly-created policy'), AS_ACCOUNT] def main(self): policy = build_iam_policy(self.args['effect'], self.args['resources'], self.args['actions']) policy_doc = json.dumps(policy) req = PutUserPolicy.from_other( self, UserName=self.args['UserName'], PolicyName=self.args['policy_name'], PolicyDocument=policy_doc, DelegateAccount=self.params['DelegateAccount']) response = req.main() response['PolicyDocument'] = policy_doc return response def print_result(self, result): if self.args['output']: print result['PolicyDocument'] euca2ools-3.3.1/euca2ools/commands/iam/addusertogroup.py000066400000000000000000000033161267461563000233130ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_group class AddUserToGroup(IAMRequest): DESCRIPTION = 'Add a user to a group' ARGS = [arg_group(help='the group to add the user to (required)'), Arg('-u', '--user-name', dest='UserName', required=True, help='the user to add (required)'), AS_ACCOUNT] euca2ools-3.3.1/euca2ools/commands/iam/createaccesskey.py000066400000000000000000000143551267461563000234070ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import sys from requestbuilder import Arg import six from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_user from euca2ools.commands.iam.getuser import GetUser import euca2ools.exceptions import euca2ools.util class CreateAccessKey(IAMRequest): DESCRIPTION = 'Create a new access key for a user' ARGS = [arg_user(help='''user the new key will belong to (default: current user)'''), Arg('-w', '--write-config', action='store_true', route_to=None, help='''output access keys and region information in the form of a euca2ools.ini(5) configuration file instead of by themselves'''), Arg('-d', '--domain', route_to=None, help='''the DNS domain to use for region information in configuration file output (default: based on IAM URL)'''), Arg('-l', '--set-default-user', action='store_true', route_to=None, help='''set this user as the default user for the region in euca2ools.ini(5) configuration file output. This option is only useful when used with -w.'''), AS_ACCOUNT] def postprocess(self, result): if self.args.get('write_config'): parsed = six.moves.urllib.parse.urlparse(self.service.endpoint) if not self.args.get('domain'): dnsname = parsed.netloc.split(':')[0] if all(label.isdigit() for label in dnsname.split('.')): msg = ('warning: IAM URL {0} refers to a specific IP; ' 'for a complete configuration file supply ' 'the region\'s DNS domain with -d/--domain' .format(self.service.endpoint)) print >> sys.stderr, msg else: self.args['domain'] = parsed.netloc.split('.', 1)[1] configfile = six.moves.configparser.SafeConfigParser() if self.args.get('domain'): if ':' not in self.args['domain'] and ':' in parsed.netloc: # Add the port self.args['domain'] += ':' + parsed.netloc.split(':')[1] # This uses self.config.region instead of # self.service.region_name because the latter is a global # service in AWS and thus frequently deferred with "use" # statements. That may eventually happen in eucalyptus # cloud federations as well. # # At some point an option that lets one choose a region # name at the command line may be useful, but until # someone asks for it let's not clutter it up for now. region_name = self.config.region or self.args['domain'] region_section = 'region {0}'.format(region_name.split(':')[0]) configfile.add_section(region_section) for service in sorted(euca2ools.util.generate_service_names()): url = '{scheme}://{service}.{domain}/'.format( scheme=parsed.scheme, domain=self.args['domain'], service=service) configfile.set(region_section, '{0}-url'.format(service), url) user_name = result['AccessKey'].get('UserName') or 'root' account_id = self.get_user_account_id() if account_id: user_name = '{0}:{1}'.format(account_id, user_name) user_section = 'user {0}'.format(user_name) configfile.add_section(user_section) configfile.set(user_section, 'key-id', result['AccessKey']['AccessKeyId']) configfile.set(user_section, 'secret-key', result['AccessKey']['SecretAccessKey']) if account_id: configfile.set(user_section, 'account-id', account_id) if self.args.get('set_default_user'): configfile.set(region_section, 'user', user_name) result['configfile'] = configfile def print_result(self, result): if self.args.get('write_config'): result['configfile'].write(sys.stdout) else: print result['AccessKey']['AccessKeyId'] print result['AccessKey']['SecretAccessKey'] def get_user_account_id(self): req = GetUser.from_other( self, UserName=self.params['UserName'], DelegateAccount=self.params.get('DelegateAccount')) try: response = req.main() except euca2ools.exceptions.AWSError as err: if err.status_code == 403: msg = ('warning: unable to retrieve account ID ({0})' .format(err.message)) print >> sys.stderr, msg return None raise arn = response['User']['Arn'] return arn.split(':')[4] euca2ools-3.3.1/euca2ools/commands/iam/createaccount.py000066400000000000000000000105651267461563000230700ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os.path import sys from requestbuilder import Arg import requestbuilder.exceptions from requestbuilder.mixins import TabifyingMixin import six from euca2ools.commands.iam import IAMRequest, arg_account_name from euca2ools.commands.iam.createaccesskey import CreateAccessKey CLC_CRED_CHECK_FILE = '/usr/sbin/clcadmin-assume-system-credentials' class CreateAccount(IAMRequest, TabifyingMixin): DESCRIPTION = '[Eucalyptus cloud admin only] Create a new account' ARGS = [arg_account_name(nargs='?', help='''also add an alias (name) to the new account (required on eucalyptus < 4.2)'''), Arg('-k', '--create-accesskey', action='store_true', route_to=None, help='''also create an access key for the new account's administrator and show it'''), Arg('-w', '--write-config', action='store_true', route_to=None, help='''output access keys and region information in the form of a euca2ools.ini(5) configuration file instead of by themselves (implies -k)'''), Arg('-d', '--domain', route_to=None, help='''the DNS domain to use for region information in configuration file output (default: based on IAM URL)'''), Arg('-l', '--set-default-user', action='store_true', route_to=None, help='''set this user as the default user for the region in euca2ools.ini(5) configuration file output. This option is only useful when used with -w.''')] def configure(self): try: IAMRequest.configure(self) except requestbuilder.exceptions.AuthError as err: if (os.path.exists(CLC_CRED_CHECK_FILE) and len(err.args) > 0 and isinstance(err.args[0], six.string_types)): msg = ("{0}. If a cloud controller is running, you " "can assume administrator credentials with " "eval `clcadmin-assume-system-credentials`") err.args = (msg.format(err.args[0]),) + err.args[1:] raise def postprocess(self, result): if self.args.get('create_accesskey') or self.args.get('write_config'): obj = CreateAccessKey.from_other( self, UserName='admin', DelegateAccount=result['Account']['AccountId'], write_config=self.args.get('write_config'), domain=self.args.get('domain'), set_default_user=self.args.get('set_default_user')) key_result = obj.main() result.update(key_result) def print_result(self, result): if self.args.get('write_config'): result['configfile'].write(sys.stdout) else: print self.tabify((result.get('Account', {}).get('AccountName'), result.get('Account', {}).get('AccountId'))) if 'AccessKey' in result: print result['AccessKey']['AccessKeyId'] print result['AccessKey']['SecretAccessKey'] euca2ools-3.3.1/euca2ools/commands/iam/createaccountalias.py000066400000000000000000000032111267461563000240700ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_account_alias class CreateAccountAlias(IAMRequest): DESCRIPTION = 'Create an alias for an account, a.k.a. an account name' ARGS = [arg_account_alias(help='name of the alias to create (required)'), AS_ACCOUNT] euca2ools-3.3.1/euca2ools/commands/iam/creategroup.py000066400000000000000000000037231267461563000225660ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_group class CreateGroup(IAMRequest): DESCRIPTION = 'Create a new group' ARGS = [arg_group(help='name of the new group (required)'), Arg('-p', '--path', dest='Path', help='path for the new group (default: "/")'), Arg('-v', '--verbose', action='store_true', route_to=None, help="print the new group's ARN and GUID"), AS_ACCOUNT] def print_result(self, result): if self.args['verbose']: print result['Group']['Arn'] print result['Group']['GroupId'] euca2ools-3.3.1/euca2ools/commands/iam/createinstanceprofile.py000066400000000000000000000070261267461563000246170ustar00rootroot00000000000000# Copyright 2014-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_iprofile from euca2ools.commands.iam.addroletoinstanceprofile import \ AddRoleToInstanceProfile from euca2ools.commands.iam.createrole import CreateRole from requestbuilder import Arg, MutuallyExclusiveArgList class CreateInstanceProfile(IAMRequest): DESCRIPTION = 'Create a new instance profile' ARGS = [arg_iprofile(help='name of the new instance profile (required)'), Arg('-p', '--path', dest='Path', help='path for the new instance profile (default: "/")'), MutuallyExclusiveArgList( Arg('-r', '--add-role', dest='role', route_to=None, help='also add a role to the new instance profile'), Arg('--create-role', dest='create_role', route_to=None, action='store_true', help='''also create a role with the same name and path and add it to the instance profile''')), Arg('-v', '--verbose', action='store_true', route_to=None, help="print the new instance profile's ARN and GUID"), AS_ACCOUNT] def postprocess(self, _): role_name = None if self.args.get('create_role'): role_name = self.args['InstanceProfileName'] req = CreateRole.from_other( self, RoleName=role_name, Path=self.args.get('path'), service_='ec2.amazonaws.com', DelegateAccount=self.args.get('DelegateAccount')) req.main() elif self.args.get('role'): role_name = self.args['role'] if role_name: self.log.info('adding role %s to instance profile %s', self.args['role'], self.args['InstanceProfileName']) req = AddRoleToInstanceProfile.from_other( self, RoleName=role_name, InstanceProfileName=self.args['InstanceProfileName'], DelegateAccount=self.args.get('DelegateAccount')) req.main() def print_result(self, result): if self.args.get('verbose'): print result.get('InstanceProfile', {}).get('Arn') print result.get('InstanceProfile', {}).get('InstanceProfileId') euca2ools-3.3.1/euca2ools/commands/iam/createloginprofile.py000066400000000000000000000041241267461563000241170ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_user from euca2ools.util import prompt_for_password class CreateLoginProfile(IAMRequest): DESCRIPTION = 'Create a password for the specified user' ARGS = [arg_user( help='name of the user to create a password for (required)'), Arg('-p', '--password', dest='Password', help='''the new password. If unspecified, the new password will be read from the console.'''), AS_ACCOUNT] def configure(self): IAMRequest.configure(self) if self.args['Password'] is None: self.log.info('no password supplied; prompting') self.params['Password'] = prompt_for_password() euca2ools-3.3.1/euca2ools/commands/iam/createrole.py000066400000000000000000000063651267461563000224000ustar00rootroot00000000000000# Copyright (c) 2014-2016 Hewlett Packard Enterprise Development LP # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse import json import urllib from requestbuilder import Arg, MutuallyExclusiveArgList from euca2ools.commands.argtypes import file_contents from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_role class CreateRole(IAMRequest): DESCRIPTION = 'Create a new role' ARGS = [arg_role(help='name of the new role (required)'), Arg('-p', '--path', dest='Path', help='path for the new role (default: "/")'), MutuallyExclusiveArgList( Arg('-f', '--trust-policy', dest='AssumeRolePolicyDocument', metavar='FILE', type=file_contents, help='file containing the trust policy for the new role'), Arg('-s', '--service', dest='service_', metavar='SERVICE', route_to=None, help='''service to allow access to the role (e.g. ec2.amazonaws.com)'''), # For compatibility with a typo in < 3.2.1 Arg('--service_', route_to=None, help=argparse.SUPPRESS)) .required(), Arg('-v', '--verbose', action='store_true', route_to=None, help="print the new role's ARN, GUID, and policy"), AS_ACCOUNT] def preprocess(self): if self.args.get('service_'): statement = {'Effect': 'Allow', 'Principal': {'Service': [self.args['service_']]}, 'Action': ['sts:AssumeRole']} policy = {'Version': '2008-10-17', 'Statement': [statement]} self.params['AssumeRolePolicyDocument'] = json.dumps(policy) def print_result(self, result): if self.args.get('verbose'): print result.get('Role', {}).get('Arn') print result.get('Role', {}).get('RoleId') print urllib.unquote(result.get('Role', {}) .get('AssumeRolePolicyDocument')) euca2ools-3.3.1/euca2ools/commands/iam/createsigningcertificate.py000066400000000000000000000052121267461563000252660ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_user class CreateSigningCertificate(IAMRequest): DESCRIPTION = '[Eucalyptus only] Create a new signing certificate' ARGS = [arg_user(nargs='?', help='''user to create the signing certificate for (default: current user)'''), Arg('--out', metavar='FILE', route_to=None, help='file to write the certificate to (default: stdout)'), Arg('--keyout', metavar='FILE', route_to=None, help='file to write the private key to (default: stdout)'), AS_ACCOUNT] def postprocess(self, result): if self.args['out']: with open(self.args['out'], 'w') as certfile: certfile.write(result['Certificate']['CertificateBody']) if self.args['keyout']: old_umask = os.umask(0o077) with open(self.args['keyout'], 'w') as keyfile: keyfile.write(result['Certificate']['PrivateKey']) os.umask(old_umask) def print_result(self, result): print result['Certificate']['CertificateId'] if not self.args['out']: print result['Certificate']['CertificateBody'] if not self.args['keyout']: print result['Certificate']['PrivateKey'] euca2ools-3.3.1/euca2ools/commands/iam/createuser.py000066400000000000000000000114301267461563000224020ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import sys from requestbuilder import Arg, MutuallyExclusiveArgList from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_user from euca2ools.commands.iam.addusertogroup import AddUserToGroup from euca2ools.commands.iam.createaccesskey import CreateAccessKey from euca2ools.commands.iam.getgroup import GetGroup class CreateUser(IAMRequest): DESCRIPTION = 'Create a new user' ARGS = [arg_user(help='name of the new user (required)'), Arg('-p', '--path', dest='Path', help='path for the new user (default: "/")'), Arg('-g', '--group-name', route_to=None, help='also add the new user to a group'), Arg('--verify', action='store_true', route_to=None, help='''ensure the group given with -g exists before doing anything'''), Arg('-k', '--create-accesskey', action='store_true', route_to=None, help='also create an access key for the new user and show it'), MutuallyExclusiveArgList( Arg('-v', '--verbose', action='store_true', route_to=None, help="show the new user's ARN and GUID"), Arg('-w', '--write-config', action='store_true', route_to=None, help='''output access keys and region information in the form of a euca2ools.ini(5) configuration file instead of by themselves (implies -k)''')), Arg('-d', '--domain', route_to=None, help='''the DNS domain to use for region information in configuration file output (default: based on IAM URL)'''), Arg('-l', '--set-default-user', action='store_true', route_to=None, help='''set this user as the default user for the region in euca2ools.ini(5) configuration file output. This option is only useful when used with -w.'''), AS_ACCOUNT] def preprocess(self): if self.args.get('verify') and self.args.get('group_name'): obj = GetGroup.from_other( self, GroupName=self.args['group_name'], DelegateAccount=self.params['DelegateAccount']) # This will blow up if the group does not exist. obj.main() def postprocess(self, result): if self.args.get('group_name'): obj = AddUserToGroup.from_other( self, UserName=self.args['UserName'], GroupName=self.args['group_name'], DelegateAccount=self.params['DelegateAccount']) obj.main() if self.args.get('create_accesskey') or self.args.get('write_config'): obj = CreateAccessKey.from_other( self, UserName=self.args['UserName'], DelegateAccount=self.params['DelegateAccount'], write_config=self.args.get('write_config'), domain=self.args.get('domain'), set_default_user=self.args.get('set_default_user')) key_result = obj.main() result.update(key_result) def print_result(self, result): if self.args.get('write_config'): result['configfile'].write(sys.stdout) else: if self.args['verbose']: print result['User']['Arn'] print result['User']['UserId'] if 'AccessKey' in result: print result['AccessKey']['AccessKeyId'] print result['AccessKey']['SecretAccessKey'] euca2ools-3.3.1/euca2ools/commands/iam/deactivatemfadevice.py000066400000000000000000000035241267461563000242220ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_user class DeactivateMFADevice(IAMRequest): DESCRIPTION = 'Deactivate an MFA device' ARGS = [arg_user( help='user owning the MFA device to deactivate (required)'), Arg('-s', '--serial-number', dest='SerialNumber', metavar='SERIAL', required=True, help='''serial number of the MFA device to deactivate (required)'''), AS_ACCOUNT] euca2ools-3.3.1/euca2ools/commands/iam/deleteaccesskey.py000066400000000000000000000033501267461563000233770ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_key_id class DeleteAccessKey(IAMRequest): DESCRIPTION = 'Delete an access key' ARGS = [arg_key_id(help='ID of the access key to delete (required)'), Arg('-u', '--user-name', dest='UserName', metavar='USER', help='user the key belongs to (default: current user)'), AS_ACCOUNT] euca2ools-3.3.1/euca2ools/commands/iam/deleteaccount.py000066400000000000000000000035311267461563000230620ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, arg_account_name class DeleteAccount(IAMRequest): DESCRIPTION = '[Eucalyptus cloud admin only] Delete an account' ARGS = [arg_account_name( help='name or ID of the account to delete (required)'), Arg('-r', '--recursive', dest='Recursive', action='store_const', const='true', help='''delete all users, groups, and policies associated with the account as well''')] euca2ools-3.3.1/euca2ools/commands/iam/deleteaccountalias.py000066400000000000000000000032051267461563000240720ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_account_alias class DeleteAccountAlias(IAMRequest): DESCRIPTION = "Delete an account's alias, a.k.a. its account name" ARGS = [arg_account_alias(help='name of the alias to delete (required)'), AS_ACCOUNT] euca2ools-3.3.1/euca2ools/commands/iam/deleteaccountpolicy.py000066400000000000000000000035301267461563000243010ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, arg_account_name class DeleteAccountPolicy(IAMRequest): DESCRIPTION = ('[Eucalyptus cloud admin only] Remove a policy from an ' 'account') ARGS = [arg_account_name(help='''name or ID of the account the policy is attached to (required)'''), Arg('-p', '--policy-name', dest='PolicyName', metavar='POLICY', required=True, help='name of the policy to delete (required)')] euca2ools-3.3.1/euca2ools/commands/iam/deletegroup.py000066400000000000000000000102351267461563000225610ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_group from euca2ools.commands.iam.deletegrouppolicy import DeleteGroupPolicy from euca2ools.commands.iam.getgroup import GetGroup from euca2ools.commands.iam.listgrouppolicies import ListGroupPolicies from euca2ools.commands.iam.removeuserfromgroup import RemoveUserFromGroup class DeleteGroup(IAMRequest): DESCRIPTION = 'Delete a group' ARGS = [arg_group(help='name of the group to delete (required)'), Arg('-r', '--recursive', action='store_true', route_to=None, help='''remove all user memberships and policies associated with the group first'''), Arg('-R', '--recursive-euca', dest='IsRecursive', action='store_const', const='true', help=argparse.SUPPRESS), Arg('-p', '--pretend', action='store_true', route_to=None, help='''list the user memberships and policies that would be deleted instead of actually deleting them. Implies -r.'''), AS_ACCOUNT] def main(self): if self.args['recursive'] or self.args['pretend']: # Figure out what we'd have to delete req = GetGroup.from_other( self, GroupName=self.args['GroupName'], DelegateAccount=self.params['DelegateAccount']) members = req.main().get('Users', []) req = ListGroupPolicies.from_other( self, GroupName=self.args['GroupName'], DelegateAccount=self.params['DelegateAccount']) policies = req.main().get('PolicyNames', []) else: # Just in case members = [] policies = [] if self.args['pretend']: return {'members': [member['Arn'] for member in members], 'policies': policies} else: if self.args['recursive']: member_names = [member['UserName'] for member in members] req = RemoveUserFromGroup.from_other( self, GroupName=self.args['GroupName'], user_names=member_names, DelegateAccount=self.params['DelegateAccount']) req.main() for policy in policies: req = DeleteGroupPolicy.from_other( self, GroupName=self.args['GroupName'], PolicyName=policy, DelegateAccount=self.params['DelegateAccount']) req.main() return self.send() def print_result(self, result): if self.args['pretend']: print 'users' for arn in result['members']: print '\t' + arn print 'policies' for policy in result['policies']: print '\t' + policy euca2ools-3.3.1/euca2ools/commands/iam/deletegrouppolicy.py000066400000000000000000000033761267461563000240110ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_group class DeleteGroupPolicy(IAMRequest): DESCRIPTION = 'Remove a policy from a group' ARGS = [arg_group(help='group the policy is attached to (required)'), Arg('-p', '--policy-name', dest='PolicyName', metavar='POLICY', required=True, help='name of the policy to delete (required)'), AS_ACCOUNT] euca2ools-3.3.1/euca2ools/commands/iam/deleteinstanceprofile.py000066400000000000000000000106731267461563000246200ustar00rootroot00000000000000# Copyright 2014-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_iprofile from euca2ools.commands.iam.deleterole import DeleteRole from euca2ools.commands.iam.getinstanceprofile import GetInstanceProfile from euca2ools.commands.iam.removerolefrominstanceprofile import \ RemoveRoleFromInstanceProfile class DeleteInstanceProfile(IAMRequest): DESCRIPTION = ('Delete an instance profile\n\nThis will break any running ' 'instances that depend upon access to the deleted instance ' 'profile.') ARGS = [arg_iprofile( help='name of the instance profile to delete (required)'), Arg('-r', '--recursive', action='store_true', route_to=None, help='''remove all IAM resources associated with the instance profile first'''), Arg('-p', '--pretend', action='store_true', route_to=None, help='''list the resources that would be deleted instead of actually deleting them. Implies -r.'''), AS_ACCOUNT] def main(self): if self.args.get('recursive') or self.args.get('pretend'): # Figure out what we have to delete req = GetInstanceProfile.from_other( self, InstanceProfileName=self.args['InstanceProfileName'], DelegateAccount=self.args.get('DelegateAccount')) response = req.main() roles = [] for role in response.get('InstanceProfile', {}).get('Roles') or []: roles.append({'arn': role.get('Arn'), 'name': role.get('RoleName')}) else: # Just in case roles = [] if self.args.get('pretend'): return {'roles': roles} else: if self.args.get('recursive'): for role in roles: req = RemoveRoleFromInstanceProfile.from_other( self, RoleName=role['name'], InstanceProfileName=self.args['InstanceProfileName'], DelegateAccount=self.args.get('DelegateAccount')) req.main() # This role could be attached to another instance # profile, which means that a truly-recursive delete # would need to also remove it from that instance # profile, delete all of the role's policies, and # so on. The failure modes for this are rather nasty, # so we don't tell DeleteRole to delete recursively; # if the same role belongs to more than one instance # profile then DeleteRole will simply fail harmlessly. req = DeleteRole.from_other( self, RoleName=role['name'], DelegateAccount=self.args.get('DelegateAccount')) req.main() return self.send() def print_result(self, result): if self.args.get('pretend'): print 'roles' for role in result['roles']: print '\t' + role['arn'] euca2ools-3.3.1/euca2ools/commands/iam/deleteloginprofile.py000066400000000000000000000032101267461563000241110ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_user class DeleteLoginProfile(IAMRequest): DESCRIPTION = "Delete a user's password" ARGS = [arg_user(help='''name of the user whose password should be deleted (required)'''), AS_ACCOUNT] euca2ools-3.3.1/euca2ools/commands/iam/deleterole.py000066400000000000000000000107121267461563000223660ustar00rootroot00000000000000# Copyright 2014-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_role from euca2ools.commands.iam.deleterolepolicy import DeleteRolePolicy from euca2ools.commands.iam.listinstanceprofilesforrole import \ ListInstanceProfilesForRole from euca2ools.commands.iam.listrolepolicies import ListRolePolicies from euca2ools.commands.iam.removerolefrominstanceprofile import \ RemoveRoleFromInstanceProfile class DeleteRole(IAMRequest): DESCRIPTION = 'Delete a role' ARGS = [arg_role(help='name of the role to delete (required)'), Arg('-c', '--recursive', action='store_true', route_to=None, help='''remove all IAM resources associated with the role first'''), Arg('-p', '--pretend', action='store_true', route_to=None, help='''list the resources that would be deleted instead of actually deleting them. Implies -c.'''), AS_ACCOUNT] def main(self): if self.args.get('recursive') or self.args.get('pretend'): # Figure out what we have to delete req = ListInstanceProfilesForRole.from_other( self, RoleName=self.args['RoleName'], DelegateAccount=self.args.get('DelegateAccount')) response = req.main() instance_profiles = [] for profile in response.get('InstanceProfiles') or []: instance_profiles.append( {'arn': profile.get('Arn'), 'name': profile.get('InstanceProfileName')}) req = ListRolePolicies.from_other( self, RoleName=self.args['RoleName'], DelegateAccount=self.args.get('DelegateAccount')) response = req.main() policies = [] for policy in response.get('PolicyNames') or []: policies.append(policy) else: # Just in case instance_profiles = [] policies = [] if self.args.get('pretend'): return {'instance_profiles': instance_profiles, 'policies': policies} else: if self.args.get('recursive'): for profile in instance_profiles: req = RemoveRoleFromInstanceProfile.from_other( self, RoleName=self.args['RoleName'], InstanceProfileName=profile['name'], DelegateAccount=self.args.get('DelegateAccount')) req.main() for policy in policies: req = DeleteRolePolicy.from_other( self, RoleName=self.args['RoleName'], PolicyName=policy, DelegateAccount=self.args.get('DelegateAccount')) req.main() return self.send() def print_result(self, result): if self.args.get('pretend'): print 'instance profiles' for profile in result['instance_profiles']: print '\t' + profile['arn'] print 'policies' for policy in result['policies']: print '\t' + policy euca2ools-3.3.1/euca2ools/commands/iam/deleterolepolicy.py000066400000000000000000000033711267461563000236110ustar00rootroot00000000000000# Copyright 2014-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_role class DeleteRolePolicy(IAMRequest): DESCRIPTION = 'Remove a policy from a role' ARGS = [arg_role(help='role the policy is attached to (required)'), Arg('-p', '--policy-name', dest='PolicyName', metavar='POLICY', required=True, help='name of the policy to delete (required)'), AS_ACCOUNT] euca2ools-3.3.1/euca2ools/commands/iam/deleteservercertificate.py000066400000000000000000000032151267461563000251360ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_server_cert class DeleteServerCertificate(IAMRequest): DESCRIPTION = 'Delete a server certificate' ARGS = [arg_server_cert( help='name of the server certificate to delete (required)'), AS_ACCOUNT] euca2ools-3.3.1/euca2ools/commands/iam/deletesigningcertificate.py000066400000000000000000000035031267461563000252660ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_signing_cert class DeleteSigningCertificate(IAMRequest): DESCRIPTION = 'Delete a signing certificate' ARGS = [arg_signing_cert( help='ID of the signing certificate to delete (required)'), Arg('-u', '--user-name', dest='UserName', metavar='USER', help='''user the signing certificate belongs to (default: current user)'''), AS_ACCOUNT] euca2ools-3.3.1/euca2ools/commands/iam/deleteuser.py000066400000000000000000000156511267461563000224120ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_user from euca2ools.commands.iam.deleteaccesskey import DeleteAccessKey from euca2ools.commands.iam.deleteloginprofile import DeleteLoginProfile from euca2ools.commands.iam.deletesigningcertificate import \ DeleteSigningCertificate from euca2ools.commands.iam.deleteuserpolicy import DeleteUserPolicy from euca2ools.commands.iam.getloginprofile import GetLoginProfile from euca2ools.commands.iam.listaccesskeys import ListAccessKeys from euca2ools.commands.iam.listgroupsforuser import ListGroupsForUser from euca2ools.commands.iam.listsigningcertificates import \ ListSigningCertificates from euca2ools.commands.iam.listuserpolicies import ListUserPolicies from euca2ools.commands.iam.removeuserfromgroup import RemoveUserFromGroup from euca2ools.exceptions import AWSError class DeleteUser(IAMRequest): DESCRIPTION = 'Delete a user' ARGS = [arg_user(help='name of the user to delete (required)'), Arg('-r', '--recursive', action='store_true', route_to=None, help='''remove all IAM resources associated with the user first'''), Arg('-R', '--recursive-euca', dest='IsRecursive', action='store_const', const='true', help=argparse.SUPPRESS), Arg('-p', '--pretend', action='store_true', route_to=None, help='''list the resources that would be deleted instead of actually deleting them. Implies -r.'''), AS_ACCOUNT] def main(self): if self.args['recursive'] or self.args['pretend']: # Figure out what we'd have to delete req = ListAccessKeys.from_other( self, UserName=self.args['UserName'], DelegateAccount=self.params['DelegateAccount']) keys = req.main().get('AccessKeyMetadata', []) req = ListUserPolicies.from_other( self, UserName=self.args['UserName'], DelegateAccount=self.params['DelegateAccount']) policies = req.main().get('PolicyNames', []) req = ListSigningCertificates.from_other( self, UserName=self.args['UserName'], DelegateAccount=self.params['DelegateAccount']) certs = req.main().get('Certificates', []) req = ListGroupsForUser.from_other( self, UserName=self.args['UserName'], DelegateAccount=self.params['DelegateAccount']) groups = req.main().get('Groups', []) req = GetLoginProfile.from_other( self, UserName=self.args['UserName'], DelegateAccount=self.params['DelegateAccount']) try: # This will raise an exception if no login profile is found. req.main() has_login_profile = True except AWSError as err: if err.code == 'NoSuchEntity': # It doesn't exist has_login_profile = False else: # Something else went wrong; not our problem raise else: # Just in case keys = [] policies = [] certs = [] groups = [] has_login_profile = False if self.args['pretend']: return {'keys': keys, 'policies': policies, 'certificates': certs, 'groups': groups, 'has_login_profile': has_login_profile} else: if self.args['recursive']: for key in keys: req = DeleteAccessKey.from_other( self, UserName=self.args['UserName'], AccessKeyId=key['AccessKeyId'], DelegateAccount=self.params['DelegateAccount']) req.main() for policy in policies: req = DeleteUserPolicy.from_other( self, UserName=self.args['UserName'], PolicyName=policy, DelegateAccount=self.params['DelegateAccount']) req.main() for cert in certs: req = DeleteSigningCertificate.from_other( self, UserName=self.args['UserName'], CertificateId=cert['CertificateId'], DelegateAccount=self.params['DelegateAccount']) req.main() for group in groups: req = RemoveUserFromGroup.from_other( self, user_names=[self.args['UserName']], GroupName=group['GroupName'], DelegateAccount=self.params['DelegateAccount']) req.main() if has_login_profile: req = DeleteLoginProfile.from_other( self, UserName=self.args['UserName'], DelegateAccount=self.params['DelegateAccount']) req.main() return self.send() def print_result(self, result): if self.args['pretend']: print 'accesskeys' for key in result['keys']: print '\t' + key['AccessKeyId'] print 'policies' for policy in result['policies']: print '\t' + policy print 'certificates' for cert in result['certificates']: print '\t' + cert['CertificateId'] print 'groups' for group in result['groups']: print '\t' + group['Arn'] euca2ools-3.3.1/euca2ools/commands/iam/deleteuserpolicy.py000066400000000000000000000033711267461563000236260ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_user class DeleteUserPolicy(IAMRequest): DESCRIPTION = 'Remove a policy from a user' ARGS = [arg_user(help='user the policy is attached to (required)'), Arg('-p', '--policy-name', dest='PolicyName', metavar='POLICY', required=True, help='name of the policy to delete (required)'), AS_ACCOUNT] euca2ools-3.3.1/euca2ools/commands/iam/enablemfadevice.py000066400000000000000000000043051267461563000233350ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_user class EnableMFADevice(IAMRequest): DESCRIPTION = 'Enable an MFA device' ARGS = [arg_user(help='user to enable the MFA device for (required)'), Arg('-s', '--serial-number', dest='SerialNumber', metavar='SERIAL', required=True, help='serial number of the MFA device to activate (required)'), Arg('-c1', dest='AuthenticationCode1', metavar='CODE', required=True, help='''an authentication code emitted by the MFA device (required)'''), Arg('-c2', dest='AuthenticationCode2', metavar='CODE', required=True, help='''a subsequent authentication code emitted by the MFA device (required)'''), AS_ACCOUNT] euca2ools-3.3.1/euca2ools/commands/iam/getaccountpolicy.py000066400000000000000000000050101267461563000236110ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import json import urllib from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, arg_account_name class GetAccountPolicy(IAMRequest): DESCRIPTION = "[Eucalyptus cloud admin only] Display an account's policy" ARGS = [arg_account_name(help='''name or ID of the account the policy is attached to (required)'''), Arg('-p', '--policy-name', dest='PolicyName', metavar='POLICY', required=True, help='name of the policy to show (required)'), Arg('--pretty-print', action='store_true', route_to=None, help='reformat the policy for easier reading')] def print_result(self, result): policy_content = urllib.unquote(result['PolicyDocument']) if self.args['pretty_print']: try: policy_json = json.loads(policy_content) except ValueError: self.log.debug('JSON parse error', exc_info=True) raise ValueError( "policy '{0}' does not appear to be valid JSON" .format(self.args['PolicyName'])) policy_content = json.dumps(policy_json, indent=4) print policy_content euca2ools-3.3.1/euca2ools/commands/iam/getaccountsummary.py000066400000000000000000000033751267461563000240230ustar00rootroot00000000000000# Copyright 2009-2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT class GetAccountSummary(IAMRequest): DESCRIPTION = ('Display account-level information about account entity ' 'usage and IAM quotas') ARGS = [AS_ACCOUNT] LIST_TAGS = ['SummaryMap'] def print_result(self, result): for entry in sorted(result.get('SummaryMap', [])): print '{0}: {1}'.format(entry.get('key'), entry.get('value')) euca2ools-3.3.1/euca2ools/commands/iam/getgroup.py000066400000000000000000000042441267461563000221010ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from requestbuilder.response import PaginatedResponse from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_group class GetGroup(IAMRequest): DESCRIPTION = 'List all the users in a group' ARGS = [arg_group(help='name of the group to enumerate (required)'), AS_ACCOUNT] LIST_TAGS = ['Users'] def main(self): return PaginatedResponse(self, (None,), ('Users',)) def prepare_for_page(self, page): # Pages are defined by markers self.params['Marker'] = page def get_next_page(self, response): if response.get('IsTruncated') == 'true': return response['Marker'] def print_result(self, result): print result['Group']['Arn'] print ' ', 'users' for user in result.get('Users', []): print ' ', user['Arn'] euca2ools-3.3.1/euca2ools/commands/iam/getgrouppolicy.py000066400000000000000000000047061267461563000233240ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import json import urllib from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_group class GetGroupPolicy(IAMRequest): DESCRIPTION = "Display a group's policy" ARGS = [arg_group(help='group the policy is attached to (required)'), Arg('-p', '--policy-name', dest='PolicyName', metavar='POLICY', required=True, help='name of the policy to show (required)'), Arg('--pretty-print', action='store_true', route_to=None, help='reformat the policy for easier reading'), AS_ACCOUNT] def print_result(self, result): policy_content = urllib.unquote(result['PolicyDocument']) if self.args['pretty_print']: try: policy_json = json.loads(policy_content) except ValueError: self.log.debug('JSON parse error', exc_info=True) raise ValueError( "policy '{0}' does not appear to be valid JSON" .format(self.args['PolicyName'])) policy_content = json.dumps(policy_json, indent=4) print policy_content euca2ools-3.3.1/euca2ools/commands/iam/getinstanceprofile.py000066400000000000000000000042431267461563000241310ustar00rootroot00000000000000# Copyright 2014-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_iprofile class GetInstanceProfile(IAMRequest): DESCRIPTION = "Display an instance profile's ARN and GUID" ARGS = [arg_iprofile( help='name of the instance profile to describe (required)'), Arg('-r', dest='show_roles', action='store_true', route_to=None, help='''also list the roles associated with the instance profile'''), AS_ACCOUNT] LIST_TAGS = ['Roles'] def print_result(self, result): print result.get('InstanceProfile', {}).get('Arn') print result.get('InstanceProfile', {}).get('InstanceProfileId') if self.args.get('show_roles'): for role in result.get('InstanceProfile', {}).get('Roles') or []: print role.get('Arn') euca2ools-3.3.1/euca2ools/commands/iam/getldapsyncstatus.py000066400000000000000000000033771267461563000240340ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder.mixins import TabifyingMixin from euca2ools.commands.iam import IAMRequest class GetLdapSyncStatus(IAMRequest, TabifyingMixin): DESCRIPTION = ("[Eucalyptus cloud admin only] Show the status of the " "cloud's LDAP synchronization") def print_result(self, result): print self.tabify(('SyncEnabled', result.get('SyncEnabled'))) print self.tabify(('InSync', result.get('InSync'))) euca2ools-3.3.1/euca2ools/commands/iam/getloginprofile.py000066400000000000000000000045231267461563000234360ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_user class GetLoginProfile(IAMRequest): DESCRIPTION = 'Verify that a user has a password' ARGS = [arg_user( help='user owning the password to check (required)'), Arg('--verbose', action='store_true', route_to=None, help="print extra info about the user's password"), AS_ACCOUNT] def print_result(self, result): # If we've managed to get to this point, we already know the user has # a login profile. user_name = result['LoginProfile'].get('UserName') print 'Login Profile Exists for User', user_name if self.args['verbose']: create_date = result['LoginProfile'].get('CreateDate') if create_date: print 'Creation date:', create_date must_change = result['LoginProfile'].get('MustChangePassword') if must_change: print 'Must change password:', must_change euca2ools-3.3.1/euca2ools/commands/iam/getrole.py000066400000000000000000000035551267461563000217120ustar00rootroot00000000000000# Copyright 2014-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import urllib from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_role class GetRole(IAMRequest): DESCRIPTION = "Display a role's ARN, GUID, and trust policy" ARGS = [arg_role(help='name of the role to describe (required)'), AS_ACCOUNT] def print_result(self, result): print result.get('Role', {}).get('Arn') print result.get('Role', {}).get('RoleId') print urllib.unquote(result.get('Role', {}) .get('AssumeRolePolicyDocument')) euca2ools-3.3.1/euca2ools/commands/iam/getrolepolicy.py000066400000000000000000000047011267461563000231240ustar00rootroot00000000000000# Copyright 2014-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import json import urllib from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_role class GetRolePolicy(IAMRequest): DESCRIPTION = "Display a role's policy" ARGS = [arg_role(help='role the poilcy is attached to (required)'), Arg('-p', '--policy-name', dest='PolicyName', metavar='POLICY', required=True, help='name of the policy to show (required)'), Arg('--pretty-print', action='store_true', route_to=None, help='reformat the policy for easier reading'), AS_ACCOUNT] def print_result(self, result): policy_content = urllib.unquote(result['PolicyDocument']) if self.args['pretty_print']: try: policy_json = json.loads(policy_content) except ValueError: self.log.debug('JSON parse error', exc_info=True) raise ValueError( "policy '{0}' does not appear to be valid JSON" .format(self.args['PolicyName'])) policy_content = json.dumps(policy_json, indent=4) print policy_content euca2ools-3.3.1/euca2ools/commands/iam/getservercertificate.py000066400000000000000000000036361267461563000244620ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_server_cert class GetServerCertificate(IAMRequest): DESCRIPTION = 'Show the ARN and GUID of a server certificate' ARGS = [arg_server_cert(help='''name of the server certificate to describe (required)'''), AS_ACCOUNT] def print_result(self, result): metadata = result.get('ServerCertificate', {}) \ .get('ServerCertificateMetadata', {}) print metadata.get('Arn') print metadata.get('ServerCertificateId') euca2ools-3.3.1/euca2ools/commands/iam/getuser.py000066400000000000000000000041251267461563000217210ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_user class GetUser(IAMRequest): DESCRIPTION = "Display a user's ARN and GUID" ARGS = [arg_user(nargs='?', help='''name of the user to describe (default: current user)'''), Arg('--show-extra', dest='ShowExtra', action='store_const', const='true', help='also display additional user info'), AS_ACCOUNT] def print_result(self, result): print result['User']['Arn'] print result['User']['UserId'] if self.args['ShowExtra'] == 'true': for attr in ('CreateDate', 'Enabled', 'RegStatus', 'PasswordExpiration'): print result['User'].get(attr, '') euca2ools-3.3.1/euca2ools/commands/iam/getuserinfo.py000066400000000000000000000040031267461563000225700ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_user class GetUserInfo(IAMRequest, TabifyingMixin): DESCRIPTION = '[Eucalyptus only] Display information about a user' ARGS = [arg_user(nargs='?', help='''name of the user to describe (default: current user)'''), Arg('-k', '--info-key', dest='InfoKey', help='name of the piece of user info to show'), AS_ACCOUNT] LIST_TAGS = ['Infos'] def print_result(self, result): for info in result.get('Infos', []): print self.tabify((info.get('Key'), info.get('Value'))) euca2ools-3.3.1/euca2ools/commands/iam/getuserpolicy.py000066400000000000000000000047011267461563000231410ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import json import urllib from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_user class GetUserPolicy(IAMRequest): DESCRIPTION = "Display a user's policy" ARGS = [arg_user(help='user the poilcy is attached to (required)'), Arg('-p', '--policy-name', dest='PolicyName', metavar='POLICY', required=True, help='name of the policy to show (required)'), Arg('--pretty-print', action='store_true', route_to=None, help='reformat the policy for easier reading'), AS_ACCOUNT] def print_result(self, result): policy_content = urllib.unquote(result['PolicyDocument']) if self.args['pretty_print']: try: policy_json = json.loads(policy_content) except ValueError: self.log.debug('JSON parse error', exc_info=True) raise ValueError( "policy '{0}' does not appear to be valid JSON" .format(self.args['PolicyName'])) policy_content = json.dumps(policy_json, indent=4) print policy_content euca2ools-3.3.1/euca2ools/commands/iam/listaccesskeys.py000066400000000000000000000043451267461563000233000ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from requestbuilder.response import PaginatedResponse from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_user class ListAccessKeys(IAMRequest): DESCRIPTION = "List a user's access keys" ARGS = [arg_user(nargs='?', help='user to list keys for (default: current user)'), AS_ACCOUNT] LIST_TAGS = ['AccessKeyMetadata'] def main(self): return PaginatedResponse(self, (None,), ('AccessKeyMetadata',)) def prepare_for_page(self, page): # Pages are defined by markers self.params['Marker'] = page def get_next_page(self, response): if response.get('IsTruncated') == 'true': return response['Marker'] def print_result(self, result): for accesskey in result.get('AccessKeyMetadata', []): print accesskey.get('AccessKeyId') print accesskey.get('Status') euca2ools-3.3.1/euca2ools/commands/iam/listaccountaliases.py000066400000000000000000000035171267461563000241410ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT class ListAccountAliases(IAMRequest): DESCRIPTION = "List your account's aliases" ARGS = [AS_ACCOUNT] LIST_TAGS = ['AccountAliases'] def print_result(self, result): # These are technically allowed to paginate, but I haven't seen # accounts with lots of aliases in the wild yet. If that starts # happening, feel free to implement it. for alias in result.get('AccountAliases', []): print 'Alias:', alias euca2ools-3.3.1/euca2ools/commands/iam/listaccountpolicies.py000066400000000000000000000071501267461563000243240ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from requestbuilder.response import PaginatedResponse from euca2ools.commands.iam import IAMRequest, arg_account_name from euca2ools.commands.iam.getaccountpolicy import GetAccountPolicy class ListAccountPolicies(IAMRequest): DESCRIPTION = ('[Eucalyptus only] List one or all policies ' 'policies attached to an account') ARGS = [arg_account_name(help='''name or ID of the account owning the policies to list (required)'''), Arg('-p', '--policy-name', metavar='POLICY', route_to=None, help='display a specific policy'), Arg('-v', '--verbose', action='store_true', route_to=None, help='''display the contents of the resulting policies (in addition to their names)'''), Arg('--pretty-print', action='store_true', route_to=None, help='''when printing the contents of policies, reformat them for easier reading''')] LIST_TAGS = ['PolicyNames'] def main(self): return PaginatedResponse(self, (None,), ('PolicyNames',)) def prepare_for_page(self, page): # Pages are defined by markers self.params['Marker'] = page def get_next_page(self, response): if response.get('IsTruncated') == 'true': return response['Marker'] def print_result(self, result): if self.args.get('policy_name'): # Look for the specific policy the user asked for for policy_name in result.get('PolicyNames', []): if policy_name == self.args['policy_name']: if self.args['verbose']: self.print_policy(policy_name) else: print policy_name break else: for policy_name in result.get('PolicyNames', []): print policy_name if self.args['verbose']: self.print_policy(policy_name) def print_policy(self, policy_name): req = GetAccountPolicy( service=self.service, AccountName=self.args['AccountName'], PolicyName=policy_name, pretty_print=self.args['pretty_print']) response = req.main() req.print_result(response) euca2ools-3.3.1/euca2ools/commands/iam/listaccounts.py000066400000000000000000000034521267461563000227600ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder.mixins import TabifyingMixin from euca2ools.commands.iam import IAMRequest class ListAccounts(IAMRequest, TabifyingMixin): DESCRIPTION = ("[Eucalyptus cloud admin only] List all of the cloud's " "accounts") LIST_TAGS = ['Accounts'] def print_result(self, result): for account in result.get('Accounts', []): print self.tabify((account.get('AccountName'), account.get('AccountId'))) euca2ools-3.3.1/euca2ools/commands/iam/listgrouppolicies.py000066400000000000000000000071021267461563000240210ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from requestbuilder.response import PaginatedResponse from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_group from euca2ools.commands.iam.getgrouppolicy import GetGroupPolicy class ListGroupPolicies(IAMRequest): DESCRIPTION = 'List one or all policies attached to a group' ARGS = [arg_group(help='group owning the policies to list (required)'), Arg('-p', '--policy-name', metavar='POLICY', route_to=None, help='display a specific policy'), Arg('-v', '--verbose', action='store_true', route_to=None, help='''display the contents of the resulting policies (in addition to their names)'''), Arg('--pretty-print', action='store_true', route_to=None, help='''when printing the contents of policies, reformat them for easier reading'''), AS_ACCOUNT] LIST_TAGS = ['PolicyNames'] def main(self): return PaginatedResponse(self, (None,), ('PolicyNames',)) def prepare_for_page(self, page): # Pages are defined by markers self.params['Marker'] = page def get_next_page(self, response): if response.get('IsTruncated') == 'true': return response['Marker'] def print_result(self, result): if self.args.get('policy_name'): # Look for the specific policy the user asked for for policy_name in result.get('PolicyNames', []): if policy_name == self.args['policy_name']: if self.args['verbose']: self.print_policy(policy_name) else: print policy_name break else: for policy_name in result.get('PolicyNames', []): print policy_name if self.args['verbose']: self.print_policy(policy_name) def print_policy(self, policy_name): req = GetGroupPolicy.from_other( self, GroupName=self.args['GroupName'], PolicyName=policy_name, pretty_print=self.args['pretty_print'], DelegateAccount=self.params.get('DelegateAccount')) response = req.main() req.print_result(response) euca2ools-3.3.1/euca2ools/commands/iam/listgroups.py000066400000000000000000000043021267461563000224530ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from requestbuilder.response import PaginatedResponse from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT class ListGroups(IAMRequest): DESCRIPTION = "List your account's groups" ARGS = [Arg('-p', '--path-prefix', dest='PathPrefix', metavar='PATH', help='limit results to groups that begin with a given path'), AS_ACCOUNT] LIST_TAGS = ['Groups'] def main(self): return PaginatedResponse(self, (None,), ('Groups',)) def prepare_for_page(self, page): # Pages are defined by markers self.params['Marker'] = page def get_next_page(self, response): if response.get('IsTruncated') == 'true': return response['Marker'] def print_result(self, result): print 'groups' for group in result.get('Groups', []): print ' ', group['Arn'] euca2ools-3.3.1/euca2ools/commands/iam/listgroupsforuser.py000066400000000000000000000041561267461563000240700ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from requestbuilder.response import PaginatedResponse from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_user class ListGroupsForUser(IAMRequest): DESCRIPTION = 'List all groups a user is a member of' ARGS = [arg_user(help='user to list membership for (required)'), AS_ACCOUNT] LIST_TAGS = ['Groups'] def main(self): return PaginatedResponse(self, (None,), ('Groups',)) def prepare_for_page(self, page): # Pages are defined by markers self.params['Marker'] = page def get_next_page(self, response): if response.get('IsTruncated') == 'true': return response['Marker'] def print_result(self, result): for group in result.get('Groups', []): print group['Arn'] euca2ools-3.3.1/euca2ools/commands/iam/listinstanceprofiles.py000066400000000000000000000043701267461563000245110ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from requestbuilder.response import PaginatedResponse from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT class ListInstanceProfiles(IAMRequest): DESCRIPTION = "List your account's instance profiles" ARGS = [Arg('-p', '--path-prefix', dest='PathPrefix', metavar='PREFIX', help='''limit results to instance profiles that begin with a given path'''), AS_ACCOUNT] LIST_TAGS = ['InstanceProfiles'] def main(self): return PaginatedResponse(self, (None,), ('InstanceProfiles',)) def prepare_for_page(self, page): # Pages are defined by markers self.params['Marker'] = page def get_next_page(self, response): if response.get('IsTruncated') == 'true': return response['Marker'] def print_result(self, result): for profile in result.get('InstanceProfiles', []): print profile['Arn'] euca2ools-3.3.1/euca2ools/commands/iam/listinstanceprofilesforrole.py000066400000000000000000000042371267461563000261040ustar00rootroot00000000000000# Copyright 2014-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from requestbuilder.response import PaginatedResponse from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_role class ListInstanceProfilesForRole(IAMRequest): DESCRIPTION = 'List all instance profiles that use a role' ARGS = [arg_role(help='role to list membership for (required)'), AS_ACCOUNT] LIST_TAGS = ['InstanceProfiles'] def main(self): return PaginatedResponse(self, (None,), ('InstanceProfiles',)) def prepare_for_page(self, page): # Pages are defined by markers self.params['Marker'] = page def get_next_page(self, response): if response.get('IsTruncated') == 'true': return response['Marker'] def print_result(self, result): for profile in result.get('InstanceProfiles', []): print profile['Arn'] euca2ools-3.3.1/euca2ools/commands/iam/listmfadevices.py000066400000000000000000000042501267461563000232440ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from requestbuilder.response import PaginatedResponse from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_user class ListMFADevices(IAMRequest): DESCRIPTION = "List a user's MFA devices" ARGS = [arg_user(nargs='?', help='''user to list MFA devices for (default: current user)'''), AS_ACCOUNT] LIST_TAGS = ['MFADevices'] def main(self): return PaginatedResponse(self, (None,), ('MFADevices',)) def prepare_for_page(self, page): # Pages are defined by markers self.params['Marker'] = page def get_next_page(self, response): if response.get('IsTruncated') == 'true': return response['Marker'] def print_result(self, result): for device in result.get('MFADevices', []): print device['SerialNumber'] euca2ools-3.3.1/euca2ools/commands/iam/listrolepolicies.py000066400000000000000000000072101267461563000236260ustar00rootroot00000000000000# Copyright 2014-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from requestbuilder.response import PaginatedResponse from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_role from euca2ools.commands.iam.getrolepolicy import GetRolePolicy class ListRolePolicies(IAMRequest): DESCRIPTION = 'List one or all policies attached to a role' ARGS = [arg_role(help='role owning the policies to list (required)'), Arg('-p', '--policy-name', metavar='POLICY', route_to=None, help='display a specific policy'), Arg('-v', '--verbose', action='store_true', route_to=None, help='''display the contents of the resulting policies (in addition to their names)'''), Arg('--pretty-print', action='store_true', route_to=None, help='''when printing the contents of policies, reformat them for easier reading'''), AS_ACCOUNT] LIST_TAGS = ['PolicyNames'] def main(self): return PaginatedResponse(self, (None,), ('PolicyNames',)) def prepare_for_page(self, page): # Pages are defined by markers self.params['Marker'] = page def get_next_page(self, response): if response.get('IsTruncated') == 'true': return response['Marker'] def print_result(self, result): if self.args.get('policy_name'): # Look for the specific policy the user asked for for policy_name in result.get('PolicyNames', []): if policy_name == self.args['policy_name']: if self.args['verbose']: self.print_policy(policy_name) else: print policy_name break else: for policy_name in result.get('PolicyNames', []): print policy_name if self.args['verbose']: self.print_policy(policy_name) # We already take care of pagination print 'IsTruncated: false' def print_policy(self, policy_name): req = GetRolePolicy.from_other( self, RoleName=self.args['RoleName'], PolicyName=policy_name, pretty_print=self.args['pretty_print'], DelegateAccount=self.params.get('DelegateAccount')) response = req.main() req.print_result(response) euca2ools-3.3.1/euca2ools/commands/iam/listroles.py000066400000000000000000000042311267461563000222610ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from requestbuilder.response import PaginatedResponse from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT class ListRoles(IAMRequest): DESCRIPTION = "List your account's roles" ARGS = [Arg('-p', '--path-prefix', dest='PathPrefix', metavar='PREFIX', help='limit results to roles who begin with a given path'), AS_ACCOUNT] LIST_TAGS = ['Roles'] def main(self): return PaginatedResponse(self, (None,), ('Roles',)) def prepare_for_page(self, page): # Pages are defined by markers self.params['Marker'] = page def get_next_page(self, response): if response.get('IsTruncated') == 'true': return response['Marker'] def print_result(self, result): for role in result.get('Roles', []): print role['Arn'] euca2ools-3.3.1/euca2ools/commands/iam/listservercertificates.py000066400000000000000000000045151267461563000250360ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from requestbuilder.response import PaginatedResponse from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT class ListServerCertificates(IAMRequest): DESCRIPTION = "List your account's server certificates" ARGS = [Arg('-p', '--path-prefix', dest='PathPrefix', metavar='PREFIX', help='''limit results to server certificates that begin with a given path'''), AS_ACCOUNT] LIST_TAGS = ['ServerCertificateMetadataList'] def main(self): return PaginatedResponse(self, (None,), ('ServerCertificateMetadataList',)) def prepare_for_page(self, page): # Pages are defined by markers self.params['Marker'] = page def get_next_page(self, response): if response.get('IsTruncated') == 'true': return response['Marker'] def print_result(self, result): for cert in result.get('ServerCertificateMetadataList', []): print cert['Arn'] euca2ools-3.3.1/euca2ools/commands/iam/listsigningcertificates.py000066400000000000000000000047421267461563000251700ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from requestbuilder.response import PaginatedResponse from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_user class ListSigningCertificates(IAMRequest): DESCRIPTION = "List a user's signing certificates" ARGS = [arg_user(nargs='?', help='''user to list certificates for (default: current user)'''), Arg('-v', '--verbose', action='store_true', route_to=None, help="also show certificates' contents"), AS_ACCOUNT] LIST_TAGS = ['Certificates'] def main(self): return PaginatedResponse(self, (None,), ('Certificates',)) def prepare_for_page(self, page): # Pages are defined by markers self.params['Marker'] = page def get_next_page(self, response): if response.get('IsTruncatated') == 'true': return response['Marker'] def print_result(self, result): for cert in result.get('Certificates', []): print cert['CertificateId'] if self.args['verbose']: print cert['CertificateBody'] print cert['Status'] print cert.get('UserName') or '' euca2ools-3.3.1/euca2ools/commands/iam/listuserpolicies.py000066400000000000000000000072101267461563000236430ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from requestbuilder.response import PaginatedResponse from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_user from euca2ools.commands.iam.getuserpolicy import GetUserPolicy class ListUserPolicies(IAMRequest): DESCRIPTION = 'List one or all policies attached to a user' ARGS = [arg_user(help='user owning the policies to list (required)'), Arg('-p', '--policy-name', metavar='POLICY', route_to=None, help='display a specific policy'), Arg('-v', '--verbose', action='store_true', route_to=None, help='''display the contents of the resulting policies (in addition to their names)'''), Arg('--pretty-print', action='store_true', route_to=None, help='''when printing the contents of policies, reformat them for easier reading'''), AS_ACCOUNT] LIST_TAGS = ['PolicyNames'] def main(self): return PaginatedResponse(self, (None,), ('PolicyNames',)) def prepare_for_page(self, page): # Pages are defined by markers self.params['Marker'] = page def get_next_page(self, response): if response.get('IsTruncated') == 'true': return response['Marker'] def print_result(self, result): if self.args.get('policy_name'): # Look for the specific policy the user asked for for policy_name in result.get('PolicyNames', []): if policy_name == self.args['policy_name']: if self.args['verbose']: self.print_policy(policy_name) else: print policy_name break else: for policy_name in result.get('PolicyNames', []): print policy_name if self.args['verbose']: self.print_policy(policy_name) # We already take care of pagination print 'IsTruncated: false' def print_policy(self, policy_name): req = GetUserPolicy.from_other( self, UserName=self.args['UserName'], PolicyName=policy_name, pretty_print=self.args['pretty_print'], DelegateAccount=self.params.get('DelegateAccount')) response = req.main() req.print_result(response) euca2ools-3.3.1/euca2ools/commands/iam/listusers.py000066400000000000000000000042361267461563000223030ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from requestbuilder.response import PaginatedResponse from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT class ListUsers(IAMRequest): DESCRIPTION = "List your account's users" ARGS = [Arg('-p', '--path-prefix', dest='PathPrefix', metavar='PREFIX', help='limit results to users who begin with a given path'), AS_ACCOUNT] LIST_TAGS = ['Users'] def main(self): return PaginatedResponse(self, (None,), ('Users',)) def prepare_for_page(self, page): # Pages are defined by markers self.params['Marker'] = page def get_next_page(self, response): if response.get('IsTruncated') == 'true': return response['Marker'] def print_result(self, result): for user in result.get('Users', []): print user['Arn'] euca2ools-3.3.1/euca2ools/commands/iam/putaccountpolicy.py000066400000000000000000000043201267461563000236450ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, MutuallyExclusiveArgList from euca2ools.commands.iam import IAMRequest, arg_account_name class PutAccountPolicy(IAMRequest): DESCRIPTION = '[Eucalyptus cloud admin only] Attach a policy to an account' ARGS = [arg_account_name(help='''name or ID of the account to attach the policy to (required)'''), Arg('-p', '--policy-name', dest='PolicyName', metavar='POLICY', required=True, help='name of the policy (required)'), MutuallyExclusiveArgList( Arg('-o', '--policy-content', dest='PolicyDocument', metavar='POLICY_CONTENT', help='the policy to attach'), Arg('-f', '--policy-document', dest='PolicyDocument', metavar='FILE', type=open, help='file containing the policy to attach')) .required()] euca2ools-3.3.1/euca2ools/commands/iam/putgrouppolicy.py000066400000000000000000000042161267461563000233510ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, MutuallyExclusiveArgList from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_group class PutGroupPolicy(IAMRequest): DESCRIPTION = 'Attach a policy to a group' ARGS = [arg_group(help='group to attach the policy to (required)'), Arg('-p', '--policy-name', dest='PolicyName', metavar='POLICY', required=True, help='name of the policy (required)'), MutuallyExclusiveArgList( Arg('-o', '--policy-content', dest='PolicyDocument', metavar='POLICY_CONTENT', help='the policy to attach'), Arg('-f', '--policy-document', dest='PolicyDocument', metavar='FILE', type=open, help='file containing the policy to attach')) .required(), AS_ACCOUNT] euca2ools-3.3.1/euca2ools/commands/iam/putrolepolicy.py000066400000000000000000000042111267461563000231510ustar00rootroot00000000000000# Copyright 2014-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, MutuallyExclusiveArgList from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_role class PutRolePolicy(IAMRequest): DESCRIPTION = 'Attach a policy to a role' ARGS = [arg_role(help='role to attach the policy to (required)'), Arg('-p', '--policy-name', dest='PolicyName', metavar='POLICY', required=True, help='name of the policy (required)'), MutuallyExclusiveArgList( Arg('-o', '--policy-content', dest='PolicyDocument', metavar='POLICY_CONTENT', help='the policy to attach'), Arg('-f', '--policy-document', dest='PolicyDocument', metavar='FILE', type=open, help='file containing the policy to attach')) .required(), AS_ACCOUNT] euca2ools-3.3.1/euca2ools/commands/iam/putuserpolicy.py000066400000000000000000000042111267461563000231660ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, MutuallyExclusiveArgList from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_user class PutUserPolicy(IAMRequest): DESCRIPTION = 'Attach a policy to a user' ARGS = [arg_user(help='user to attach the policy to (required)'), Arg('-p', '--policy-name', dest='PolicyName', metavar='POLICY', required=True, help='name of the policy (required)'), MutuallyExclusiveArgList( Arg('-o', '--policy-content', dest='PolicyDocument', metavar='POLICY_CONTENT', help='the policy to attach'), Arg('-f', '--policy-document', dest='PolicyDocument', metavar='FILE', type=open, help='file containing the policy to attach')) .required(), AS_ACCOUNT] euca2ools-3.3.1/euca2ools/commands/iam/removerolefrominstanceprofile.py000066400000000000000000000034441267461563000264170ustar00rootroot00000000000000# Copyright 2014-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_iprofile class RemoveRoleFromInstanceProfile(IAMRequest): DESCRIPTION = 'Remove a role from an instance profile' ARGS = [Arg('-r', '--role-name', dest='RoleName', metavar='ROLE', required=True, help='the role to remove (required)'), arg_iprofile( help='instance profile to remove the role from (required)'), AS_ACCOUNT] euca2ools-3.3.1/euca2ools/commands/iam/removeuserfromgroup.py000066400000000000000000000040651267461563000244030ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_group class RemoveUserFromGroup(IAMRequest): DESCRIPTION = 'Remove a user from a group' ARGS = [Arg('-u', '--user-name', dest='user_names', metavar='USER', action='append', route_to=None, required=True, help='user to remove from the group (required)'), arg_group(help='group to remove the user from (required)'), AS_ACCOUNT] def main(self): for user in self.args['user_names']: self.params['UserName'] = user self.send() # The response doesn't actually contain anything of interest, so don't # bother returning anything return None euca2ools-3.3.1/euca2ools/commands/iam/resyncmfadevice.py000066400000000000000000000043651267461563000234200ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_user class ResyncMFADevice(IAMRequest): DESCRIPTION = 'Re-synchronize an MFA device with the server' ARGS = [arg_user(help='''user owning the MFA device to re-synchronize (required)'''), Arg('-s', '--serial-number', dest='SerialNumber', metavar='SERIAL', required=True, help='serial number of the MFA device (required)'), Arg('-c1', dest='AuthenticationCode1', metavar='CODE', required=True, help='''an authentication code emitted by the MFA device (required)'''), Arg('-c2', dest='AuthenticationCode2', metavar='CODE', required=True, help='''a subsequent authentication code emitted by the MFA device (required)'''), AS_ACCOUNT] euca2ools-3.3.1/euca2ools/commands/iam/updateaccesskey.py000066400000000000000000000040251267461563000234170ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_key_id class UpdateAccessKey(IAMRequest): DESCRIPTION = ('Change the status of an access key from Active to ' 'Inactive, or vice versa') ARGS = [arg_key_id(help='ID of the access key to update (required)'), Arg('-s', '--status', dest='Status', required=True, choices=('Active', 'Inactive'), help='status to assign to the access key (required)'), Arg('-u', '--user-name', dest='UserName', metavar='USER', help='''user owning the access key to update (default: current user)'''), AS_ACCOUNT] euca2ools-3.3.1/euca2ools/commands/iam/updateassumerolepolicy.py000066400000000000000000000053661267461563000250550ustar00rootroot00000000000000# Copyright 2014-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import json from requestbuilder import Arg, MutuallyExclusiveArgList from euca2ools.commands.argtypes import file_contents from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_role class UpdateAssumeRolePolicy(IAMRequest): DESCRIPTION = ("Update a role's trust policy, the policy that allows " "entities to assume a role") ARGS = [arg_role(help='role to update (required)'), MutuallyExclusiveArgList( Arg('-f', dest='PolicyDocument', metavar='FILE', type=file_contents, help='file containing the policy for the new role'), Arg('-s', '--service', route_to=None, help='''service to allow access to the role (e.g. ec2.amazonaws.com)''')) .required(), Arg('-o', dest='verbose', action='store_true', help="also print the role's new policy"), AS_ACCOUNT] def preprocess(self): if self.args.get('service'): statement = {'Effect': 'Allow', 'Principal': {'Service': [self.args['service']]}, 'Action': ['sts:AssumeRole']} policy = {'Version': '2008-10-17', 'Statement': [statement]} self.params['PolicyDocument'] = json.dumps(policy) def print_result(self, _): if self.args.get('verbose'): print self.params['PolicyDocument'] euca2ools-3.3.1/euca2ools/commands/iam/updategroup.py000066400000000000000000000035261267461563000226060ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_group class UpdateGroup(IAMRequest): DESCRIPTION = 'Change the name and/or path of a group' ARGS = [arg_group(help='name of the group to update (required)'), Arg('-n', '--new-group-name', dest='NewGroupName', metavar='GROUP', help='new name for the group'), Arg('-p', '--new-path', dest='NewPath', metavar='PATH', help='new path for the group'), AS_ACCOUNT] euca2ools-3.3.1/euca2ools/commands/iam/updateloginprofile.py000066400000000000000000000041041267461563000241340ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_user from euca2ools.util import prompt_for_password class UpdateLoginProfile(IAMRequest): DESCRIPTION = "Update a user's password" ARGS = [arg_user( help='name of the user to change a password for (required)'), Arg('-p', '--password', dest='Password', help='''the new password. If unspecified, the new password will be read from the console.'''), AS_ACCOUNT] def configure(self): IAMRequest.configure(self) if self.args['Password'] is None: self.log.info('no password supplied; prompting') self.params['Password'] = prompt_for_password() euca2ools-3.3.1/euca2ools/commands/iam/updateservercertificate.py000066400000000000000000000036771267461563000251720ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_server_cert class UpdateServerCertificate(IAMRequest): DESCRIPTION = 'Change the name and/or path of a server certificate' ARGS = [arg_server_cert(help='name of the server certificate to update'), Arg('-n', '--new-server-certificate-name', dest='NewServerCertificateName', metavar='CERT', help='new name for the server certificate'), Arg('-p', '--new-path', dest='NewPath', metavar='PATH', help='new path for the server certificate'), AS_ACCOUNT] euca2ools-3.3.1/euca2ools/commands/iam/updatesigningcertificate.py000066400000000000000000000041131267461563000253040ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_signing_cert class UpdateSigningCertificate(IAMRequest): DESCRIPTION = ('Change the status of a signing certificate from Active to ' 'Inactive, or vice versa') ARGS = [arg_signing_cert( help='ID of the signing certificate to update (required)'), Arg('-u', '--user-name', dest='UserName', metavar='USER', help='''user owning the signing certificate to update (default: current user)'''), Arg('-s', '--status', dest='Status', required=True, choices=('Active', 'Inactive'), help='status to assign to the certificate'), AS_ACCOUNT] euca2ools-3.3.1/euca2ools/commands/iam/updateuser.py000066400000000000000000000047321267461563000224300ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_user class UpdateUser(IAMRequest): DESCRIPTION = 'Change the name and/or path of a user' ARGS = [arg_user(help='name of the user to update'), Arg('-n', '--new-user-name', dest='NewUserName', metavar='USER', help='new name for the user'), Arg('-p', '--new-path', dest='NewPath', metavar='PATH', help='new path for the user'), Arg('--enabled', dest='Enabled', choices=('true', 'false'), help='''[Eucalyptus only] 'true' to enable the user, or 'false' to disable the user'''), Arg('--pwd-expires', dest='PasswordExpiration', metavar='YYYY-MM-DDThh:mm:ssZ', help='''[Eucalyptus only] New password expiration date, in ISO8601 format'''), Arg('--reg-status', dest='RegStatus', choices=('REGISTERED', 'APPROVED', 'CONFIRMED'), help='''[Eucalyptus < 4.2 only] new registration status. Only CONFIRMED users may access the system.'''), AS_ACCOUNT] euca2ools-3.3.1/euca2ools/commands/iam/updateuserinfo.py000066400000000000000000000036561267461563000233100ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_user class UpdateUserInfo(IAMRequest): DESCRIPTION = "[Eucalyptus only] Update a user's information" ARGS = [arg_user(nargs='?', help='user to update (default: current user)'), Arg('-k', '--info-key', dest='InfoKey', metavar='KEY', required=True, help='name of the info field to set (required)'), Arg('-i', '--info-value', dest='InfoValue', metavar='VALUE', help='value to set the info field to (omit to delete it)'), AS_ACCOUNT] euca2ools-3.3.1/euca2ools/commands/iam/uploadservercertificate.py000066400000000000000000000062351267461563000251650ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, MutuallyExclusiveArgList from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_server_cert class UploadServerCertificate(IAMRequest): DESCRIPTION = 'Upload a server certificate' ARGS = [arg_server_cert( help='name to give the new server certificate (required)'), MutuallyExclusiveArgList( Arg('-c', '--certificate-body', dest='CertificateBody', metavar='CERT_CONTENT', help='PEM-encoded certificate'), Arg('--certificate-file', dest='CertificateBody', metavar='FILE', type=open, help='file containing the PEM-encoded certificate')) .required(), MutuallyExclusiveArgList( Arg('--private-key', dest='PrivateKey', metavar='KEY', help='PEM-encoded private key'), Arg('--private-key-file', dest='PrivateKey', metavar='FILE', type=open, help='file containing the PEM-encoded private key')) .required(), MutuallyExclusiveArgList( Arg('--certificate-chain', dest='CertificateChain', metavar='CHAIN', help='''PEM-encoded certificate chain. This is typically the PEM-encoded certificates of the chain, concatenated together.'''), Arg('--certificate-chain-file', dest='CertificateChain', metavar='FILE', type=open, help='''file containing the PEM-encoded certificate chain. This is typically the PEM-encoded certificates of the chain, concatenated together.''')), Arg('-p', '--path', dest='Path', help='path for the new server certificate (default: "/")'), AS_ACCOUNT] euca2ools-3.3.1/euca2ools/commands/iam/uploadsigningcertificate.py000066400000000000000000000043051267461563000253110ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg, MutuallyExclusiveArgList from euca2ools.commands.iam import IAMRequest, AS_ACCOUNT, arg_user class UploadSigningCertificate(IAMRequest): DESCRIPTION = 'Upload a signing certificate' ARGS = [arg_user(help='''user the signing certificate is for (default: current user)'''), MutuallyExclusiveArgList( Arg('-c', '--certificate-body', dest='CertificateBody', metavar='CERT_CONTENT', help='PEM-encoded contents of the new certificate'), Arg('-f', '--certificate-file', dest='CertificateBody', metavar='FILE', type=open, help='file containing the new certificate')) .required(), AS_ACCOUNT] def print_result(self, result): print result.get('Certificate', {}).get('CertificateId') euca2ools-3.3.1/euca2ools/commands/misc/000077500000000000000000000000001267461563000200545ustar00rootroot00000000000000euca2ools-3.3.1/euca2ools/commands/misc/__init__.py000066400000000000000000000024751267461563000221750ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. euca2ools-3.3.1/euca2ools/commands/misc/generateenvironment.py000066400000000000000000000106731267461563000245140ustar00rootroot00000000000000# Copyright 2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os from requestbuilder import Arg from requestbuilder.auth.aws import HmacKeyAuth from requestbuilder.command import BaseCommand import requestbuilder.exceptions from requestbuilder.mixins import RegionConfigurableMixin from euca2ools.commands import Euca2ools import euca2ools.util class GenerateEnvironment(BaseCommand, RegionConfigurableMixin): DESCRIPTION = ('Read environment variables and euca2ools.ini(5) ' 'files to discover the service URLs and credentials ' 'for a region, then output shellcode with the ' 'corresponding environment variables for that ' 'information. This output will contain secret ' 'access keys and should be treated with care.') SUITE = Euca2ools ARGS = [Arg('--simple', action='store_true', help='''use a simpler output format intended for consumption by scripts'''), HmacKeyAuth.ARGS] def configure(self): BaseCommand.configure(self) self.update_config_view() def main(self): env_vars = {} services = euca2ools.util.generate_service_names() for service, service_var in services.items(): url = os.getenv(service_var) if not url: url = self.config.get_region_option('{0}-url'.format(service)) env_vars[service_var] = url auth = HmacKeyAuth(config=self.config, loglevel=self.log.level, **self.args) try: auth.configure() except requestbuilder.exceptions.AuthError: self.log.info('auth configuration failed; info may be missing', exc_info=True) env_vars['AWS_ACCESS_KEY_ID'] = auth.args.get('key_id') env_vars['AWS_SECRET_ACCESS_KEY'] = auth.args.get('secret_key') env_vars['AWS_SECURITY_TOKEN'] = auth.args.get('security_token') env_vars['AWS_CREDENTIAL_EXPIRATION'] = auth.args.get( 'credential_expiration') env_vars['EC2_USER_ID'] = os.getenv( 'EC2_USER_ID', self.config.get_user_option('account-id')) env_vars['EC2_CERT'] = os.getenv( 'EC2_CERT', self.config.get_user_option('certificate')) env_vars['EC2_PRIVATE_KEY'] = os.getenv( 'EC2_PRIVATE_KEY', self.config.get_user_option('private-key')) env_vars['EUCALYPTUS_CERT'] = os.getenv( 'EUCALYPTUS_CERT', self.config.get_region_option('certificate')) return env_vars def print_result(self, env_vars): if self.args.get('simple'): for key, val in sorted(env_vars.items()): print '{key}={val}'.format(key=key, val=(val or '')) else: # We do this in two steps so we can put all the comments last, # allowing the output to work inside a shell's eval statement. for key, val in sorted(env_vars.items()): if val: print '{key}={val}; export {key};'.format(key=key, val=val) for key, val in sorted(env_vars.items()): if not val: print '# {key} is not set'.format(key=key) euca2ools-3.3.1/euca2ools/commands/misc/generatekeyfingerprint.py000066400000000000000000000046511267461563000252070ustar00rootroot00000000000000# Copyright (c) 2014-2016 Hewlett Packard Enterprise Development LP # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import hashlib import subprocess from requestbuilder import Arg from requestbuilder.command import BaseCommand from euca2ools.commands import Euca2ools class GenerateKeyFingerprint(BaseCommand): DESCRIPTION = ('Show the fingerprint of a private key as it would appear ' 'in the output of euca-describe-keypairs.\n\nNote that ' "this will differ from the key's SSH key fingerprint.") SUITE = Euca2ools ARGS = [Arg('privkey_filename', metavar='FILE', help='file containing the private key (required)')] def main(self): pkcs8 = subprocess.Popen( ('openssl', 'pkcs8', '-in', self.args['privkey_filename'], '-nocrypt', '-topk8', '-outform', 'DER'), stdout=subprocess.PIPE) privkey = pkcs8.communicate()[0] if pkcs8.returncode: raise subprocess.CalledProcessError(pkcs8.returncode, 'openssl') fprint = hashlib.sha1(privkey).hexdigest() return ':'.join(fprint[i:i+2] for i in range(0, len(fprint), 2)) def print_result(self, fprint): print fprint euca2ools-3.3.1/euca2ools/commands/misc/releaserole.py000066400000000000000000000066421267461563000227400ustar00rootroot00000000000000# Copyright 2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os import pipes import sys from requestbuilder import Arg, MutuallyExclusiveArgList from requestbuilder.command import BaseCommand from euca2ools.commands import Euca2ools class ReleaseRole(BaseCommand): DESCRIPTION = '''\ Release IAM role credentials The %(prog)s utility removes the credentials created by euare-assumerole(1) by outputting shellcode that deletes the environment variables it creates. Use it inside an eval command to make this process seamless: $ eval `euare-releaserole` Note that if the credentials used to initially assume the role were supplied in the form of environment variables those environment variables will need to be reset: $ source eucarc''' SUITE = Euca2ools ARGS = [MutuallyExclusiveArgList( Arg('-c', dest='csh_output', route_to=None, action='store_true', help='''generate C-shell commands on stdout (default if SHELL looks like a csh-style shell'''), Arg('-s', dest='sh_output', route_to=None, action='store_true', help='''generate Bourne shell commands on stdout (default if SHELL does not look like a csh-style shell'''))] def print_result(self, _): for var in ( 'AWS_ACCESS_KEY_ID', 'AWS_ACCESS_KEY', 'EC2_ACCESS_KEY', 'AWS_SECRET_ACCESS_KEY', 'AWS_SECRET_KEY', 'EC2_SECRET_KEY', 'AWS_SESSION_TOKEN', 'AWS_SECURITY_TOKEN', 'AWS_CREDENTIAL_EXPIRATION', 'EC2_USER_ID', 'AWS_CREDENTIAL_FILE'): if (self.args.get('csh_output') or (not self.args.get('sh_output') and os.getenv('SHELL', '').endswith('csh'))): fmt = 'unsetenv {0};' else: fmt = 'unset {0};' print fmt.format(var) print print '# If you can read this, rerun this program with eval:' print '# eval `{0}`'.format( ' '.join(pipes.quote(arg) for arg in sys.argv)) euca2ools-3.3.1/euca2ools/commands/monitoring/000077500000000000000000000000001267461563000213065ustar00rootroot00000000000000euca2ools-3.3.1/euca2ools/commands/monitoring/__init__.py000066400000000000000000000101431267461563000234160ustar00rootroot00000000000000# Copyright 2013-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os import sys from requestbuilder import Arg import requestbuilder.auth.aws from requestbuilder.mixins import TabifyingMixin from requestbuilder.request import AWSQueryRequest import requestbuilder.service from euca2ools.commands import Euca2ools from euca2ools.exceptions import AWSError from euca2ools.util import strip_response_metadata, add_fake_region_name class CloudWatch(requestbuilder.service.BaseService): NAME = 'monitoring' DESCRIPTION = 'Instance monitoring service' API_VERSION = '2010-08-01' REGION_ENVVAR = 'AWS_DEFAULT_REGION' URL_ENVVAR = 'AWS_CLOUDWATCH_URL' ARGS = [Arg('-U', '--url', metavar='URL', help='instance monitoring service endpoint URL')] def configure(self): requestbuilder.service.BaseService.configure(self) add_fake_region_name(self) def handle_http_error(self, response): raise AWSError(response) class CloudWatchRequest(AWSQueryRequest, TabifyingMixin): SUITE = Euca2ools SERVICE_CLASS = CloudWatch AUTH_CLASS = requestbuilder.auth.aws.HmacV4Auth METHOD = 'POST' def parse_response(self, response): response_dict = AWSQueryRequest.parse_response(self, response) return strip_response_metadata(response_dict) def print_alarm(self, alarm): bits = [alarm.get('AlarmName')] if self.args['show_long']: bits.append(alarm.get('AlarmDescription')) bits.append(alarm.get('StateValue')) if self.args['show_long']: bits.append(alarm.get('StateReason')) bits.append(alarm.get('StateReasonData')) bits.append(alarm.get('ActionsEnabled')) bits.append(','.join(alarm.get('OKActions', []))) bits.append(','.join(alarm.get('AlarmActions', []))) if self.args['show_long']: bits.append(','.join(alarm.get('InsufficientDataActions', []))) bits.append(alarm.get('Namespace')) bits.append(alarm.get('MetricName')) if self.args['show_long']: dimensions = [] for dimension in alarm.get('Dimensions', []): dimensions.append('{0}={1}'.format(dimension.get('Name'), dimension.get('Value'))) if len(dimensions) > 0: bits.append('{{{0}}}'.format(','.join(dimensions))) else: bits.append(None) bits.append(alarm.get('Period')) bits.append(alarm.get('Statistic')) if self.args['show_long']: bits.append(alarm.get('Unit')) bits.append(alarm.get('EvaluationPeriods')) bits.append(alarm.get('ComparisonOperator')) bits.append(alarm.get('Threshold')) if self.args['show_long']: bits.append(alarm.get('AlarmArn')) print self.tabify(bits) euca2ools-3.3.1/euca2ools/commands/monitoring/argtypes.py000066400000000000000000000032121267461563000235140ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse def cloudwatch_dimension(dim_as_str): try: name, val = dim_as_str.split('=', 1) return {'Name': name, 'Value': val} except ValueError: raise argparse.ArgumentTypeError('dimension filter "{0}" must have ' 'form KEY=VALUE'.format(dim_as_str)) euca2ools-3.3.1/euca2ools/commands/monitoring/deletealarms.py000066400000000000000000000033571267461563000243320ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from euca2ools.commands.monitoring import CloudWatchRequest from requestbuilder import Arg class DeleteAlarms(CloudWatchRequest): DESCRIPTION = 'Delete alarms' ARGS = [Arg('AlarmNames.member', metavar='ALARM', nargs='+', help='names of the alarms to delete'), Arg('-f', '--force', action='store_true', route_to=None, help=argparse.SUPPRESS)] # for compatibility euca2ools-3.3.1/euca2ools/commands/monitoring/describealarmhistory.py000066400000000000000000000060101267461563000260740ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.monitoring import CloudWatchRequest from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin from requestbuilder.response import PaginatedResponse class DescribeAlarmHistory(CloudWatchRequest, TabifyingMixin): DESCRIPTION = 'Retrieve history for one alarm or all alarms' ARGS = [Arg('AlarmName', metavar='ALARM', nargs='?', help='limit results to a specific alarm'), Arg('--end-date', dest='EndDate', metavar='DATE', help='limit results to history before a given point in time'), Arg('--history-item-type', dest='HistoryItemType', choices=('Action', 'ConfigurationUpdate', 'StateUpdate'), help='limit results to specific history item types'), Arg('--show-long', action='store_true', route_to=None, help='show detailed event data as machine-readable JSON'), Arg('--start-date', dest='StartDate', metavar='DATE', help='limit results to history after a given point in time')] LIST_TAGS = ['AlarmHistoryItems'] def main(self): return PaginatedResponse(self, (None,), ('AlarmHistoryItems',)) def prepare_for_page(self, page): self.params['NextToken'] = page def get_next_page(self, response): return response.get('NextToken') or None def print_result(self, result): for item in result.get('AlarmHistoryItems', []): bits = [item.get('AlarmName'), item.get('Timestamp'), item.get('HistoryItemType'), item.get('HistorySummary')] if self.args['show_long']: bits.append(item.get('HistoryData')) print self.tabify(bits) euca2ools-3.3.1/euca2ools/commands/monitoring/describealarms.py000066400000000000000000000055771267461563000246560ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.monitoring import CloudWatchRequest from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin from requestbuilder.response import PaginatedResponse class DescribeAlarms(CloudWatchRequest, TabifyingMixin): DESCRIPTION = 'Describe alarms' ARGS = [Arg('AlarmNames.member', metavar='ALARM', nargs='*', help='limit results to specific alarms'), Arg('--action-prefix', dest='ActionPrefix', metavar='PREFIX', help='''limit results to alarms whose actions' ARNs begin with a specific string'''), Arg('--alarm-name-prefix', dest='AlarmNamePrefix', metavar='PREFIX', help='''limit results to alarms whose names begin with a specific string'''), Arg('--show-long', action='store_true', route_to=None, help="show all of the alarms' info"), Arg('--state-value', dest='StateValue', choices=('OK', 'ALARM', 'INSUFFICIENT_DATA'), help='limit results to alarms in a specific state')] LIST_TAGS = ['MetricAlarms', 'AlarmActions', 'Dimensions', 'InsufficientDataActions', 'OKActions'] def main(self): return PaginatedResponse(self, (None,), ('MetricAlarms',)) def prepare_for_page(self, page): self.params['NextToken'] = page def get_next_page(self, response): return response.get('NextToken') or None def print_result(self, result): for alarm in result.get('MetricAlarms', []): self.print_alarm(alarm) euca2ools-3.3.1/euca2ools/commands/monitoring/describealarmsformetric.py000066400000000000000000000071551267461563000265630ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from euca2ools.commands.argtypes import delimited_list from euca2ools.commands.monitoring import CloudWatchRequest from euca2ools.commands.monitoring.argtypes import cloudwatch_dimension from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin from requestbuilder.response import PaginatedResponse class DescribeAlarmsForMetric(CloudWatchRequest, TabifyingMixin): DESCRIPTION = ('Describe alarms for a single metric.\n\nNote that all ' "of an alarm's metrics must match exactly to obtain any " 'results.') ARGS = [Arg('--metric-name', dest='MetricName', metavar='METRIC', required=True, help='name of the metric (required)'), Arg('--namespace', dest='Namespace', metavar='NAMESPACE', required=True, help='namespace of the metric (required)'), # --alarm-description is supported by the tool, but not the service Arg('--alarm-description', route_to=None, help=argparse.SUPPRESS), Arg('--dimensions', dest='Dimensions.member', metavar='KEY1=VALUE1,KEY2=VALUE2,...', type=delimited_list(',', item_type=cloudwatch_dimension), help='dimensions of the metric'), Arg('--period', dest='Period', metavar='SECONDS', help='period over which statistics are applied'), Arg('--show-long', action='store_true', route_to=None, help="show all of the alarms' info"), Arg('--statistic', dest='Statistic', choices=('Average', 'Maximum', 'Minimum', 'SampleCount', 'Sum'), help='statistic of the metric on which to trigger alarms'), Arg('--unit', dest='Unit', help='unit of measurement for statistics')] LIST_TAGS = ['MetricAlarms', 'AlarmActions', 'Dimensions', 'InsufficientDataActions', 'OKActions'] def main(self): return PaginatedResponse(self, (None,), ('MetricAlarms',)) def prepare_for_page(self, page): self.params['NextToken'] = page def get_next_page(self, response): return response.get('NextToken') or None def print_result(self, result): for alarm in result.get('MetricAlarms', []): self.print_alarm(alarm) euca2ools-3.3.1/euca2ools/commands/monitoring/disablealarmactions.py000066400000000000000000000032151267461563000256620ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.monitoring import CloudWatchRequest from requestbuilder import Arg class DisableAlarmActions(CloudWatchRequest): DESCRIPTION = 'Disable all actions for one or more alarms' ARGS = [Arg('AlarmNames.member', metavar='ALARM', nargs='+', help='names of the alarms to disable actions for')] euca2ools-3.3.1/euca2ools/commands/monitoring/enablealarmactions.py000066400000000000000000000032121267461563000255020ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.monitoring import CloudWatchRequest from requestbuilder import Arg class EnableAlarmActions(CloudWatchRequest): DESCRIPTION = 'Enable all actions for one or more alarms' ARGS = [Arg('AlarmNames.member', metavar='ALARM', nargs='+', help='names of the alarms to enable actions for')] euca2ools-3.3.1/euca2ools/commands/monitoring/getmetricstatistics.py000066400000000000000000000117371267461563000257670ustar00rootroot00000000000000# Copyright 2013-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import datetime from requestbuilder import Arg from requestbuilder.exceptions import ArgumentError from requestbuilder.mixins import TabifyingMixin from requestbuilder.response import PaginatedResponse from euca2ools.commands.argtypes import delimited_list from euca2ools.commands.monitoring import CloudWatchRequest from euca2ools.commands.monitoring.argtypes import cloudwatch_dimension class GetMetricStatistics(CloudWatchRequest, TabifyingMixin): DESCRIPTION = "Show a metric's statistics" ARGS = [Arg('MetricName', metavar='METRIC', help='name of the metric to get statistics for (required)'), Arg('-n', '--namespace', dest='Namespace', required=True, help="the metric's namespace (required)"), Arg('-s', '--statistics', dest='Statistics.member', required=True, metavar='STAT1,STAT2,...', type=delimited_list(','), help='the metric statistics to show (at least 1 required)'), Arg('--dimensions', dest='Dimensions.member', metavar='KEY1=VALUE1,KEY2=VALUE2,...', type=delimited_list(',', item_type=cloudwatch_dimension), help='the dimensions of the metric to show'), Arg('--start-time', dest='StartTime', metavar='YYYY-MM-DDThh:mm:ssZ', help='''earliest time to retrieve data points for (default: one hour ago)'''), Arg('--end-time', dest='EndTime', metavar='YYYY-MM-DDThh:mm:ssZ', help='''latest time to retrieve data points for (default: now)'''), Arg('--period', dest='Period', metavar='SECONDS', type=int, default=60, help='''granularity of the returned data points (must be a multiple of 60) (default: 60)'''), Arg('--unit', dest='Unit', help='unit the metric is reported in')] LIST_TAGS = ['Datapoints'] # noinspection PyExceptionInherit def configure(self): CloudWatchRequest.configure(self) if self.args.get('period'): if self.args['period'] <= 0: raise ArgumentError( 'argument --period: value must be positive') elif self.args['period'] % 60 != 0: raise ArgumentError( 'argument --period: value must be a multiple of 60') def main(self): now = datetime.datetime.utcnow() then = now - datetime.timedelta(hours=1) if not self.args.get('StartTime'): self.params['StartTime'] = then.strftime('%Y-%m-%dT%H:%M:%SZ') if not self.args.get('EndTime'): self.params['EndTime'] = now.strftime('%Y-%m-%dT%H:%M:%SZ') return PaginatedResponse(self, (None,), ('Datapoints',)) def prepare_for_page(self, page): self.params['NextToken'] = page def get_next_page(self, response): return response.get('NextToken') or None def print_result(self, result): points = [] for point in result.get('Datapoints', []): timestamp = point.get('Timestamp', '') try: parsed = datetime.datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%SZ') timestamp = parsed.strftime('%Y-%m-%d %H:%M:%S') except ValueError: # We'll just print it verbatim pass points.append((timestamp, point.get('SampleCount'), point.get('Average'), point.get('Sum'), point.get('Minimum'), point.get('Maximum'), point.get('Unit'))) for point in sorted(points): print self.tabify(point) euca2ools-3.3.1/euca2ools/commands/monitoring/listmetrics.py000066400000000000000000000065561267461563000242360ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.argtypes import delimited_list from euca2ools.commands.monitoring import CloudWatchRequest from euca2ools.commands.monitoring.argtypes import cloudwatch_dimension from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin from requestbuilder.response import PaginatedResponse class ListMetrics(CloudWatchRequest, TabifyingMixin): DESCRIPTION = 'Show a list of monitoring metrics' ARGS = [Arg('-d', '--dimensions', dest='Dimensions.member', metavar='KEY1=VALUE1,KEY2=VALUE2,...', type=delimited_list(',', item_type=cloudwatch_dimension), help='limit results to metrics with specific dimensions'), Arg('-m', '--metric-name', dest='MetricName', metavar='METRIC', help='limit results to a specific metric'), Arg('-n', '--namespace', dest='Namespace', metavar='NAMESPACE', help='limit results to metrics in a specific namespace')] LIST_TAGS = ['Metrics', 'Dimensions'] def main(self): return PaginatedResponse(self, (None,), ('Metrics',)) def prepare_for_page(self, page): self.params['NextToken'] = page def get_next_page(self, response): return response.get('NextToken') or None def print_result(self, result): out_lines = [] for metric in sorted(result.get('Metrics', [])): if len(metric.get('Dimensions', [])) > 0: formatted_dims = ['{0}={1}'.format(dimension.get('Name'), dimension.get('Value')) for dimension in metric['Dimensions']] out_lines.append((metric.get('MetricName'), metric.get('Namespace'), '{{{0}}}'.format(','.join(formatted_dims)))) else: out_lines.append((metric.get('MetricName'), metric.get('Namespace'), None)) for out_line in sorted(out_lines): print self.tabify(out_line) euca2ools-3.3.1/euca2ools/commands/monitoring/putmetricalarm.py000066400000000000000000000114241267461563000247130ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.argtypes import delimited_list from euca2ools.commands.monitoring import CloudWatchRequest from euca2ools.commands.monitoring.argtypes import cloudwatch_dimension from requestbuilder import Arg class PutMetricAlarm(CloudWatchRequest): DESCRIPTION = 'Create or update an alarm' ARGS = [Arg('AlarmName', metavar='ALARM', help='name of the alarm (required)'), Arg('--comparison-operator', dest='ComparisonOperator', choices=('GreaterThanOrEqualToThreshold', 'GreaterThanThreshold', 'LessThanThreshold', 'LessThanOrEqualToThreshold'), required=True, help='''arithmetic operator with which the comparison with the threshold will be made (required)'''), Arg('--evaluation-periods', dest='EvaluationPeriods', type=int, metavar='COUNT', required=True, help='''number of consecutive periods for which the value of the metric needs to be compared to the threshold (required)'''), Arg('--metric-name', dest='MetricName', metavar='METRIC', required=True, help="name for the alarm's associated metric (required)"), Arg('--namespace', dest='Namespace', metavar='NAMESPACE', required=True, help="namespace for the alarm's associated metric (required)"), Arg('--period', dest='Period', metavar='SECONDS', type=int, required=True, help='''period over which the specified statistic is applied (required)'''), Arg('--statistic', dest='Statistic', required=True, choices=('Average', 'Maximum', 'Minimum', 'SampleCount', 'Sum'), help='statistic on which to alarm (required)'), Arg('--threshold', dest='Threshold', metavar='FLOAT', type=float, required=True, help='value to compare the statistic against (required)'), Arg('--actions-enabled', dest='ActionsEnabled', choices=('true', 'false'), help='''whether this alarm's actions should be executed when it changes state'''), Arg('--alarm-actions', dest='AlarmActions.member', metavar='ARN1,ARN2,...', type=delimited_list(','), help='''ARNs of SNS topics to publish to when the alarm changes to the ALARM state'''), Arg('--alarm-description', dest='AlarmDescription', metavar='DESCRIPTION', help='description of the alarm'), Arg('-d', '--dimensions', dest='Dimensions.member', metavar='KEY1=VALUE1,KEY2=VALUE2,...', type=delimited_list(',', item_type=cloudwatch_dimension), help="dimensions for the alarm's associated metric"), Arg('--insufficient-data-actions', metavar='ARN1,ARN2,...', dest='InsufficientDataActions.member', type=delimited_list(','), help='''ARNs of SNS topics to publish to when the alarm changes to the INSUFFICIENT_DATA state'''), Arg('--ok-actions', dest='OKActions.member', metavar='ARN1,ARN2,...', type=delimited_list(','), help='''ARNs of SNS topics to publish to when the alarm changes to the OK state'''), Arg('--unit', dest='Unit', help="unit for the alarm's associated metric")] euca2ools-3.3.1/euca2ools/commands/monitoring/putmetricdata.py000066400000000000000000000077031267461563000245350ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from requestbuilder import Arg, MutuallyExclusiveArgList from euca2ools.commands.argtypes import delimited_list from euca2ools.commands.monitoring import CloudWatchRequest from euca2ools.commands.monitoring.argtypes import cloudwatch_dimension def _statistic_set(set_as_str): pairs = {} for pair in set_as_str.split(','): try: key, val = pair.split('=') except ValueError: raise argparse.ArgumentTypeError( 'statistic set must have format KEY1=VALUE1,...') try: pairs[key] = float(val) except ValueError: raise argparse.ArgumentTypeError('value "{0}" must be numeric' .format(val)) for field in ('Maximum', 'Minimum', 'SampleCount', 'Sum'): if field not in pairs: raise argparse.ArgumentTypeError( 'value for statistic "{0}" is required'.format(field)) return pairs class PutMetricData(CloudWatchRequest): DESCRIPTION = 'Add data points or statistics to a metric' ARGS = [Arg('-m', '--metric-name', dest='MetricData.member.1.MetricName', metavar='METRIC', required=True, help='name of the metric to add data points to (required)'), Arg('-n', '--namespace', dest='Namespace', required=True, help="the metric's namespace (required)"), MutuallyExclusiveArgList( Arg('-v', '--value', dest='MetricData.member.1.Value', metavar='FLOAT', type=float, help='data value for the metric'), Arg('-s', '--statistic-values', '--statisticValues', dest='MetricData.member.1.StatisticValues', metavar=('Maximum=FLOAT,Minimum=FLOAT,SampleCount=FLOAT,' 'Sum=FLOAT'), type=_statistic_set, help='''statistic values for the metric. Maximum, Minimum, SampleCount, and Sum values are all required.''')) .required(), Arg('-d', '--dimensions', dest='MetricData.member.1.Dimensions.member', metavar='KEY1=VALUE1,KEY2=VALUE2,...', type=delimited_list(',', item_type=cloudwatch_dimension), help='the dimensions of the metric to add data points to'), Arg('-t', '--timestamp', dest='MetricData.member.1.Timestamp', metavar='YYYY-MM-DDThh:mm:ssZ', help='timestamp of the data point'), Arg('-u', '--unit', dest='MetricData.member.1.Unit', metavar='UNIT', help='unit the metric is being reported in')] euca2ools-3.3.1/euca2ools/commands/monitoring/setalarmstate.py000066400000000000000000000042511267461563000245330ustar00rootroot00000000000000# Copyright 2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.monitoring import CloudWatchRequest from requestbuilder import Arg class SetAlarmState(CloudWatchRequest): DESCRIPTION = 'Temporarily set the state of an alarm' ARGS = [Arg('AlarmName', metavar='ALARM', help='name of the alarm to update (required)'), Arg('--state-value', dest='StateValue', required=True, choices=('ALARM', 'INSUFFICIENT_DATA', 'OK'), help='state to set the alarm to (required)'), Arg('--state-reason', dest='StateReason', metavar='REASON', required=True, help='''human-readable reason why the alarm was set to this state (required)'''), Arg('--state-reason-data', dest='StateReasonData', metavar='JSON', help='''JSON-formatted reason why the alarm was set to this state''')] euca2ools-3.3.1/euca2ools/commands/s3/000077500000000000000000000000001267461563000174465ustar00rootroot00000000000000euca2ools-3.3.1/euca2ools/commands/s3/__init__.py000066400000000000000000000245271267461563000215710ustar00rootroot00000000000000# Copyright 2013-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os import string import sys import urlparse import warnings from requestbuilder import Arg import requestbuilder.auth.aws import requestbuilder.exceptions import requestbuilder.request import requestbuilder.service import requests import six from euca2ools.commands import Euca2ools from euca2ools.exceptions import AWSError class S3(requestbuilder.service.BaseService): NAME = 's3' DESCRIPTION = 'Object storage service' REGION_ENVVAR = 'AWS_DEFAULT_REGION' URL_ENVVAR = 'S3_URL' ARGS = [Arg('-U', '--url', metavar='URL', help='object storage service endpoint URL')] def handle_http_error(self, response): raise AWSError(response) def build_presigned_url(self, method='GET', path=None, params=None, auth=None, auth_args=None): # requestbuilder 0.2 msg = ('S3.build_presigned_url is deprecated; use ' 'S3Request.get_presigned_url2 instead') self.log.warn(msg) warnings.warn(msg, DeprecationWarning) if path: # We can't simply use urljoin because a path might start with '/' # like it could for keys that start with that character. if self.endpoint.endswith('/'): url = self.endpoint + path else: url = self.endpoint + '/' + path else: url = self.endpoint request = requests.Request(method=method, url=url, params=params) if auth is not None: auth.apply_to_request_params(request, self, **(auth_args or {})) p_request = request.prepare() return p_request.url def resolve_url_to_location(self, url): """ Given a URL, try to return its associated region, bucket, and key names based on this object's endpoint info as well as all S3 endpoints given in the configuration. """ parsed_url = six.moves.urllib.parse.urlparse(url) if not parsed_url.scheme: parsed_url = six.moves.urllib.parse.urlparse('http://' + url) parsed_own_url = six.moves.urllib.parse.urlparse(self.endpoint) bucket, key = self.__match_path(parsed_url, parsed_own_url) if bucket: return self.region_name, bucket, key else: # Try to look it up in the config s3_urls = self.config.get_all_region_options('s3-url') for section, conf_url in s3_urls.iteritems(): parsed_conf_url = six.moves.urllib.parse.urlparse(conf_url) bucket, key = self.__match_path(parsed_url, parsed_conf_url) if bucket: region = self.config.get_region_option('name', region=section) return region or section, bucket, key raise ValueError("URL '{0}' matches no known object storage " "endpoints. Supply one via the command line or " "configuration.".format(url)) def __match_path(self, given, service): if given.netloc == service.netloc: # path-style service_path = service.path if not service_path.endswith('/'): service_path += '/' cpath = given.path.split(service_path, 1)[1] bucket, key = cpath.split('/', 1) self.log.debug('URL path match: %s://%s%s + %s://%s%s -> %s/%s', given.scheme, given.netloc, given.path, service.scheme, service.netloc, service.path, bucket, key) elif given.netloc.endswith(service.netloc): # vhost-style bucket = given.netloc.rsplit('.' + service.netloc, 1)[0] bucket = bucket.lstrip('/') if given.path.startswith('/'): key = given.path[1:] else: key = given.path self.log.debug('URL vhost match: %s://%s%s + %s://%s%s -> %s/%s', given.scheme, given.netloc, given.path, service.scheme, service.netloc, service.path, bucket, key) else: bucket = None key = None return bucket, key class S3Request(requestbuilder.request.BaseRequest): SUITE = Euca2ools SERVICE_CLASS = S3 AUTH_CLASS = requestbuilder.auth.aws.HmacV1Auth def __init__(self, **kwargs): requestbuilder.request.BaseRequest.__init__(self, **kwargs) self.redirects_left = 3 def configure(self): requestbuilder.request.BaseRequest.configure(self) if self.__should_use_sigv4(): self.log.info('switching to HmacV4Auth') auth = requestbuilder.auth.aws.HmacV4Auth.from_other(self.auth) auth.configure() self.auth = auth def __should_use_sigv4(self): return self.config.convert_to_bool( self.config.get_region_option('s3-force-sigv4')) def get_presigned_url(self, expiration_datetime): # requestbuilder 0.2 msg = ('S3Request.get_presigned_url is deprecated; use ' 'S3Request.get_presigned_url2 instead') self.log.warn(msg) warnings.warn(msg, DeprecationWarning) self.preprocess() return self.service.build_presigned_url( method=self.method, path=self.path, params=self.params, auth=self.auth, auth_args={'expiration_datetime': expiration_datetime}) def get_presigned_url2(self, timeout): """ Get a pre-signed URL for this request that expires after a given number of seconds. """ # requestbuilder 0.3 self.preprocess() if self.__should_use_sigv4(): # UNSIGNED-PAYLOAD is a magical string used for S3 V4 query auth. auth = requestbuilder.auth.aws.QueryHmacV4Auth.from_other( self.auth, timeout=timeout, payload_hash='UNSIGNED-PAYLOAD') else: auth = requestbuilder.auth.aws.QueryHmacV1Auth.from_other( self.auth, timeout=timeout) return self.service.get_request_url( method=self.method, path=self.path, params=self.params, auth=auth) def handle_server_error(self, err): if err.status_code == 301: self.log.debug('-- response content --\n', extra={'append': True}) self.log.debug(self.response.text, extra={'append': True}) self.log.debug('-- end of response content --') self.log.error('result: inter-region redirect') msg = 'Aborting due to inter-region redirect' if 'Endpoint' in err.elements: msg += ' to {0}'.format(err.elements['Endpoint']) self.log.debug(msg, exc_info=True) if 'Bucket' in err.elements: bucket = '"{0}" '.format(err.elements['Bucket']) else: bucket = '' parsed = six.moves.urllib.parse.urlparse(self.service.endpoint) msg = ('Bucket {0}is not available from endpoint "{1}". Ensure ' "the object storage service URL matches the bucket's " 'location.'.format(bucket, parsed.netloc)) raise requestbuilder.exceptions.ClientError(msg) else: return requestbuilder.request.BaseRequest.handle_server_error( self, err) def validate_generic_bucket_name(bucket): if len(bucket) == 0: raise ValueError('name is too short') if len(bucket) > 255: raise ValueError('name is too long') for char in bucket: if char not in string.ascii_letters + string.digits + '.-_': raise ValueError('invalid character \'{0}\''.format(char)) def validate_dns_bucket_name(bucket): if len(bucket) < 3: raise ValueError('name is too short') if len(bucket) > 63: raise ValueError('name is too long') if bucket.startswith('.'): raise ValueError('name may not start with \'.\'') if bucket.endswith('.'): raise ValueError('name may not end with \'.\'') labels = bucket.split('.') for label in labels: if len(label) == 0: raise ValueError('name may not contain \'..\'') for char in label: if char not in string.ascii_lowercase + string.digits + '-': raise ValueError('invalid character \'{0}\''.format(char)) if label[0] not in string.ascii_lowercase + string.digits: raise ValueError(('character \'{0}\' may not begin part of a ' 'bucket name').format(label[0])) if label[-1] not in string.ascii_lowercase + string.digits: raise ValueError(('character \'{0}\' may not end part of a ' 'bucket name').format(label[-1])) if len(labels) == 4: try: [int(chunk) for chunk in bucket.split('.')] except ValueError: # This is actually the case we want pass else: raise ValueError('name must not be formatted like an IP address') euca2ools-3.3.1/euca2ools/commands/s3/checkbucket.py000066400000000000000000000034471267461563000223030ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from euca2ools.commands.s3 import S3Request class CheckBucket(S3Request): DESCRIPTION = 'Return successfully if a bucket exists' ARGS = [Arg('bucket', route_to=None, help='name of the bucket to check')] def preprocess(self): # We use GET instead of HEAD so we can get redirections when we talk # to the wrong region. self.method = 'GET' self.path = self.args['bucket'] self.params['max-keys'] = 0 euca2ools-3.3.1/euca2ools/commands/s3/createbucket.py000066400000000000000000000051651267461563000224700ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import xml.etree.ElementTree as ET from requestbuilder import Arg from euca2ools.commands.s3 import S3Request, validate_generic_bucket_name class CreateBucket(S3Request): DESCRIPTION = 'Create a new bucket' ARGS = [Arg('bucket', route_to=None, help='name of the new bucket'), Arg('--location', route_to=None, help='''location constraint to configure the bucket with (default: inferred from s3-location-constraint in configuration, or otherwise none)''')] def configure(self): S3Request.configure(self) validate_generic_bucket_name(self.args['bucket']) def preprocess(self): self.method = 'PUT' self.path = self.args['bucket'] cb_config = ET.Element('CreateBucketConfiguration') cb_config.set('xmlns', 'http://doc.s3.amazonaws.com/2006-03-01') lconstraint = (self.args.get('location') or self.config.get_region_option('s3-location-constraint')) if lconstraint: cb_lconstraint = ET.SubElement(cb_config, 'LocationConstraint') cb_lconstraint.text = lconstraint if len(cb_config.getchildren()): cb_xml = ET.tostring(cb_config) self.log.debug('bucket configuration: %s', cb_xml) self.body = cb_xml euca2ools-3.3.1/euca2ools/commands/s3/deletebucket.py000066400000000000000000000034751267461563000224710ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.s3 import (S3Request, validate_generic_bucket_name) from requestbuilder import Arg class DeleteBucket(S3Request): DESCRIPTION = 'Delete a bucket' ARGS = [Arg('bucket', route_to=None, help='name of the bucket to delete')] def configure(self): S3Request.configure(self) validate_generic_bucket_name(self.args['bucket']) def preprocess(self): self.method = 'DELETE' self.path = self.args['bucket'] euca2ools-3.3.1/euca2ools/commands/s3/deleteobject.py000066400000000000000000000036711267461563000224600ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.s3 import S3Request from requestbuilder import Arg from requestbuilder.exceptions import ArgumentError class DeleteObject(S3Request): DESCRIPTION = 'Delete an object from the server' ARGS = [Arg('path', metavar='BUCKET/KEY', route_to=None)] METHOD = 'DELETE' # noinspection PyExceptionInherit def configure(self): S3Request.configure(self) if '/' not in self.args['path']: raise ArgumentError("path '{0}' must include a key name" .format(self.args['path'])) def preprocess(self): self.path = self.args['path'] euca2ools-3.3.1/euca2ools/commands/s3/getobject.py000066400000000000000000000130541267461563000217710ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import hashlib import os.path import sys from requestbuilder import Arg from requestbuilder.exceptions import ArgumentError from requestbuilder.mixins import FileTransferProgressBarMixin from euca2ools.commands.s3 import S3Request import euca2ools.bundle.pipes class GetObject(S3Request, FileTransferProgressBarMixin): DESCRIPTION = 'Retrieve objects from the server' ARGS = [Arg('source', metavar='BUCKET/KEY', route_to=None, help='the object to download (required)'), Arg('-o', dest='dest', metavar='PATH', route_to=None, default='.', help='''where to download to. If this names a directory the object will be written to a file inside of that directory. If this is is "-" the object will be written to stdout. Otherwise it will be written to a file with the name given. (default: current directory)''')] def configure(self): S3Request.configure(self) bucket, _, key = self.args['source'].partition('/') if not bucket: raise ArgumentError('source must contain a bucket name') if not key: raise ArgumentError('source must contain a key name') if isinstance(self.args.get('dest'), basestring): # If it is not a string we assume it is a file-like object if self.args['dest'] == '-': self.args['dest'] = sys.stdout elif os.path.isdir(self.args['dest']): basename = os.path.basename(key) if not basename: raise ArgumentError("specify a complete file path with -o " "to download objects that end in '/'") dest_path = os.path.join(self.args['dest'], basename) self.args['dest'] = open(dest_path, 'w') else: self.args['dest'] = open(self.args['dest'], 'w') def preprocess(self): self.path = self.args['source'] def main(self): # Note that this method does not close self.args['dest'] self.preprocess() bytes_written = 0 md5_digest = hashlib.md5() sha_digest = hashlib.sha1() response = self.send() content_length = response.headers.get('Content-Length') if content_length: pbar = self.get_progressbar(label=self.args['source'], maxval=int(content_length)) else: pbar = self.get_progressbar(label=self.args['source']) pbar.start() for chunk in response.iter_content(chunk_size=euca2ools.BUFSIZE): self.args['dest'].write(chunk) bytes_written += len(chunk) md5_digest.update(chunk) sha_digest.update(chunk) if pbar is not None: pbar.update(bytes_written) self.args['dest'].flush() pbar.finish() # Integrity checks if content_length and bytes_written != int(content_length): self.log.error('rejecting download due to Content-Length size ' 'mismatch (expected: %i, actual: %i)', content_length, bytes_written) raise RuntimeError('downloaded file appears to be corrupt ' '(expected size: {0}, actual: {1})' .format(content_length, bytes_written)) etag = response.headers.get('ETag', '').lower().strip('"') if (len(etag) == 32 and all(char in '0123456789abcdef' for char in etag)): # It looks like an MD5 hash if md5_digest.hexdigest() != etag: self.log.error('rejecting download due to ETag MD5 mismatch ' '(expected: %s, actual: %s)', etag, md5_digest.hexdigest()) raise RuntimeError('downloaded file appears to be corrupt ' '(expected MD5: {0}, actual: {1})' .format(etag, md5_digest.hexdigest())) return {self.args['source']: {'md5': md5_digest.hexdigest(), 'sha1': sha_digest.hexdigest(), 'size': bytes_written}} euca2ools-3.3.1/euca2ools/commands/s3/headobject.py000066400000000000000000000040321267461563000221070ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg from requestbuilder.exceptions import ArgumentError from euca2ools.commands.s3 import S3Request class HeadObject(S3Request): DESCRIPTION = 'Retrieve info about an object from the server' ARGS = [Arg('path', metavar='BUCKET/KEY', route_to=None, help='the object to retrieve info for (required)')] METHOD = 'HEAD' def configure(self): S3Request.configure(self) bucket, _, key = self.args['path'].partition('/') if not bucket: raise ArgumentError('path must contain a bucket name') if not key: raise ArgumentError('path must contain a key name') def preprocess(self): self.path = self.args['path'] euca2ools-3.3.1/euca2ools/commands/s3/listallmybuckets.py000066400000000000000000000057041267461563000234210ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from euca2ools.commands.s3 import S3Request from requestbuilder import Arg from requestbuilder.mixins import TabifyingMixin from requestbuilder.xmlparse import parse_listdelimited_aws_xml class ListAllMyBuckets(S3Request, TabifyingMixin): DESCRIPTION = 'List all buckets owned by your account' ARGS = [Arg('-l', dest='long_output', action='store_true', route_to=None, help='''list in long format, with creation dates and owner info'''), Arg('-n', dest='numeric_output', action='store_true', route_to=None, help='''display account IDs numerically in long (-l) output. This option turns on the -l option.''')] def configure(self): S3Request.configure(self) if self.args['numeric_output']: self.args['long_output'] = True def preprocess(self): self.method = 'GET' self.path = '' def parse_response(self, response): response_dict = self.log_and_parse_response( response, parse_listdelimited_aws_xml, list_tags=('Buckets',)) return response_dict['ListAllMyBucketsResult'] def print_result(self, result): if self.args['numeric_output'] or 'DisplayName' not in result['Owner']: owner = result.get('Owner', {}).get('ID') else: owner = result.get('Owner', {}).get('DisplayName') for bucket in result.get('Buckets', []): if self.args['long_output']: print self.tabify((owner, bucket.get('CreationDate'), bucket.get('Name'))) else: print bucket.get('Name') euca2ools-3.3.1/euca2ools/commands/s3/listbucket.py000066400000000000000000000072361267461563000222010ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse from requestbuilder import Arg from requestbuilder.exceptions import ArgumentError from requestbuilder.mixins import TabifyingMixin from requestbuilder.response import PaginatedResponse from requestbuilder.xmlparse import parse_aws_xml from euca2ools.commands.s3 import S3Request, validate_generic_bucket_name class ListBucket(S3Request, TabifyingMixin): DESCRIPTION = 'List keys in one or more buckets' ARGS = [Arg('paths', metavar='BUCKET[/KEY]', nargs='+', route_to=None), Arg('--max-keys-per-request', dest='max-keys', type=int, default=argparse.SUPPRESS, help=argparse.SUPPRESS)] # noinspection PyExceptionInherit def configure(self): S3Request.configure(self) for path in self.args['paths']: if path.startswith('/'): raise ArgumentError(( 'argument \'{0}\' must not start with ' '"/"; format is BUCKET[/KEY]').format(path)) bucket = path.split('/', 1)[0] try: validate_generic_bucket_name(bucket) except ValueError as err: raise ArgumentError( 'bucket "{0}": {1}'.format(bucket, err.message)) def main(self): self.method = 'GET' pages = [(path, {}) for path in self.args['paths']] return PaginatedResponse(self, pages, ('Contents',)) def get_next_page(self, response): if response.get('IsTruncated') == 'true': return self.path, {'marker': response['Contents'][-1]['Key']} def prepare_for_page(self, page): bucket, _, prefix = page[0].partition('/') markers = page[1] self.path = bucket if prefix: self.params['prefix'] = prefix elif 'prefix' in self.params: del self.params['prefix'] if markers is not None and markers.get('marker'): self.params['marker'] = markers['marker'] elif 'marker' in self.params: del self.params['marker'] def parse_response(self, response): response_dict = self.log_and_parse_response( response, parse_aws_xml, list_item_tags=('Contents', 'CommonPrefixes')) return response_dict['ListBucketResult'] def print_result(self, result): for obj in result.get('Contents', []): print obj.get('Key') euca2ools-3.3.1/euca2ools/commands/s3/postobject.py000066400000000000000000000123231267461563000221750ustar00rootroot00000000000000# Copyright 2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse import base64 import sys from requestbuilder import Arg, MutuallyExclusiveArgList from requestbuilder.exceptions import ArgumentError from euca2ools.commands.argtypes import b64encoded_file_contents from euca2ools.commands.s3 import S3Request class PostObject(S3Request): DESCRIPTION = ('Upload an object to the server using an upload policy\n\n' 'Note that uploading a large file to a region other than ' 'the one the bucket is may result in "Broken pipe" errors ' 'or other connection problems that this program cannot ' 'detect.') AUTH_CLASS = None ARGS = [Arg('source', metavar='FILE', route_to=None, help='file to upload (required)'), Arg('dest', metavar='BUCKET/KEY', route_to=None, help='bucket and key name to upload the object to (required)'), MutuallyExclusiveArgList( Arg('--policy', dest='Policy', metavar='POLICY', type=base64.b64encode, help='upload policy to use for authorization'), Arg('--policy-file', dest='Policy', metavar='FILE', type=b64encoded_file_contents, help='''file containing the upload policy to use for authorization''')) .required(), Arg('--policy-signature', dest='Signature', required=True, help='signature for the upload policy (required)'), Arg('-I', '--access-key-id', dest='AWSAccessKeyId', required=True, metavar='KEY_ID', help='''ID of the access key that signed the upload policy (required)'''), # --security-token is an extension meant for eucalyptus's back end # to use for BundleInstance operations started by the web console. # https://eucalyptus.atlassian.net/browse/EUCA-9911 # https://eucalyptus.atlassian.net/browse/TOOLS-511 Arg('--security-token', dest='x-amz-security-token', default=argparse.SUPPRESS, help=argparse.SUPPRESS), Arg('--acl', default=argparse.SUPPRESS, choices=( 'private', 'public-read', 'public-read-write', 'authenticated-read', 'bucket-owner-read', 'bucket-owner-full-control', 'aws-exec-read', 'ec2-bundle-read'), help='''the ACL the object should have once uploaded. Take care to ensure this satisfies any restrictions the upload policy may contain.'''), Arg('--mime-type', dest='Content-Type', default=argparse.SUPPRESS, help='MIME type for the file being uploaded')] METHOD = 'POST' # noinspection PyExceptionInherit def configure(self): S3Request.configure(self) if self.args['source'] == '-': self.files['file'] = sys.stdin elif isinstance(self.args['source'], basestring): self.files['file'] = open(self.args['source']) else: self.files['file'] = self.args['source'] bucket, _, key = self.args['dest'].partition('/') if not bucket: raise ArgumentError('destination bucket name must be non-empty') if not key: raise ArgumentError('destination key name must be non-empty') # noinspection PyExceptionInherit def preprocess(self): # FIXME: This should really stream the contents of the source rather # than reading it all into memory at once, but at the moment doing so # would require me to write a multipart MIME encoder that supports # both streaming and file rewinding. Patches that do that are very # welcome. # # FIXME: While you're in there, would you mind adding progress bar # support? 8^) self.path, _, self.params['key'] = self.args['dest'].partition('/') self.body = self.params self.params = None euca2ools-3.3.1/euca2ools/commands/s3/putobject.py000066400000000000000000000220731267461563000220230ustar00rootroot00000000000000# Copyright 2013-2014 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import argparse import hashlib import socket import sys import threading import time from requestbuilder import Arg from requestbuilder.exceptions import (ArgumentError, ClientError, TimeoutError) from requestbuilder.mixins import FileTransferProgressBarMixin from euca2ools.commands.s3 import S3Request import euca2ools.util class PutObject(S3Request, FileTransferProgressBarMixin): DESCRIPTION = ('Upload an object to the server\n\nNote that uploading a ' 'large file to a region other than the one the bucket is ' 'may result in "Broken pipe" errors or other connection ' 'problems that this program cannot detect.') ARGS = [Arg('source', metavar='FILE', route_to=None, help='file to upload (required)'), Arg('dest', metavar='BUCKET/KEY', route_to=None, help='bucket and key name to upload the object to (required)'), Arg('--size', type=int, route_to=None, help='''the number of bytes to upload (required when reading from stdin)'''), Arg('--acl', route_to=None, choices=( 'private', 'public-read', 'public-read-write', 'authenticated-read', 'bucket-owner-read', 'bucket-owner-full-control', 'aws-exec-read')), Arg('--mime-type', route_to=None, help='MIME type for the file being uploaded'), Arg('--retry', dest='retries', action='store_const', const=5, default=0, route_to=None, help='retry interrupted uploads up to 5 times'), Arg('--progressbar-label', help=argparse.SUPPRESS)] METHOD = 'PUT' def __init__(self, **kwargs): S3Request.__init__(self, **kwargs) self.last_upload_error = None self._lock = threading.Lock() # noinspection PyExceptionInherit def configure(self): S3Request.configure(self) if self.args['source'] == '-': if self.args.get('size') is None: raise ArgumentError( "argument --size is required when uploading stdin") source = _FileObjectExtent(sys.stdin, self.args['size']) elif isinstance(self.args['source'], basestring): source = _FileObjectExtent.from_filename( self.args['source'], size=self.args.get('size')) else: if self.args.get('size') is None: raise ArgumentError( "argument --size is required when uploading a file object") source = _FileObjectExtent(self.args['source'], self.args['size']) self.args['source'] = source bucket, _, key = self.args['dest'].partition('/') if not bucket: raise ArgumentError('destination bucket name must be non-empty') if not key: raise ArgumentError('destination key name must be non-empty') def preprocess(self): self.path = self.args['dest'] if self.args.get('acl'): self.headers['x-amz-acl'] = self.args['acl'] if self.args.get('mime_type'): self.headers['Content-Type'] = self.args['mime_type'] # noinspection PyExceptionInherit def main(self): self.preprocess() source = self.args['source'] self.headers['Content-Length'] = source.size # We do the upload in another thread so the main thread can show a # progress bar. upload_thread = threading.Thread( target=self.try_send, args=(source,), kwargs={'retries_left': self.args.get('retries') or 0}) # The upload thread is daemonic so ^C will kill the program more # cleanly. upload_thread.daemon = True upload_thread.start() pbar_label = self.args.get('progressbar_label') or source.filename pbar = self.get_progressbar(label=pbar_label, maxval=source.size) pbar.start() while upload_thread.is_alive(): pbar.update(source.tell()) time.sleep(0.05) pbar.finish() upload_thread.join() source.close() with self._lock: if self.last_upload_error is not None: # pylint: disable=E0702 raise self.last_upload_error # pylint: enable=E0702 def try_send(self, source, retries_left=0): self.body = source if retries_left > 0 and not source.can_rewind: self.log.warn('source cannot rewind, so requested retries will ' 'not be attempted') retries_left = 0 try: response = self.send() our_md5 = source.read_hexdigest their_md5 = response.headers['ETag'].lower().strip('"') if their_md5 != our_md5: self.log.error('corrupt upload (our MD5: %s, their MD5: %s', our_md5, their_md5) raise ClientError('upload was corrupted during transit') except ClientError as err: if isinstance(err, TimeoutError): if retries_left > 0: self.log.info('retrying upload (%i retry attempt(s) ' 'remaining)', retries_left) source.rewind() return self.try_send(source, retries_left - 1) with self._lock: self.log.error('upload failed', exc_info=True) self.last_upload_error = err return except Exception as err: with self._lock: self.log.error('upload failed', exc_info=True) self.last_upload_error = err return class _FileObjectExtent(object): # By rights this class should be iterable, but if we do that then requests # will attempt to use chunked transfer-encoding, which S3 does not # support. def __init__(self, fileobj, size, filename=None): self.closed = False self.filename = filename self.fileobj = fileobj self.size = size self.__bytes_read = 0 self.__md5 = hashlib.md5() if hasattr(self.fileobj, 'tell'): self.__initial_pos = self.fileobj.tell() else: self.__initial_pos = None def __len__(self): return self.size @classmethod def from_filename(cls, filename, size=None): if size is None: size = euca2ools.util.get_filesize(filename) return cls(open(filename), size, filename=filename) @property def can_rewind(self): return hasattr(self.fileobj, 'seek') and self.__initial_pos is not None def close(self): self.fileobj.close() self.closed = True def next(self): remaining = self.size - self.__bytes_read if remaining <= 0: raise StopIteration() chunk = self.fileobj.next() # might raise StopIteration, which is good chunk = chunk[:remaining] # throw away data that are off the end self.__bytes_read += len(chunk) self.__md5.update(chunk) return chunk def read(self, size=-1): remaining = self.size - self.__bytes_read if size < 0: chunk_len = remaining else: chunk_len = min(remaining, size) chunk = self.fileobj.read(chunk_len) self.__bytes_read += len(chunk) self.__md5.update(chunk) return chunk @property def read_hexdigest(self): return self.__md5.hexdigest() def rewind(self): if not hasattr(self.fileobj, 'seek'): raise TypeError('file object is not seekable') assert self.__initial_pos is not None self.fileobj.seek(self.__initial_pos) self.__bytes_read = 0 self.__md5 = hashlib.md5() def tell(self): return self.__bytes_read euca2ools-3.3.1/euca2ools/commands/sts/000077500000000000000000000000001267461563000177325ustar00rootroot00000000000000euca2ools-3.3.1/euca2ools/commands/sts/__init__.py000066400000000000000000000047021267461563000220460ustar00rootroot00000000000000# Copyright 2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from requestbuilder import Arg import requestbuilder.auth.aws import requestbuilder.service import requestbuilder.request from euca2ools.commands import Euca2ools from euca2ools.exceptions import AWSError from euca2ools.util import strip_response_metadata, add_fake_region_name class STS(requestbuilder.service.BaseService): NAME = 'sts' DESCRIPTION = 'Token service' API_VERSION = '2011-06-15' REGION_ENVVAR = 'AWS_DEFAULT_REGION' URL_ENVVAR = 'TOKEN_URL' ARGS = [Arg('-U', '--url', metavar='URL', help='token service endpoint URL')] def configure(self): requestbuilder.service.BaseService.configure(self) add_fake_region_name(self) def handle_http_error(self, response): raise AWSError(response) class STSRequest(requestbuilder.request.AWSQueryRequest): SUITE = Euca2ools SERVICE_CLASS = STS AUTH_CLASS = requestbuilder.auth.aws.HmacV4Auth METHOD = 'POST' def parse_response(self, response): response_dict = requestbuilder.request.AWSQueryRequest.parse_response( self, response) return strip_response_metadata(response_dict) euca2ools-3.3.1/euca2ools/commands/sts/assumerole.py000066400000000000000000000165331267461563000224730ustar00rootroot00000000000000# Copyright 2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import datetime import os import pipes import sys from requestbuilder import Arg, MutuallyExclusiveArgList from requestbuilder.exceptions import ArgumentError from euca2ools.commands.sts import STSRequest class AssumeRole(STSRequest): DESCRIPTION = '''\ Assume an IAM role The %(prog)s utility obtains credentials for an IAM role and outputs them in the form of shellcode that sets environment variables that allow euca2ools commands to use them. Use it inside an eval command to make this process seamless: $ eval `%(prog)s myrole` To stop using the role, use euare-releaserole(1).''' ARGS = [Arg('rolename', metavar='ROLE', route_to=None, help='the role to assume'), Arg('-d', '--duration', dest='DurationSeconds', metavar='SECONDS', type=int, default=900, help='''number of seconds the credentials should be valid for (900-3600) (default: 900)'''), Arg('--session-name', dest='RoleSessionName', metavar='PATH', help='''role session identifier to include in the assumed role user ID (default: automatic)'''), MutuallyExclusiveArgList( Arg('-c', dest='csh_output', route_to=None, action='store_true', help='''generate C-shell commands on stdout (default if SHELL looks like a csh-style shell'''), Arg('-s', dest='sh_output', route_to=None, action='store_true', help='''generate Bourne shell commands on stdout (default if SHELL does not look like a csh-style shell''')), MutuallyExclusiveArgList( Arg('--policy-content', dest='Policy', metavar='POLICY_CONTENT', help='''an IAM policy further restricting what the credentials will be allowed to do. This cannot grant additional permissions.'''), Arg('--policy-document', dest='Policy', metavar='FILE', type=open, help='''file containing an IAM policy further restricting what the credentials will be allowed to do. This cannot grant additional permissions.''')), Arg('--external-id', dest='ExternalId', metavar='STR', help='external ID to use for comparison with policies'), Arg('--mfa-serial', dest='SerialNumber', metavar='MFA', help='MFA token serial number'), Arg('--mfa-code', dest='TokenCode', metavar='CODE', help='MFA token code')] def preprocess(self): self.params['RoleArn'] = self.__build_role_arn( self.args.get('rolename')) if not self.params.get('RoleSessionName'): session = datetime.datetime.utcnow().strftime( 'euca2ools-%Y-%m-%dT%H:%M:%SZ') self.params['RoleSessionName'] = session def __build_role_arn(self, arn): """ Build an ARN for a role from the fragment that was supplied at the command line. """ if arn.count(':') == 1 and '/' not in arn: # Special case syntactic sugar arn = '{0}:role/{1}'.format(*arn.split(':')) if arn.count(':') == 0: # S3Access if not arn.startswith('role/'): arn = 'role/' + arn # role/A3Access arn = '{0}:{1}'.format(self.__get_account_id(), arn) if arn.count(':') == 1: # 123456789012:role/S3Access arn = ':' + arn if arn.count(':') == 2: # :123456789012:role/S3Access arn = 'iam:' + arn if arn.count(':') == 3: # iam::123456789012:role/S3Access arn = 'aws:' + arn if arn.count(':') == 4: # aws:iam::123456789012:role/S3Access arn = 'arn:' + arn # Shound be arn:aws:iam::123456789012:role/S3Access at this point return arn def __get_account_id(self): account_id = self.config.get_user_option('account-id') if not account_id: account_id = os.getenv('EC2_USER_ID') if not account_id: raise ArgumentError( 'failed to determine account ID; set account-id for ' 'the user in configuration or EC2_USER_ID in the ' 'environment') return account_id def print_result(self, result): creds = result['Credentials'] # If this list changes please go update ReleaseRole. self.__print_var('AWS_ACCESS_KEY_ID', creds['AccessKeyId']) self.__print_var('AWS_ACCESS_KEY', creds['AccessKeyId']) self.__print_var('EC2_ACCESS_KEY', creds['AccessKeyId']) self.__print_var('AWS_SECRET_ACCESS_KEY', creds['SecretAccessKey']) self.__print_var('AWS_SECRET_KEY', creds['SecretAccessKey']) self.__print_var('EC2_SECRET_KEY', creds['SecretAccessKey']) self.__print_var('AWS_SESSION_TOKEN', creds['SessionToken']) self.__print_var('AWS_SECURITY_TOKEN', creds['SessionToken']) self.__print_var('AWS_CREDENTIAL_EXPIRATION', creds['Expiration']) self.__print_var('EC2_USER_ID', self.params['RoleArn'].split(':')[4]) # Unset AWS_CREDENTIAL_FILE to avoid accidentally using its creds self.__print_var('AWS_CREDENTIAL_FILE', None) print print '# If you can read this, rerun this program with eval:' print '# eval `{0}`'.format( ' '.join(pipes.quote(arg) for arg in sys.argv)) def __print_var(self, key, val): if (self.args.get('csh_output') or (not self.args.get('sh_output') and os.getenv('SHELL', '').endswith('csh'))): if val: fmt = 'setenv {key} {val};' else: fmt = 'unsetenv {key};' else: if val: fmt = '{key}={val}; export {key};' else: fmt = 'unset {key};' print fmt.format(key=key, val=val) euca2ools-3.3.1/euca2ools/exceptions.py000066400000000000000000000057371267461563000200670ustar00rootroot00000000000000# Copyright 2009-2013 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import io import requestbuilder.exceptions from requestbuilder.xmlparse import parse_aws_xml import six class AWSError(requestbuilder.exceptions.ServerError): def __init__(self, response, *args): requestbuilder.exceptions.ServerError.__init__(self, response, *args) self.code = None # API error code self.message = None # Error message self.elements = {} # Elements in the error response's body if self.body: try: parsed = parse_aws_xml(io.StringIO(six.text_type(self.body))) parsed = parsed[parsed.keys()[0]] # Strip off the root element if 'Errors' in parsed: # This could probably be improved, but meh. Patches are # welcome. :) parsed = parsed['Errors'] if 'Error' in parsed: parsed = parsed['Error'] if parsed.get('Code'): self.code = parsed['Code'] self.args += (parsed['Code'],) self.message = parsed.get('Message') self.elements = parsed except ValueError: # Dump the unparseable message body so we don't include # unusable garbage in the exception. Since Eucalyptus # frequently returns plain text and/or broken XML, store it # in case we need it later. self.message = self.body self.args += (self.message,) def format_for_cli(self): return 'error ({0}): {1}'.format(self.code or self.status_code, self.message or self.reason) euca2ools-3.3.1/euca2ools/util.py000066400000000000000000000166571267461563000166660ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import datetime import getpass import inspect import os.path import pkgutil import stat import struct import sys import tempfile import requestbuilder.service import euca2ools.commands def build_progressbar_label_template(fnames): if len(fnames) == 0: return None elif len(fnames) == 1: return '{fname}' else: max_fname_len = max(len(os.path.basename(fname)) for fname in fnames) fmt_template = '{{fname:<{maxlen}}} ({{index:>{lenlen}}}/{total})' return fmt_template.format(maxlen=max_fname_len, lenlen=len(str(len(fnames))), total=len(fnames)) # pylint: disable=W0622 def mkdtemp_for_large_files(suffix='', prefix='tmp', dir=None): """ Like tempfile.mkdtemp, but using /var/tmp as a last resort instead of /tmp. This is meant for utilities that create large files, as /tmp is often a ramdisk. """ if dir is None: dir = (os.getenv('TMPDIR') or os.getenv('TEMP') or os.getenv('TMP') or '/var/tmp') return tempfile.mkdtemp(suffix=suffix, prefix=prefix, dir=dir) # pylint: enable=W0622 def prompt_for_password(): pass1 = getpass.getpass(prompt='New password: ') pass2 = getpass.getpass(prompt='Retype new password: ') if pass1 == pass2: return pass1 else: print >> sys.stderr, 'error: passwords do not match' return prompt_for_password() def strip_response_metadata(response_dict): useful_keys = [key for key in response_dict if key != 'ResponseMetadata'] if len(useful_keys) == 1: return response_dict[useful_keys[0]] or {} else: return response_dict def build_iam_policy(effect, resources, actions): policy = {'Statement': []} for resource in resources or []: sid = datetime.datetime.utcnow().strftime('Stmt%Y%m%d%H%M%S%f') statement = {'Sid': sid, 'Effect': effect, 'Action': actions, 'Resource': resource} policy['Statement'].append(statement) return policy def get_filesize(filename): mode = os.stat(filename).st_mode if stat.S_ISBLK(mode): # os.path.getsize doesn't work on block devices, but we can use lseek # to figure it out block_fd = os.open(filename, os.O_RDONLY) try: return os.lseek(block_fd, 0, os.SEEK_END) finally: os.close(block_fd) elif any((stat.S_ISCHR(mode), stat.S_ISFIFO(mode), stat.S_ISSOCK(mode), stat.S_ISDIR(mode))): raise TypeError("'{0}' does not have a usable file size" .format(filename)) return os.path.getsize(filename) def get_vmdk_image_size(filename): if get_filesize(filename) < 1024: raise ValueError('File {0} is to small to be a valid Stream' ' Optimized VMDK'.format(filename)) # see https://www.vmware.com/support/developer/vddk/vmdk_50_technote.pdf # for header/footer format with open(filename, 'rb') as disk: data = struct.unpack('=0.3.4 requests six>=1.4 euca2ools-3.3.1/requirements26.txt000066400000000000000000000000751267461563000170620ustar00rootroot00000000000000argparse PyYAML lxml requestbuilder>=0.3.4 requests six>=1.4 euca2ools-3.3.1/setup.py000066400000000000000000000152261267461563000151440ustar00rootroot00000000000000# Copyright 2009-2015 Eucalyptus Systems, Inc. # # Redistribution and use of this software in source and binary forms, # with or without modification, are permitted provided that the following # conditions are met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from distutils.command.build_py import build_py from distutils.command.build_scripts import build_scripts from distutils.command.install_scripts import install_scripts from distutils.command.sdist import sdist import glob import os.path import sys from setuptools import find_packages, setup from euca2ools import __version__ REQUIREMENTS = ['lxml', 'PyYAML', 'requestbuilder>=0.4', 'requests', 'six>=1.4'] if sys.version_info < (2, 7): REQUIREMENTS.append('argparse') # Cheap hack: install symlinks separately from regular files. # cmd.copy_tree accepts a preserve_symlinks option, but when we call # ``setup.py install'' more than once the method fails when it encounters # symlinks that are already there. class build_scripts_except_symlinks(build_scripts): '''Like build_scripts, but ignoring symlinks''' def copy_scripts(self): orig_scripts = self.scripts self.scripts = [script for script in self.scripts if not os.path.islink(script)] build_scripts.copy_scripts(self) self.scripts = orig_scripts class install_scripts_and_symlinks(install_scripts): '''Like install_scripts, but also replicating nonexistent symlinks''' def run(self): install_scripts.run(self) # Replicate symlinks if they don't exist for script in self.distribution.scripts: if os.path.islink(script): target = os.readlink(script) newlink = os.path.join(self.install_dir, os.path.basename(script)) if not os.path.exists(newlink): os.symlink(target, newlink) class build_py_with_git_version(build_py): '''Like build_py, but also hardcoding the version in __init__.__version__ so it's consistent even outside of the source tree''' def build_module(self, module, module_file, package): build_py.build_module(self, module, module_file, package) print module, module_file, package if module == '__init__' and '.' not in package: version_line = "__version__ = '{0}'\n".format(__version__) old_init_name = self.get_module_outfile(self.build_lib, (package,), module) new_init_name = old_init_name + '.new' with open(new_init_name, 'w') as new_init: with open(old_init_name) as old_init: for line in old_init: if line.startswith('__version__ ='): new_init.write(version_line) else: new_init.write(line) new_init.flush() os.rename(new_init_name, old_init_name) class sdist_with_git_version(sdist): '''Like sdist, but also hardcoding the version in __init__.__version__ so it's consistent even outside of the source tree''' def make_release_tree(self, base_dir, files): sdist.make_release_tree(self, base_dir, files) version_line = "__version__ = '{0}'\n".format(__version__) old_init_name = os.path.join(base_dir, 'euca2ools/__init__.py') new_init_name = old_init_name + '.new' with open(new_init_name, 'w') as new_init: with open(old_init_name) as old_init: for line in old_init: if line.startswith('__version__ ='): new_init.write(version_line) else: new_init.write(line) new_init.flush() os.rename(new_init_name, old_init_name) setup(name="euca2ools", version=__version__, description="Eucalyptus Command Line Tools", long_description="Eucalyptus Command Line Tools", author="Eucalyptus Systems, Inc.", author_email="support@eucalyptus.com", url="http://www.eucalyptus.com", scripts=sum((glob.glob('bin/euare-*'), glob.glob('bin/euca-*'), glob.glob('bin/euform-*'), glob.glob('bin/euimage-*'), glob.glob('bin/eulb-*'), glob.glob('bin/euscale-*'), glob.glob('bin/euwatch-*')), []), data_files=[('share/man/man1', glob.glob('man/*.1')), ('share/man/man5', glob.glob('man/*.5')), ('share/man/man7', glob.glob('man/*.7'))], packages=find_packages(), install_requires=REQUIREMENTS, license='BSD (Simplified)', platforms='Posix; MacOS X', classifiers=['Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', 'Intended Audience :: System Administrators', 'License :: OSI Approved :: Simplified BSD License', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Topic :: Internet'], cmdclass={'build_py': build_py_with_git_version, 'build_scripts': build_scripts_except_symlinks, 'install_scripts': install_scripts_and_symlinks, 'sdist': sdist_with_git_version})