Пример #1
0
  def setUp(self):
    self.cloud_argv = ['--min', '1', '--max', '1', '--group', 'blargscale',
      '--infrastructure', 'ec2', '--machine', 'ami-ABCDEFG']
    self.cluster_argv = ['--ips', 'ips.yaml']
    self.function = "appscale-run-instances"

    # mock out all logging, since it clutters our output
    flexmock(AppScaleLogger)
    AppScaleLogger.should_receive('log').and_return()

    # set up phony AWS credentials for each test
    # ones that test not having them present can
    # remove them
    for credential in EucalyptusAgent.REQUIRED_EC2_CREDENTIALS:
      os.environ[credential] = "baz"
    os.environ['EC2_URL'] = "http://boo"

    # similarly, pretend that our image does exist in EC2
    # and Euca
    fake_ec2 = flexmock(name="fake_ec2")
    fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \
      .and_return()
    fake_ec2.should_receive('get_image').with_args('emi-ABCDEFG') \
      .and_return('anything')

    flexmock(boto)
    boto.should_receive('connect_ec2').with_args('baz', 'baz') \
      .and_return(fake_ec2)
    boto.should_receive('connect_euca').and_return(fake_ec2)
Пример #2
0
    def setUp(self):
        # mock out logging, since it clutters out test output
        flexmock(AppScaleLogger)
        AppScaleLogger.should_receive('log').and_return()

        # next, pretend our ec2 credentials are properly set
        for credential in EC2Agent.REQUIRED_CREDENTIALS:
            os.environ[credential] = "baz"

        # finally, pretend that our ec2 image to use exists
        fake_ec2 = flexmock(name="fake_ec2")
        fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \
          .and_return()
        flexmock(boto)
        boto.should_receive('connect_ec2').with_args(
            'baz', 'baz').and_return(fake_ec2)

        # add in some instance variables so that we don't have
        # a lot IP addresses everywhere
        self.blank_input_yaml = None
        self.default_options = {'table': 'cassandra'}
        self.ip_1 = '192.168.1.1'
        self.ip_2 = '192.168.1.2'
        self.ip_3 = '192.168.1.3'
        self.ip_4 = '192.168.1.4'
        self.ip_5 = '192.168.1.5'
        self.ip_6 = '192.168.1.6'
        self.ip_7 = '192.168.1.7'
        self.ip_8 = '192.168.1.8'
Пример #3
0
    def testUpWithEC2EnvironmentVariables(self):
        # if the user wants us to use their EC2 credentials when running AppScale,
        # we should make sure they get set
        appscale = AppScale()

        # Mock out the actual file reading itself, and slip in a YAML-dumped
        # file
        contents = {
            'infrastructure': 'ec2',
            'machine': 'ami-ABCDEFG',
            'keyname': 'bookey',
            'group': 'boogroup',
            'min': 1,
            'max': 1,
            'EC2_ACCESS_KEY': 'access key',
            'EC2_SECRET_KEY': 'secret key'
        }
        yaml_dumped_contents = yaml.dump(contents)
        self.addMockForAppScalefile(appscale, yaml_dumped_contents)

        # finally, pretend that our ec2 image to use exists
        fake_ec2 = flexmock(name="fake_ec2")
        fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \
          .and_return()
        flexmock(boto)
        boto.should_receive('connect_ec2').with_args('access key', 'secret key') \
          .and_return(fake_ec2)

        # finally, mock out the actual appscale-run-instances call
        flexmock(AppScaleTools)
        AppScaleTools.should_receive('run_instances')
        appscale.up()

        self.assertEquals('access key', os.environ['EC2_ACCESS_KEY'])
        self.assertEquals('secret key', os.environ['EC2_SECRET_KEY'])
Пример #4
0
  def testUpWithEC2EnvironmentVariables(self):
    # if the user wants us to use their EC2 credentials when running AppScale,
    # we should make sure they get set
    appscale = AppScale()

    # Mock out the actual file reading itself, and slip in a YAML-dumped
    # file
    contents = {
      'infrastructure' : 'ec2',
      'machine' : 'ami-ABCDEFG',
      'keyname' : 'bookey',
      'group' : 'boogroup',
      'min' : 1,
      'max' : 1,
      'EC2_ACCESS_KEY' : 'access key',
      'EC2_SECRET_KEY' : 'secret key'
    }
    yaml_dumped_contents = yaml.dump(contents)
    self.addMockForAppScalefile(appscale, yaml_dumped_contents)

    # finally, pretend that our ec2 image to use exists
    fake_ec2 = flexmock(name="fake_ec2")
    fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \
      .and_return()
    flexmock(boto)
    boto.should_receive('connect_ec2').with_args('access key', 'secret key') \
      .and_return(fake_ec2)

    # finally, mock out the actual appscale-run-instances call
    flexmock(AppScaleTools)
    AppScaleTools.should_receive('run_instances')
    appscale.up()

    self.assertEquals('access key', os.environ['EC2_ACCESS_KEY'])
    self.assertEquals('secret key', os.environ['EC2_SECRET_KEY'])
Пример #5
0
    def setUp(self):
        self.cloud_argv = [
            '--min', '1', '--max', '1', '--group', 'blargscale',
            '--infrastructure', 'ec2', '--machine', 'ami-ABCDEFG'
        ]
        self.cluster_argv = ['--ips', 'ips.yaml']
        self.function = "appscale-run-instances"

        # mock out all logging, since it clutters our output
        flexmock(AppScaleLogger)
        AppScaleLogger.should_receive('log').and_return()

        # set up phony AWS credentials for each test
        # ones that test not having them present can
        # remove them
        for credential in EucalyptusAgent.REQUIRED_EC2_CREDENTIALS:
            os.environ[credential] = "baz"
        os.environ['EC2_URL'] = "http://boo"

        # similarly, pretend that our image does exist in EC2
        # and Euca
        fake_ec2 = flexmock(name="fake_ec2")
        fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \
          .and_return()
        fake_ec2.should_receive('get_image').with_args('emi-ABCDEFG') \
          .and_return('anything')

        fake_price = flexmock(name='fake_price', price=1.00)
        fake_ec2.should_receive('get_spot_price_history').and_return(
            [fake_price])

        flexmock(boto)
        boto.should_receive('connect_ec2').with_args('baz', 'baz') \
          .and_return(fake_ec2)
        boto.should_receive('connect_euca').and_return(fake_ec2)
Пример #6
0
  def setUp(self):
    # mock out logging, since it clutters out test output
    flexmock(AppScaleLogger)
    AppScaleLogger.should_receive('log').and_return()

    # next, pretend our ec2 credentials are properly set
    for credential in EC2Agent.REQUIRED_CREDENTIALS:
      os.environ[credential] = "baz"

    # finally, pretend that our ec2 image to use exists
    fake_ec2 = flexmock(name="fake_ec2")
    fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \
      .and_return()
    flexmock(boto)
    boto.should_receive('connect_ec2').with_args('baz', 'baz').and_return(fake_ec2)

    # add in some instance variables so that we don't have
    # a lot IP addresses everywhere
    self.blank_input_yaml = None
    self.default_options = {
      'table' : 'cassandra'
    }
    self.ip_1 = '192.168.1.1'
    self.ip_2 = '192.168.1.2'
    self.ip_3 = '192.168.1.3'
    self.ip_4 = '192.168.1.4'
    self.ip_5 = '192.168.1.5'
    self.ip_6 = '192.168.1.6'
    self.ip_7 = '192.168.1.7'
    self.ip_8 = '192.168.1.8'
Пример #7
0
  def testUpWithCloudAppScalefile(self):
    # calling 'appscale up' if there is an AppScalefile present
    # should call appscale-run-instances with the given config
    # params. here, we assume that the file is intended for use
    # on EC2
    appscale = AppScale()

    # Mock out the actual file reading itself, and slip in a YAML-dumped
    # file
    contents = {
      'infrastructure' : 'ec2',
      'machine' : 'ami-ABCDEFG',
      'keyname' : 'bookey',
      'group' : 'boogroup',
      'min' : 1,
      'max' : 1
    }
    yaml_dumped_contents = yaml.dump(contents)
    self.addMockForAppScalefile(appscale, yaml_dumped_contents)

    # throw in some mocks for the argument parsing
    for credential in EC2Agent.REQUIRED_CREDENTIALS:
      os.environ[credential] = "baz"

    # finally, pretend that our ec2 image to use exists
    fake_ec2 = flexmock(name="fake_ec2")
    fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \
      .and_return()
    flexmock(boto)
    boto.should_receive('connect_ec2').with_args('baz', 'baz').and_return(fake_ec2)

    # finally, mock out the actual appscale-run-instances call
    flexmock(AppScaleTools)
    AppScaleTools.should_receive('run_instances')
    appscale.up()
Пример #8
0
  def setUp(self):
    self.cloud_argv = ['--min', '1', '--max', '1', '--group', 'blargscale',
      '--infrastructure', 'ec2', '--machine', 'ami-ABCDEFG', '--zone',
      'my-zone-1b']
    self.cluster_argv = ['--ips', 'ips.yaml']
    self.function = "appscale-run-instances"

    # mock out all logging, since it clutters our output
    flexmock(AppScaleLogger)
    AppScaleLogger.should_receive('log').and_return()

    # set up phony AWS credentials for each test
    # ones that test not having them present can
    # remove them
    for credential in EucalyptusAgent.REQUIRED_EC2_CREDENTIALS:
      os.environ[credential] = "baz"
    os.environ['EC2_URL'] = "http://boo"

    # pretend that our credentials are valid.
    fake_ec2 = flexmock(name="fake_ec2")
    fake_ec2.should_receive('get_all_instances')

    # similarly, pretend that our image does exist in EC2
    # and Euca
    fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \
      .and_return()
    fake_ec2.should_receive('get_image').with_args('emi-ABCDEFG') \
      .and_return('anything')

    # Slip in mocks that assume our EBS volume exists in EC2.
    fake_ec2.should_receive('get_all_volumes').with_args(['vol-ABCDEFG']) \
      .and_return('anything')

    # Also pretend that the availability zone we want to use exists.
    fake_ec2.should_receive('get_all_zones').with_args('my-zone-1b') \
      .and_return('anything')

    # Pretend that a bad availability zone doesn't exist.
    fake_ec2.should_receive('get_all_zones').with_args('bad-zone-1b') \
      .and_raise(boto.exception.EC2ResponseError, 'baz', 'baz')

    # Pretend that we have one elastic IP allocated for use.
    fake_ec2.should_receive('get_all_addresses').with_args('GOOD.IP.ADDRESS') \
      .and_return('anything')

    # Pretend that asking for a bad elastic IP doesn't work.
    fake_ec2.should_receive('get_all_addresses').with_args('BAD.IP.ADDRESS') \
      .and_raise(boto.exception.EC2ResponseError, 'baz', 'baz')

    fake_price = flexmock(name='fake_price', price=1.00)
    fake_ec2.should_receive('get_spot_price_history').and_return([fake_price])

    flexmock(boto)
    flexmock(boto.ec2)
    boto.ec2.should_receive('connect_to_region').with_args('my-zone-1',
      aws_access_key_id='baz', aws_secret_access_key='baz').and_return(fake_ec2)
    boto.ec2.should_receive('connect_to_region').with_args('bad-zone-1',
      aws_access_key_id='baz', aws_secret_access_key='baz').and_return(fake_ec2)
    boto.should_receive('connect_euca').and_return(fake_ec2)
  def setUp(self):
    # mock out printing to stdout
    builtins = flexmock(sys.modules['__builtin__'])
    builtins.should_receive('print').and_return()

    # next, pretend our ec2 credentials are properly set
    for credential in EC2Agent.REQUIRED_CREDENTIALS:
      os.environ[credential] = "baz"

    # finally, pretend that our ec2 image to use exists
    fake_ec2 = flexmock(name="fake_ec2")
    fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \
      .and_return()
    flexmock(boto)
    boto.should_receive('connect_ec2').with_args('baz', 'baz').and_return(fake_ec2)

    # do argument parsing here, since the below tests do it the
    # same way every time
    argv = ["--min", "1", "--max", "1", "--infrastructure",
      "ec2", "--machine", "ami-ABCDEFG", "--group", "blargscale"]
    function = "appscale-run-instances"
    self.options = ParseArgs(argv, function).args
    self.my_id = "12345"

    self.expected = {
      "EC2_ACCESS_KEY" : None,
      "EC2_SECRET_KEY" : None,
      "EC2_URL" : None,
      "admin_pass" : None,
      "admin_user" : None,
      "appengine" : 1,
      "autoscale" : True,
      "min" : 1,
      "max" : 1,
      "infrastructure" : "ec2",
      "machine" : "ami-ABCDEFG",
      "force" : False,
      "group" : "blargscale",
      "instance_type" : "m1.large",
      "ips" : None,
      "ips_layout" : None,
      "keyname" : "appscale",
      "login_host" : None,
      "max_spot_price": None,
      "replication" : None,
      "scp" : None,
      "table" : "cassandra",
      "test" : False,
      "use_spot_instances" : False,
      "verbose" : False,
      "version" : False
    }

    # finally, construct a http payload for mocking that the below
    # tests can use
    self.payload = "?boo=baz&min=1&max=1&infrastructure=ec2" + \
      "&machine=ami-ABCDEFG&force=False&group=appscale" + \
      "&instance_type=m1.large&ips=None&keyname=appscale&n=None" + \
      "table=cassandra&test=False&version=False"
Пример #10
0
  def setUp(self):
    self.ec2_args = ['--EC2_ACCESS_KEY', 'baz', '--EC2_SECRET_KEY', 'baz',
      '--infrastructure', 'ec2']
    # change infrastructure and add EC2_URL.
    self.euca_args = self.ec2_args[:-1] + ['euca', '--EC2_URL', 'http://boo']
    self.cloud_argv = ['--min', '1', '--max', '1', '--group', 'blargscale',
                       '--instance_type', 'm3.medium', '--machine',
                       'ami-ABCDEFG', '--zone', 'my-zone-1b'] + self.ec2_args
    self.cluster_argv = ['--ips', 'ips.yaml']
    self.function = "appscale-run-instances"

    # mock out all logging, since it clutters our output
    flexmock(AppScaleLogger)
    AppScaleLogger.should_receive('log').and_return()

    # pretend that our credentials are valid.
    fake_ec2 = flexmock(name="fake_ec2")
    fake_ec2.should_receive('get_all_instances')

    # similarly, pretend that our image does exist in EC2
    # and Euca
    fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \
      .and_return()
    fake_ec2.should_receive('get_image').with_args('emi-ABCDEFG') \
      .and_return('anything')

    # Slip in mocks that assume our EBS volume exists in EC2.
    fake_ec2.should_receive('get_all_volumes').with_args(['vol-ABCDEFG']) \
      .and_return('anything')

    # Also pretend that the availability zone we want to use exists.
    fake_ec2.should_receive('get_all_zones').with_args('my-zone-1b') \
      .and_return('anything')

    # Pretend that a bad availability zone doesn't exist.
    fake_ec2.should_receive('get_all_zones').with_args('bad-zone-1b') \
      .and_raise(boto.exception.EC2ResponseError, 'baz', 'baz')

    # Pretend that we have one elastic IP allocated for use.
    fake_ec2.should_receive('get_all_addresses').with_args('GOOD.IP.ADDRESS') \
      .and_return('anything')

    # Pretend that asking for a bad elastic IP doesn't work.
    fake_ec2.should_receive('get_all_addresses').with_args('BAD.IP.ADDRESS') \
      .and_raise(boto.exception.EC2ResponseError, 'baz', 'baz')

    fake_price = flexmock(name='fake_price', price=1.00)
    fake_ec2.should_receive('get_spot_price_history').and_return([fake_price])

    flexmock(boto)
    flexmock(boto.ec2)
    boto.ec2.should_receive('connect_to_region').with_args('my-zone-1',
      aws_access_key_id='baz', aws_secret_access_key='baz').and_return(fake_ec2)
    boto.ec2.should_receive('connect_to_region').with_args('bad-zone-1',
      aws_access_key_id='baz', aws_secret_access_key='baz').and_return(fake_ec2)
    boto.should_receive('connect_euca').and_return(fake_ec2)
Пример #11
0
  def test_failure_when_ami_doesnt_exist(self):
    # mock out boto calls to EC2 and put in that the image doesn't exist
    fake_ec2 = flexmock(name="fake_ec2")
    fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \
      .and_raise(boto.exception.EC2ResponseError, '', '')

    flexmock(boto)
    boto.should_receive('connect_ec2').with_args('baz', 'baz').and_return(fake_ec2)

    argv = self.cloud_argv[:] + ["--infrastructure", "ec2", "--machine", "ami-ABCDEFG"]
    self.assertRaises(BadConfigurationException, ParseArgs, argv, self.function)
Пример #12
0
    def test_failure_when_ami_doesnt_exist(self):
        # mock out boto calls to EC2 and put in that the image doesn't exist
        fake_ec2 = flexmock(name="fake_ec2")
        fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \
          .and_raise(boto.exception.EC2ResponseError, '', '')

        flexmock(boto)
        boto.should_receive('connect_ec2').with_args('baz', 'baz') \
          .and_return(fake_ec2)

        argv = self.cloud_argv[:] + ["--infrastructure", "ec2", "--machine",\
          "ami-ABCDEFG"]
        self.assertRaises(BadConfigurationException, ParseArgs, argv,
                          self.function)
Пример #13
0
    def testUpWithCloudAppScalefile(self):
        # calling 'appscale up' if there is an AppScalefile present
        # should call appscale-run-instances with the given config
        # params. here, we assume that the file is intended for use
        # on EC2
        appscale = AppScale()

        # Mock out the actual file reading itself, and slip in a YAML-dumped
        # file
        contents = {
            'infrastructure': 'ec2',
            'machine': 'ami-ABCDEFG',
            'keyname': 'bookey',
            'group': 'boogroup',
            'min': 1,
            'max': 1
        }
        yaml_dumped_contents = yaml.dump(contents)
        self.addMockForAppScalefile(appscale, yaml_dumped_contents)

        # throw in some mocks for the argument parsing
        for credential in EC2Agent.REQUIRED_CREDENTIALS:
            os.environ[credential] = "baz"

        # finally, pretend that our ec2 image to use exists
        fake_ec2 = flexmock(name="fake_ec2")
        fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \
          .and_return()
        flexmock(boto)
        boto.should_receive('connect_ec2').with_args(
            'baz', 'baz').and_return(fake_ec2)

        # finally, mock out the actual appscale-run-instances call
        flexmock(AppScaleTools)
        AppScaleTools.should_receive('run_instances')
        appscale.up()
Пример #14
0
    def test_terminate_in_cloud_and_succeeds(self):
        # let's say that there is a locations.yaml file, which means appscale is
        # running, so we should terminate the services on each box
        flexmock(os.path)
        os.path.should_call('exists')  # set up the fall-through
        os.path.should_receive('exists').with_args(
            LocalState.get_locations_yaml_location(
                self.keyname)).and_return(True)

        # mock out reading the locations.yaml file, and pretend that we're on
        # a virtualized cluster
        builtins = flexmock(sys.modules['__builtin__'])
        builtins.should_call('open')

        fake_yaml_file = flexmock(name='fake_file')
        fake_yaml_file.should_receive('read').and_return(
            yaml.dump({
                'infrastructure': 'ec2',
                'group': 'bazboogroup'
            }))
        builtins.should_receive('open').with_args(
          LocalState.get_locations_yaml_location(self.keyname), 'r') \
          .and_return(fake_yaml_file)

        # mock out reading the json file, and pretend that we're running in a
        # two node deployment
        fake_json_file = flexmock(name='fake_file')
        fake_json_file.should_receive('read').and_return(
            json.dumps([{
                'public_ip': 'public1',
                'jobs': ['shadow']
            }, {
                'public_ip': 'public2',
                'jobs': ['appengine']
            }]))
        builtins.should_receive('open').with_args(
          LocalState.get_locations_json_location(self.keyname), 'r') \
          .and_return(fake_json_file)

        # and slip in a fake secret file
        fake_secret_file = flexmock(name='fake_file')
        fake_secret_file.should_receive('read').and_return('the secret')
        builtins.should_receive('open').with_args(
          LocalState.get_secret_key_location(self.keyname), 'r') \
          .and_return(fake_secret_file)

        # mock out talking to EC2
        fake_ec2 = flexmock(name='fake_ec2')

        # let's say that three instances are running, and that two of them are in
        # our deployment
        fake_one_running = flexmock(name='fake_one',
                                    key_name=self.keyname,
                                    state='running',
                                    id='i-ONE',
                                    public_dns_name='public1',
                                    private_dns_name='private1')
        fake_two_running = flexmock(name='fake_two',
                                    key_name=self.keyname,
                                    state='running',
                                    id='i-TWO',
                                    public_dns_name='public2',
                                    private_dns_name='private2')
        fake_three_running = flexmock(name='fake_three',
                                      key_name='abcdefg',
                                      state='running',
                                      id='i-THREE',
                                      public_dns_name='public3',
                                      private_dns_name='private3')
        fake_reservation_running = flexmock(
            name='fake_reservation',
            instances=[fake_one_running, fake_two_running, fake_three_running])

        fake_one_terminated = flexmock(name='fake_one',
                                       key_name=self.keyname,
                                       state='terminated',
                                       id='i-ONE',
                                       public_dns_name='public1',
                                       private_dns_name='private1')
        fake_two_terminated = flexmock(name='fake_two',
                                       key_name=self.keyname,
                                       state='terminated',
                                       id='i-TWO',
                                       public_dns_name='public2',
                                       private_dns_name='private2')
        fake_three_terminated = flexmock(name='fake_three',
                                         key_name='abcdefg',
                                         state='terminated',
                                         id='i-THREE',
                                         public_dns_name='public3',
                                         private_dns_name='private3')
        fake_reservation_terminated = flexmock(name='fake_reservation',
                                               instances=[
                                                   fake_one_terminated,
                                                   fake_two_terminated,
                                                   fake_three_terminated
                                               ])

        fake_ec2.should_receive('get_all_instances').and_return(fake_reservation_running) \
          .and_return(fake_reservation_terminated)

        flexmock(boto)
        boto.should_receive('connect_ec2').and_return(fake_ec2)

        # and mock out the call to kill the instances
        fake_ec2.should_receive('terminate_instances').with_args(
            ['i-ONE',
             'i-TWO']).and_return([fake_one_terminated, fake_two_terminated])

        # mock out the call to delete the keypair
        fake_ec2.should_receive('delete_key_pair').and_return()

        # and the call to delete the security group - let's say that we can't
        # delete the group the first time, and can the second
        fake_ec2.should_receive('delete_security_group').and_return(False) \
          .and_return(True)

        # finally, mock out removing the yaml file, json file, and secret key from
        # this machine
        flexmock(os)
        os.should_receive('remove').with_args(
            LocalState.get_locations_yaml_location(self.keyname)).and_return()
        os.should_receive('remove').with_args(
            LocalState.get_locations_json_location(self.keyname)).and_return()
        os.should_receive('remove').with_args(
            LocalState.get_secret_key_location(self.keyname)).and_return()

        argv = ["--keyname", self.keyname]
        options = ParseArgs(argv, self.function).args
        AppScaleTools.terminate_instances(options)
  def test_terminate_in_cloud_and_succeeds(self):
    # let's say that there is a locations.yaml file, which means appscale is
    # running, so we should terminate the services on each box
    flexmock(os.path)
    os.path.should_call('exists')  # set up the fall-through
    os.path.should_receive('exists').with_args(
      LocalState.get_locations_yaml_location(self.keyname)).and_return(True)

    # mock out reading the locations.yaml file, and pretend that we're on
    # a virtualized cluster
    builtins = flexmock(sys.modules['__builtin__'])
    builtins.should_call('open')

    fake_yaml_file = flexmock(name='fake_file')
    fake_yaml_file.should_receive('read').and_return(yaml.dump({
      'infrastructure' : 'ec2',
      'group' : 'bazboogroup'
    }))
    builtins.should_receive('open').with_args(
      LocalState.get_locations_yaml_location(self.keyname), 'r') \
      .and_return(fake_yaml_file)

    # mock out reading the json file, and pretend that we're running in a
    # two node deployment
    fake_json_file = flexmock(name='fake_file')
    fake_json_file.should_receive('read').and_return(json.dumps([
      {
        'public_ip' : 'public1',
        'jobs' : ['shadow']
      },
      {
        'public_ip' : 'public2',
        'jobs' : ['appengine']
      }
    ]))
    builtins.should_receive('open').with_args(
      LocalState.get_locations_json_location(self.keyname), 'r') \
      .and_return(fake_json_file)

    # and slip in a fake secret file
    fake_secret_file = flexmock(name='fake_file')
    fake_secret_file.should_receive('read').and_return('the secret')
    builtins.should_receive('open').with_args(
      LocalState.get_secret_key_location(self.keyname), 'r') \
      .and_return(fake_secret_file)

    # mock out talking to EC2
    fake_ec2 = flexmock(name='fake_ec2')

    # let's say that three instances are running, and that two of them are in
    # our deployment
    fake_one = flexmock(name='fake_one', key_name=self.keyname, state='running',
      id='i-ONE', public_dns_name='public1', private_dns_name='private1')
    fake_two = flexmock(name='fake_two', key_name=self.keyname, state='running',
      id='i-TWO', public_dns_name='public2', private_dns_name='private2')
    fake_three = flexmock(name='fake_three', key_name='abcdefg',
      state='running', id='i-THREE', public_dns_name='public3',
      private_dns_name='private3')

    fake_reservation = flexmock(name='fake_reservation', instances=[fake_one,
      fake_two, fake_three])
    fake_ec2.should_receive('get_all_instances').and_return(fake_reservation)

    flexmock(boto)
    boto.should_receive('connect_ec2').with_args('baz', 'baz') \
      .and_return(fake_ec2)

    # and mock out the call to kill the instances
    fake_ec2.should_receive('terminate_instances').with_args(['i-ONE',
      'i-TWO']).and_return([fake_one, fake_two])

    # mock out the call to delete the keypair
    fake_ec2.should_receive('delete_key_pair').and_return()

    # and the call to delete the security group - let's say that we can't
    # delete the group the first time, and can the second
    fake_ec2.should_receive('delete_security_group').and_return(False) \
      .and_return(True)

    # finally, mock out removing the yaml file, json file, and secret key from
    # this machine
    flexmock(os)
    os.should_receive('remove').with_args(
      LocalState.get_locations_yaml_location(self.keyname)).and_return()
    os.should_receive('remove').with_args(
      LocalState.get_locations_json_location(self.keyname)).and_return()
    os.should_receive('remove').with_args(
      LocalState.get_secret_key_location(self.keyname)).and_return()

    argv = [
      "--keyname", self.keyname
    ]
    options = ParseArgs(argv, self.function).args
    AppScaleTools.terminate_instances(options)
  def test_appscale_in_one_node_cloud_deployment_manual_spot_price(self):
    # let's say that appscale isn't already running

    local_state = flexmock(LocalState)
    local_state.should_receive('ensure_appscale_isnt_running').and_return()
    local_state.should_receive('make_appscale_directory').and_return()

    # mock out talking to logs.appscale.com
    fake_connection = flexmock(name='fake_connection')
    fake_connection.should_receive('request').with_args('POST', '/upload', str,
      AppScaleLogger.HEADERS).and_return()

    flexmock(httplib)
    httplib.should_receive('HTTPConnection').with_args('logs.appscale.com') \
      .and_return(fake_connection)

    # mock out generating the secret key
    flexmock(uuid)
    uuid.should_receive('uuid4').and_return('the secret')

    # mock out writing the secret key to ~/.appscale, as well as reading it
    # later
    builtins = flexmock(sys.modules['__builtin__'])
    builtins.should_call('open')  # set the fall-through

    secret_key_location = LocalState.get_secret_key_location(self.keyname)
    fake_secret = flexmock(name="fake_secret")
    fake_secret.should_receive('read').and_return('the secret')
    fake_secret.should_receive('write').and_return()
    builtins.should_receive('open').with_args(secret_key_location, 'r') \
      .and_return(fake_secret)
    builtins.should_receive('open').with_args(secret_key_location, 'w') \
      .and_return(fake_secret)

    # mock out interactions with AWS
    fake_ec2 = flexmock(name='fake_ec2')

    # first, pretend that our image does exist in EC2
    fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \
      .and_return()

    # next, assume that our keypair doesn't exist yet
    fake_ec2.should_receive('get_key_pair').with_args(self.keyname) \
      .and_return(None)

    # same for the security group
    fake_ec2.should_receive('get_all_security_groups').and_return([])

    # mock out creating the keypair
    fake_key = flexmock(name='fake_key', material='baz')
    local_state.should_receive('write_key_file').with_args(
      re.compile(self.keyname), fake_key.material).and_return()
    fake_ec2.should_receive('create_key_pair').with_args(self.keyname) \
      .and_return(fake_key)

    # and the same for the security group
    fake_ec2.should_receive('create_security_group').with_args('bazgroup',
      str).and_return()
    fake_ec2.should_receive('authorize_security_group').with_args('bazgroup',
      from_port=1, to_port=65535, ip_protocol='udp', cidr_ip='0.0.0.0/0')
    fake_ec2.should_receive('authorize_security_group').with_args('bazgroup',
      from_port=1, to_port=65535, ip_protocol='tcp', cidr_ip='0.0.0.0/0')
    fake_ec2.should_receive('authorize_security_group').with_args('bazgroup',
      ip_protocol='icmp', cidr_ip='0.0.0.0/0')

    # also mock out acquiring a spot instance
    fake_ec2.should_receive('request_spot_instances').with_args('1.23',
      'ami-ABCDEFG', key_name=self.keyname, security_groups=['bazgroup'],
      instance_type='m1.large', count=1)

    # assume that there are no instances running initially, and that the
    # instance we spawn starts as pending, then becomes running
    no_instances = flexmock(name='no_instances', instances=[])

    pending_instance = flexmock(name='pending_instance', state='pending',
      key_name=self.keyname, id='i-ABCDEFG')
    pending_reservation = flexmock(name='pending_reservation',
      instances=[pending_instance])

    running_instance = flexmock(name='running_instance', state='running',
      key_name=self.keyname, id='i-ABCDEFG', public_dns_name='public1',
      private_dns_name='private1')
    running_reservation = flexmock(name='running_reservation',
      instances=[running_instance])

    fake_ec2.should_receive('get_all_instances').and_return(no_instances) \
      .and_return(pending_reservation).and_return(running_reservation)

    # finally, inject the mocked EC2 in
    flexmock(boto)
    boto.should_receive('connect_ec2').and_return(fake_ec2)

    # assume that root login is not enabled
    local_state.should_receive('shell').with_args(re.compile('ssh'),
      False, 1, stdin='ls').and_return(RemoteHelper.LOGIN_AS_UBUNTU_USER)

    # assume that we can enable root login
    local_state.should_receive('shell').with_args(re.compile('ssh'),
      False, 5, stdin=re.compile('sudo cp')).and_return()

    # and assume that we can copy over our ssh keys fine
    local_state.should_receive('shell').with_args(re.compile('scp .*[r|d]sa'),
      False, 5).and_return()
    local_state.should_receive('shell').with_args(re.compile('scp .*{0}'
      .format(self.keyname)), False, 5).and_return()

    # mock out seeing if the image is appscale-compatible, and assume it is
    # mock out our attempts to find /etc/appscale and presume it does exist
    local_state.should_receive('shell').with_args(re.compile('ssh'),
      False, 5, stdin=re.compile('/etc/appscale')).and_return()

    # mock out our attempts to find /etc/appscale/version and presume it does
    # exist
    local_state.should_receive('shell').with_args(re.compile('ssh'),
      False, 5, stdin=re.compile('/etc/appscale/{0}'
      .format(APPSCALE_VERSION)))

    # put in a mock indicating that the database the user wants is supported
    local_state.should_receive('shell').with_args(re.compile('ssh'),
      False, 5, stdin=re.compile('/etc/appscale/{0}/{1}'
      .format(APPSCALE_VERSION, 'cassandra')))

    # mock out generating the private key
    local_state.should_receive('shell').with_args(re.compile('openssl'),
      False, stdin=None)

    # assume that we started god fine
    local_state.should_receive('shell').with_args(re.compile('ssh'),
      False, 5, stdin=re.compile('god &'))

    # and that we copied over the AppController's god file
    local_state.should_receive('shell').with_args(re.compile('scp'),
      False, 5, stdin=re.compile('appcontroller.god'))

    # also, that we started the AppController itself
    local_state.should_receive('shell').with_args(re.compile('ssh'),
      False, 5, stdin=re.compile('god load'))

    # assume that ssh comes up on the third attempt
    fake_socket = flexmock(name='fake_socket')
    fake_socket.should_receive('connect').with_args(('public1',
      RemoteHelper.SSH_PORT)).and_raise(Exception).and_raise(Exception) \
      .and_return(None)

    # assume that the AppController comes up on the third attempt
    fake_socket.should_receive('connect').with_args(('public1',
      AppControllerClient.PORT)).and_raise(Exception).and_raise(Exception) \
      .and_return(None)

    # same for the UserAppServer
    fake_socket.should_receive('connect').with_args(('public1',
      UserAppClient.PORT)).and_raise(Exception).and_raise(Exception) \
      .and_return(None)

    # as well as for the AppLoadBalancer
    fake_socket.should_receive('connect').with_args(('public1',
      RemoteHelper.APP_LOAD_BALANCER_PORT)).and_raise(Exception) \
      .and_raise(Exception).and_return(None)

    flexmock(socket)
    socket.should_receive('socket').and_return(fake_socket)

    # mock out the SOAP call to the AppController and assume it succeeded
    fake_appcontroller = flexmock(name='fake_appcontroller')
    fake_appcontroller.should_receive('set_parameters').with_args(list, list,
      ['none'], 'the secret').and_return('OK')
    fake_appcontroller.should_receive('get_all_public_ips').with_args('the secret') \
      .and_return(json.dumps(['public1']))
    role_info = [{
      'public_ip' : 'public1',
      'private_ip' : 'private1',
      'jobs' : ['shadow', 'login']
    }]
    fake_appcontroller.should_receive('get_role_info').with_args('the secret') \
      .and_return(json.dumps(role_info))
    fake_appcontroller.should_receive('status').with_args('the secret') \
      .and_return('nothing interesting here') \
      .and_return('Database is at not-up-yet') \
      .and_return('Database is at public1')
    fake_appcontroller.should_receive('is_done_initializing') \
      .and_return(False) \
      .and_return(True)
    flexmock(SOAPpy)
    SOAPpy.should_receive('SOAPProxy').with_args('https://*****:*****@a.com', str, 'xmpp_user', 'the secret') \
      .and_return('true')
    fake_userappserver.should_receive('commit_new_user').with_args(
      'a@public1', str, 'xmpp_user', 'the secret') \
      .and_return('true')
    fake_userappserver.should_receive('set_cloud_admin_status').with_args(
      '*****@*****.**', 'true', 'the secret').and_return()
    fake_userappserver.should_receive('set_capabilities').with_args(
      '*****@*****.**', UserAppClient.ADMIN_CAPABILITIES, 'the secret').and_return()
    SOAPpy.should_receive('SOAPProxy').with_args('https://public1:4343') \
      .and_return(fake_userappserver)

    argv = [
      "--min", "1",
      "--max", "1",
      "--infrastructure", "ec2",
      "--machine", "ami-ABCDEFG",
      "--use_spot_instances",
      "--max_spot_price", "1.23",
      "--keyname", self.keyname,
      "--group", "bazgroup",
      "--test"
    ]

    options = ParseArgs(argv, self.function).args
    AppScaleTools.run_instances(options)
    def setUp(self):
        # mock out all logging, since it clutters our output
        flexmock(AppScaleLogger)
        AppScaleLogger.should_receive("log").and_return()

        # mock out all sleeps, as they aren't necessary for unit testing
        flexmock(time)
        time.should_receive("sleep").and_return()

        # set up some fake options so that we don't have to generate them via
        # ParseArgs
        self.options = flexmock(
            infrastructure="ec2",
            group="boogroup",
            machine="ami-ABCDEFG",
            instance_type="m1.large",
            keyname="bookey",
            table="cassandra",
            verbose=False,
            test=False,
            use_spot_instances=False,
            zone="my-zone-1b",
        )
        self.my_id = "12345"
        self.node_layout = NodeLayout(self.options)

        # set up phony AWS credentials for each test
        # ones that test not having them present can
        # remove them
        for credential in EucalyptusAgent.REQUIRED_EC2_CREDENTIALS:
            os.environ[credential] = "baz"
        os.environ["EC2_URL"] = "http://boo"

        # mock out calls to EC2
        # begin by assuming that our ssh keypair doesn't exist, and thus that we
        # need to create it
        key_contents = "key contents here"
        fake_key = flexmock(name="fake_key", material=key_contents)
        fake_key.should_receive("save").with_args(os.environ["HOME"] + "/.appscale").and_return(None)

        fake_ec2 = flexmock(name="fake_ec2")
        fake_ec2.should_receive("get_key_pair").with_args("bookey").and_return(None)
        fake_ec2.should_receive("create_key_pair").with_args("bookey").and_return(fake_key)

        # mock out writing the secret key
        builtins = flexmock(sys.modules["__builtin__"])
        builtins.should_call("open")  # set the fall-through

        secret_key_location = LocalState.LOCAL_APPSCALE_PATH + "bookey.secret"
        fake_secret = flexmock(name="fake_secret")
        fake_secret.should_receive("write").and_return()
        builtins.should_receive("open").with_args(secret_key_location, "w").and_return(fake_secret)

        # also, mock out the keypair writing and chmod'ing
        ssh_key_location = LocalState.LOCAL_APPSCALE_PATH + "bookey.key"
        fake_file = flexmock(name="fake_file")
        fake_file.should_receive("write").with_args(key_contents).and_return()

        builtins.should_receive("open").with_args(ssh_key_location, "w").and_return(fake_file)

        flexmock(os)
        os.should_receive("chmod").with_args(ssh_key_location, 0600).and_return()

        # next, assume there are no security groups up at first, but then it gets
        # created.
        udp_rule = flexmock(from_port=1, to_port=65535, ip_protocol="udp")
        tcp_rule = flexmock(from_port=1, to_port=65535, ip_protocol="tcp")
        icmp_rule = flexmock(from_port=-1, to_port=-1, ip_protocol="icmp")
        group = flexmock(name="boogroup", rules=[tcp_rule, udp_rule, icmp_rule])
        fake_ec2.should_receive("get_all_security_groups").with_args().and_return([])
        fake_ec2.should_receive("get_all_security_groups").with_args("boogroup").and_return([group])

        # and then assume we can create and open our security group fine
        fake_ec2.should_receive("create_security_group").with_args("boogroup", "AppScale security group").and_return()
        fake_ec2.should_receive("authorize_security_group").and_return()

        # next, add in mocks for run_instances
        # the first time around, let's say that no machines are running
        # the second time around, let's say that our machine is pending
        # and that it's up the third time around
        fake_pending_instance = flexmock(state="pending")
        fake_pending_reservation = flexmock(instances=fake_pending_instance)

        fake_running_instance = flexmock(
            state="running", key_name="bookey", id="i-12345678", public_dns_name="public1", private_dns_name="private1"
        )
        fake_running_reservation = flexmock(instances=fake_running_instance)

        fake_ec2.should_receive("get_all_instances").and_return([]).and_return([fake_pending_reservation]).and_return(
            [fake_running_reservation]
        )

        # next, assume that our run_instances command succeeds
        fake_ec2.should_receive("run_instances").and_return()

        # finally, inject our mocked EC2
        flexmock(boto)
        boto.should_receive("connect_ec2").and_return(fake_ec2)

        # assume that ssh comes up on the third attempt
        fake_socket = flexmock(name="fake_socket")
        fake_socket.should_receive("connect").with_args(("public1", RemoteHelper.SSH_PORT)).and_raise(
            Exception
        ).and_raise(Exception).and_return(None)
        flexmock(socket)
        socket.should_receive("socket").and_return(fake_socket)

        # throw some default mocks together for when invoking via shell succeeds
        # and when it fails
        self.fake_temp_file = flexmock(name="fake_temp_file")
        self.fake_temp_file.should_receive("seek").with_args(0).and_return()
        self.fake_temp_file.should_receive("read").and_return("boo out")
        self.fake_temp_file.should_receive("close").and_return()

        flexmock(tempfile)
        tempfile.should_receive("NamedTemporaryFile").and_return(self.fake_temp_file)

        self.success = flexmock(name="success", returncode=0)
        self.success.should_receive("wait").and_return(0)

        self.failed = flexmock(name="success", returncode=1)
        self.failed.should_receive("wait").and_return(1)

        # assume that root login isn't already enabled
        local_state = flexmock(LocalState)
        local_state.should_receive("shell").with_args(re.compile("^ssh .*root"), False, 1, stdin="ls").and_return(
            "Please login as the ubuntu user rather than root user."
        )

        # and assume that we can ssh in as ubuntu to enable root login
        local_state = flexmock(LocalState)
        local_state.should_receive("shell").with_args(re.compile("^ssh .*ubuntu"), False, 5).and_return()

        # also assume that we can scp over our ssh keys
        local_state.should_receive("shell").with_args(re.compile("scp .*/root/.ssh/id_"), False, 5).and_return()

        local_state.should_receive("shell").with_args(
            re.compile("scp .*/root/.appscale/bookey.key"), False, 5
        ).and_return()
Пример #18
0
  def test_appscale_in_one_node_cloud_deployment_manual_spot_price(self):
    # let's say that appscale isn't already running

    local_state = flexmock(LocalState)
    local_state.should_receive('ensure_appscale_isnt_running').and_return()
    local_state.should_receive('make_appscale_directory').and_return()

    # mock out talking to logs.appscale.com
    fake_connection = flexmock(name='fake_connection')
    fake_connection.should_receive('request').with_args('POST', '/upload', str,
      AppScaleLogger.HEADERS).and_return()

    flexmock(httplib)
    httplib.should_receive('HTTPConnection').with_args('logs.appscale.com') \
      .and_return(fake_connection)

    # mock out generating the secret key
    flexmock(uuid)
    uuid.should_receive('uuid4').and_return('the secret')

    # mock out writing the secret key to ~/.appscale, as well as reading it
    # later
    builtins = flexmock(sys.modules['__builtin__'])
    builtins.should_call('open')  # set the fall-through

    secret_key_location = LocalState.get_secret_key_location(self.keyname)
    fake_secret = flexmock(name="fake_secret")
    fake_secret.should_receive('read').and_return('the secret')
    fake_secret.should_receive('write').and_return()
    builtins.should_receive('open').with_args(secret_key_location, 'r') \
      .and_return(fake_secret)
    builtins.should_receive('open').with_args(secret_key_location, 'w') \
      .and_return(fake_secret)

    # mock out interactions with AWS
    fake_ec2 = flexmock(name='fake_ec2')

    # first, pretend that our image does exist in EC2
    fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \
      .and_return()

    # next, assume that our keypair doesn't exist yet
    fake_ec2.should_receive('get_key_pair').with_args(self.keyname) \
      .and_return(None)

    # same for the security group
    fake_ec2.should_receive('get_all_security_groups').and_return([])

    # mock out creating the keypair
    fake_key = flexmock(name='fake_key', material='baz')
    local_state.should_receive('write_key_file').with_args(
      re.compile(self.keyname), fake_key.material).and_return()
    fake_ec2.should_receive('create_key_pair').with_args(self.keyname) \
      .and_return(fake_key)

    # and the same for the security group
    fake_ec2.should_receive('create_security_group').with_args('bazgroup',
      str).and_return()
    fake_ec2.should_receive('authorize_security_group').with_args('bazgroup',
      from_port=1, to_port=65535, ip_protocol='udp', cidr_ip='0.0.0.0/0')
    fake_ec2.should_receive('authorize_security_group').with_args('bazgroup',
      from_port=1, to_port=65535, ip_protocol='tcp', cidr_ip='0.0.0.0/0')
    fake_ec2.should_receive('authorize_security_group').with_args('bazgroup',
      ip_protocol='icmp', cidr_ip='0.0.0.0/0')

    # also mock out acquiring a spot instance
    fake_ec2.should_receive('request_spot_instances').with_args('1.23',
      'ami-ABCDEFG', key_name=self.keyname, security_groups=['bazgroup'],
      instance_type='m1.large', count=1)

    # assume that there are no instances running initially, and that the
    # instance we spawn starts as pending, then becomes running
    no_instances = flexmock(name='no_instances', instances=[])

    pending_instance = flexmock(name='pending_instance', state='pending',
      key_name=self.keyname, id='i-ABCDEFG')
    pending_reservation = flexmock(name='pending_reservation',
      instances=[pending_instance])

    running_instance = flexmock(name='running_instance', state='running',
      key_name=self.keyname, id='i-ABCDEFG', public_dns_name='public1',
      private_dns_name='private1')
    running_reservation = flexmock(name='running_reservation',
      instances=[running_instance])

    fake_ec2.should_receive('get_all_instances').and_return(no_instances) \
      .and_return(pending_reservation).and_return(running_reservation)

    # finally, inject the mocked EC2 in
    flexmock(boto)
    boto.should_receive('connect_ec2').and_return(fake_ec2)

    # assume that root login is not enabled
    local_state.should_receive('shell').with_args(re.compile('ssh'),
      False, 1, stdin='ls').and_return(RemoteHelper.LOGIN_AS_UBUNTU_USER)

    # assume that we can enable root login
    local_state.should_receive('shell').with_args(re.compile('ssh'),
      False, 5, stdin=re.compile('sudo cp')).and_return()

    # and assume that we can copy over our ssh keys fine
    local_state.should_receive('shell').with_args(re.compile('scp .*[r|d]sa'),
      False, 5).and_return()
    local_state.should_receive('shell').with_args(re.compile('scp .*{0}'
      .format(self.keyname)), False, 5).and_return()

    # mock out seeing if the image is appscale-compatible, and assume it is
    # mock out our attempts to find /etc/appscale and presume it does exist
    local_state.should_receive('shell').with_args(re.compile('ssh'),
      False, 5, stdin=re.compile('/etc/appscale')).and_return()

    # mock out our attempts to find /etc/appscale/version and presume it does
    # exist
    local_state.should_receive('shell').with_args(re.compile('ssh'),
      False, 5, stdin=re.compile('/etc/appscale/{0}'
      .format(APPSCALE_VERSION)))

    # put in a mock indicating that the database the user wants is supported
    local_state.should_receive('shell').with_args(re.compile('ssh'),
      False, 5, stdin=re.compile('/etc/appscale/{0}/{1}'
      .format(APPSCALE_VERSION, 'cassandra')))

    # mock out generating the private key
    local_state.should_receive('shell').with_args(re.compile('openssl'),
      False, stdin=None)

    # assume that we started god fine
    local_state.should_receive('shell').with_args(re.compile('ssh'),
      False, 5, stdin=re.compile('god &'))

    # and that we copied over the AppController's god file
    local_state.should_receive('shell').with_args(re.compile('scp'),
      False, 5, stdin=re.compile('appcontroller.god'))

    # also, that we started the AppController itself
    local_state.should_receive('shell').with_args(re.compile('ssh'),
      False, 5, stdin=re.compile('god load'))

    # assume that ssh comes up on the third attempt
    fake_socket = flexmock(name='fake_socket')
    fake_socket.should_receive('connect').with_args(('public1',
      RemoteHelper.SSH_PORT)).and_raise(Exception).and_raise(Exception) \
      .and_return(None)

    # assume that the AppController comes up on the third attempt
    fake_socket.should_receive('connect').with_args(('public1',
      AppControllerClient.PORT)).and_raise(Exception).and_raise(Exception) \
      .and_return(None)

    # same for the UserAppServer
    fake_socket.should_receive('connect').with_args(('public1',
      UserAppClient.PORT)).and_raise(Exception).and_raise(Exception) \
      .and_return(None)

    # as well as for the AppDashboard
    fake_socket.should_receive('connect').with_args(('public1',
      RemoteHelper.APP_DASHBOARD_PORT)).and_raise(Exception) \
      .and_raise(Exception).and_return(None)

    flexmock(socket)
    socket.should_receive('socket').and_return(fake_socket)

    # mock out the SOAP call to the AppController and assume it succeeded
    fake_appcontroller = flexmock(name='fake_appcontroller')
    fake_appcontroller.should_receive('set_parameters').with_args(list, list,
      ['none'], 'the secret').and_return('OK')
    fake_appcontroller.should_receive('get_all_public_ips').with_args('the secret') \
      .and_return(json.dumps(['public1']))
    role_info = [{
      'public_ip' : 'public1',
      'private_ip' : 'private1',
      'jobs' : ['shadow', 'login']
    }]
    fake_appcontroller.should_receive('get_role_info').with_args('the secret') \
      .and_return(json.dumps(role_info))
    fake_appcontroller.should_receive('status').with_args('the secret') \
      .and_return('nothing interesting here') \
      .and_return('Database is at not-up-yet') \
      .and_return('Database is at public1')
    fake_appcontroller.should_receive('is_done_initializing') \
      .and_return(False) \
      .and_return(True)
    flexmock(SOAPpy)
    SOAPpy.should_receive('SOAPProxy').with_args('https://*****:*****@a.com', str, 'xmpp_user', 'the secret') \
      .and_return('true')
    fake_userappserver.should_receive('commit_new_user').with_args(
      'a@public1', str, 'xmpp_user', 'the secret') \
      .and_return('true')
    fake_userappserver.should_receive('set_cloud_admin_status').with_args(
      '*****@*****.**', 'true', 'the secret').and_return()
    fake_userappserver.should_receive('set_capabilities').with_args(
      '*****@*****.**', UserAppClient.ADMIN_CAPABILITIES, 'the secret').and_return()
    SOAPpy.should_receive('SOAPProxy').with_args('https://public1:4343') \
      .and_return(fake_userappserver)

    argv = [
      "--min", "1",
      "--max", "1",
      "--infrastructure", "ec2",
      "--machine", "ami-ABCDEFG",
      "--use_spot_instances",
      "--max_spot_price", "1.23",
      "--keyname", self.keyname,
      "--group", "bazgroup",
      "--test"
    ]

    options = ParseArgs(argv, self.function).args
    AppScaleTools.run_instances(options)
Пример #19
0
  def setUp(self):
    # mock out all logging, since it clutters our output
    flexmock(AppScaleLogger)
    AppScaleLogger.should_receive('log').and_return()

    # mock out all sleeps, as they aren't necessary for unit testing
    flexmock(time)
    time.should_receive('sleep').and_return()

    # set up some fake options so that we don't have to generate them via
    # ParseArgs
    self.options = flexmock(infrastructure='ec2', group='boogroup',
      machine='ami-ABCDEFG', instance_type='m1.large', keyname='bookey',
      table='cassandra', verbose=False, test=False, use_spot_instances=False)
    self.my_id = "12345"
    self.node_layout = NodeLayout(self.options)

    # mock out calls to EC2
    # begin by assuming that our ssh keypair doesn't exist, and thus that we
    # need to create it
    key_contents = "key contents here"
    fake_key = flexmock(name="fake_key", material=key_contents)
    fake_key.should_receive('save').with_args(os.environ['HOME']+'/.appscale').and_return(None)

    fake_ec2 = flexmock(name="fake_ec2")
    fake_ec2.should_receive('get_key_pair').with_args('bookey') \
      .and_return(None)
    fake_ec2.should_receive('create_key_pair').with_args('bookey') \
      .and_return(fake_key)

    # mock out writing the secret key
    builtins = flexmock(sys.modules['__builtin__'])
    builtins.should_call('open')  # set the fall-through

    secret_key_location = LocalState.LOCAL_APPSCALE_PATH + "bookey.secret"
    fake_secret = flexmock(name="fake_secret")
    fake_secret.should_receive('write').and_return()
    builtins.should_receive('open').with_args(secret_key_location, 'w') \
      .and_return(fake_secret)

    # also, mock out the keypair writing and chmod'ing
    ssh_key_location = LocalState.LOCAL_APPSCALE_PATH + "bookey.key"
    fake_file = flexmock(name="fake_file")
    fake_file.should_receive('write').with_args(key_contents).and_return()

    builtins.should_receive('open').with_args(ssh_key_location, 'w') \
      .and_return(fake_file)

    flexmock(os)
    os.should_receive('chmod').with_args(ssh_key_location, 0600).and_return()

    # next, assume there are no security groups up yet
    fake_ec2.should_receive('get_all_security_groups').and_return([])

    # and then assume we can create and open our security group fine
    fake_ec2.should_receive('create_security_group').with_args('boogroup',
      'AppScale security group').and_return()
    fake_ec2.should_receive('authorize_security_group').and_return()

    # next, add in mocks for run_instances
    # the first time around, let's say that no machines are running
    # the second time around, let's say that our machine is pending
    # and that it's up the third time around
    fake_pending_instance = flexmock(state='pending')
    fake_pending_reservation = flexmock(instances=fake_pending_instance)

    fake_running_instance = flexmock(state='running', key_name='bookey',
      id='i-12345678', public_dns_name='public1', private_dns_name='private1')
    fake_running_reservation = flexmock(instances=fake_running_instance)

    fake_ec2.should_receive('get_all_instances').and_return([]) \
      .and_return([fake_pending_reservation]) \
      .and_return([fake_running_reservation])

    # next, assume that our run_instances command succeeds
    fake_ec2.should_receive('run_instances').and_return()

    # finally, inject our mocked EC2
    flexmock(boto)
    boto.should_receive('connect_ec2').and_return(fake_ec2)

    # assume that ssh comes up on the third attempt
    fake_socket = flexmock(name='fake_socket')
    fake_socket.should_receive('connect').with_args(('public1',
      RemoteHelper.SSH_PORT)).and_raise(Exception).and_raise(Exception) \
      .and_return(None)
    flexmock(socket)
    socket.should_receive('socket').and_return(fake_socket)

    # throw some default mocks together for when invoking via shell succeeds
    # and when it fails
    self.fake_temp_file = flexmock(name='fake_temp_file')
    self.fake_temp_file.should_receive('seek').with_args(0).and_return()
    self.fake_temp_file.should_receive('read').and_return('boo out')
    self.fake_temp_file.should_receive('close').and_return()


    flexmock(tempfile)
    tempfile.should_receive('NamedTemporaryFile')\
      .and_return(self.fake_temp_file)

    self.success = flexmock(name='success', returncode=0)
    self.success.should_receive('wait').and_return(0)

    self.failed = flexmock(name='success', returncode=1)
    self.failed.should_receive('wait').and_return(1)

    # assume that root login isn't already enabled
    local_state = flexmock(LocalState)
    local_state.should_receive('shell') \
      .with_args(re.compile('^ssh .*root'), False, 1, stdin='ls') \
      .and_return('Please login as the ubuntu user rather than root user.')

    # and assume that we can ssh in as ubuntu to enable root login
    local_state = flexmock(LocalState)
    local_state.should_receive('shell')\
      .with_args(re.compile('^ssh .*ubuntu'),False,5)\
      .and_return()

    # also assume that we can scp over our ssh keys
    local_state.should_receive('shell')\
      .with_args(re.compile('scp .*/root/.ssh/id_'),False,5)\
      .and_return()

    local_state.should_receive('shell')\
      .with_args(re.compile('scp .*/root/.appscale/bookey.key'),False,5)\
      .and_return()
    def setUp(self):
        self.cloud_argv = [
            '--min', '1', '--max', '1', '--group', 'blargscale',
            '--infrastructure', 'ec2', '--machine', 'ami-ABCDEFG', '--zone',
            'my-zone-1b'
        ]
        self.cluster_argv = ['--ips', 'ips.yaml']
        self.function = "appscale-run-instances"

        # mock out all logging, since it clutters our output
        flexmock(AppScaleLogger)
        AppScaleLogger.should_receive('log').and_return()

        # set up phony AWS credentials for each test
        # ones that test not having them present can
        # remove them
        for credential in EucalyptusAgent.REQUIRED_EC2_CREDENTIALS:
            os.environ[credential] = "baz"
        os.environ['EC2_URL'] = "http://boo"

        # pretend that our credentials are valid.
        fake_ec2 = flexmock(name="fake_ec2")
        fake_ec2.should_receive('get_all_instances')

        # similarly, pretend that our image does exist in EC2
        # and Euca
        fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \
          .and_return()
        fake_ec2.should_receive('get_image').with_args('emi-ABCDEFG') \
          .and_return('anything')

        # Slip in mocks that assume our EBS volume exists in EC2.
        fake_ec2.should_receive('get_all_volumes').with_args(['vol-ABCDEFG']) \
          .and_return('anything')

        # Also pretend that the availability zone we want to use exists.
        fake_ec2.should_receive('get_all_zones').with_args('my-zone-1b') \
          .and_return('anything')

        # Pretend that a bad availability zone doesn't exist.
        fake_ec2.should_receive('get_all_zones').with_args('bad-zone-1b') \
          .and_raise(boto.exception.EC2ResponseError, 'baz', 'baz')

        # Pretend that we have one elastic IP allocated for use.
        fake_ec2.should_receive('get_all_addresses').with_args('GOOD.IP.ADDRESS') \
          .and_return('anything')

        # Pretend that asking for a bad elastic IP doesn't work.
        fake_ec2.should_receive('get_all_addresses').with_args('BAD.IP.ADDRESS') \
          .and_raise(boto.exception.EC2ResponseError, 'baz', 'baz')

        fake_price = flexmock(name='fake_price', price=1.00)
        fake_ec2.should_receive('get_spot_price_history').and_return(
            [fake_price])

        flexmock(boto)
        flexmock(boto.ec2)
        boto.ec2.should_receive('connect_to_region').with_args(
            'my-zone-1', aws_access_key_id='baz',
            aws_secret_access_key='baz').and_return(fake_ec2)
        boto.ec2.should_receive('connect_to_region').with_args(
            'bad-zone-1', aws_access_key_id='baz',
            aws_secret_access_key='baz').and_return(fake_ec2)
        boto.should_receive('connect_euca').and_return(fake_ec2)
    def test_terminate_in_cloud_and_succeeds(self):
        # let's say that there is a locations.yaml file, which means appscale is
        # running, so we should terminate the services on each box
        flexmock(os.path)
        os.path.should_call("exists")  # set up the fall-through
        os.path.should_receive("exists").with_args(LocalState.get_locations_yaml_location(self.keyname)).and_return(
            True
        )

        # mock out reading the locations.yaml file, and pretend that we're on
        # a virtualized cluster
        builtins = flexmock(sys.modules["__builtin__"])
        builtins.should_call("open")

        fake_yaml_file = flexmock(name="fake_file")
        fake_yaml_file.should_receive("read").and_return(yaml.dump({"infrastructure": "ec2", "group": "bazboogroup"}))
        builtins.should_receive("open").with_args(LocalState.get_locations_yaml_location(self.keyname), "r").and_return(
            fake_yaml_file
        )

        # mock out reading the json file, and pretend that we're running in a
        # two node deployment
        fake_json_file = flexmock(name="fake_file")
        fake_json_file.should_receive("read").and_return(
            json.dumps([{"public_ip": "public1", "jobs": ["shadow"]}, {"public_ip": "public2", "jobs": ["appengine"]}])
        )
        builtins.should_receive("open").with_args(LocalState.get_locations_json_location(self.keyname), "r").and_return(
            fake_json_file
        )

        # and slip in a fake secret file
        fake_secret_file = flexmock(name="fake_file")
        fake_secret_file.should_receive("read").and_return("the secret")
        builtins.should_receive("open").with_args(LocalState.get_secret_key_location(self.keyname), "r").and_return(
            fake_secret_file
        )

        # mock out talking to EC2
        fake_ec2 = flexmock(name="fake_ec2")

        # let's say that three instances are running, and that two of them are in
        # our deployment
        fake_one_running = flexmock(
            name="fake_one",
            key_name=self.keyname,
            state="running",
            id="i-ONE",
            public_dns_name="public1",
            private_dns_name="private1",
        )
        fake_two_running = flexmock(
            name="fake_two",
            key_name=self.keyname,
            state="running",
            id="i-TWO",
            public_dns_name="public2",
            private_dns_name="private2",
        )
        fake_three_running = flexmock(
            name="fake_three",
            key_name="abcdefg",
            state="running",
            id="i-THREE",
            public_dns_name="public3",
            private_dns_name="private3",
        )
        fake_reservation_running = flexmock(
            name="fake_reservation", instances=[fake_one_running, fake_two_running, fake_three_running]
        )

        fake_one_terminated = flexmock(
            name="fake_one",
            key_name=self.keyname,
            state="terminated",
            id="i-ONE",
            public_dns_name="public1",
            private_dns_name="private1",
        )
        fake_two_terminated = flexmock(
            name="fake_two",
            key_name=self.keyname,
            state="terminated",
            id="i-TWO",
            public_dns_name="public2",
            private_dns_name="private2",
        )
        fake_three_terminated = flexmock(
            name="fake_three",
            key_name="abcdefg",
            state="terminated",
            id="i-THREE",
            public_dns_name="public3",
            private_dns_name="private3",
        )
        fake_reservation_terminated = flexmock(
            name="fake_reservation", instances=[fake_one_terminated, fake_two_terminated, fake_three_terminated]
        )

        fake_ec2.should_receive("get_all_instances").and_return(fake_reservation_running).and_return(
            fake_reservation_terminated
        )

        flexmock(boto)
        boto.should_receive("connect_ec2").and_return(fake_ec2)

        # and mock out the call to kill the instances
        fake_ec2.should_receive("terminate_instances").with_args(["i-ONE", "i-TWO"]).and_return(
            [fake_one_terminated, fake_two_terminated]
        )

        # mock out the call to delete the keypair
        fake_ec2.should_receive("delete_key_pair").and_return()

        # and the call to delete the security group - let's say that we can't
        # delete the group the first time, and can the second
        fake_ec2.should_receive("delete_security_group").and_return(False).and_return(True)

        # finally, mock out removing the yaml file, json file, and secret key from
        # this machine
        flexmock(os)
        os.should_receive("remove").with_args(LocalState.get_locations_yaml_location(self.keyname)).and_return()
        os.should_receive("remove").with_args(LocalState.get_locations_json_location(self.keyname)).and_return()
        os.should_receive("remove").with_args(LocalState.get_secret_key_location(self.keyname)).and_return()

        argv = ["--keyname", self.keyname]
        options = ParseArgs(argv, self.function).args
        AppScaleTools.terminate_instances(options)
    def setUp(self):
        # mock out all logging, since it clutters our output
        flexmock(AppScaleLogger)
        AppScaleLogger.should_receive('log').and_return()

        # mock out all sleeps, as they aren't necessary for unit testing
        flexmock(time)
        time.should_receive('sleep').and_return()

        # set up some fake options so that we don't have to generate them via
        # ParseArgs
        self.options = flexmock(infrastructure='ec2',
                                group='boogroup',
                                machine='ami-ABCDEFG',
                                instance_type='m1.large',
                                keyname='bookey',
                                table='cassandra',
                                verbose=False,
                                test=False,
                                use_spot_instances=False)
        self.my_id = "12345"
        self.node_layout = NodeLayout(self.options)

        # set up phony AWS credentials for each test
        # ones that test not having them present can
        # remove them
        for credential in EucalyptusAgent.REQUIRED_EC2_CREDENTIALS:
            os.environ[credential] = "baz"
        os.environ['EC2_URL'] = "http://boo"

        # mock out calls to EC2
        # begin by assuming that our ssh keypair doesn't exist, and thus that we
        # need to create it
        key_contents = "key contents here"
        fake_key = flexmock(name="fake_key", material=key_contents)
        fake_key.should_receive('save').with_args(
            os.environ['HOME'] + '/.appscale').and_return(None)

        fake_ec2 = flexmock(name="fake_ec2")
        fake_ec2.should_receive('get_key_pair').with_args('bookey') \
          .and_return(None)
        fake_ec2.should_receive('create_key_pair').with_args('bookey') \
          .and_return(fake_key)

        # mock out writing the secret key
        builtins = flexmock(sys.modules['__builtin__'])
        builtins.should_call('open')  # set the fall-through

        secret_key_location = LocalState.LOCAL_APPSCALE_PATH + "bookey.secret"
        fake_secret = flexmock(name="fake_secret")
        fake_secret.should_receive('write').and_return()
        builtins.should_receive('open').with_args(secret_key_location, 'w') \
          .and_return(fake_secret)

        # also, mock out the keypair writing and chmod'ing
        ssh_key_location = LocalState.LOCAL_APPSCALE_PATH + "bookey.key"
        fake_file = flexmock(name="fake_file")
        fake_file.should_receive('write').with_args(key_contents).and_return()

        builtins.should_receive('open').with_args(ssh_key_location, 'w') \
          .and_return(fake_file)

        flexmock(os)
        os.should_receive('chmod').with_args(ssh_key_location,
                                             0600).and_return()

        # next, assume there are no security groups up yet
        fake_ec2.should_receive('get_all_security_groups').and_return([])

        # and then assume we can create and open our security group fine
        fake_ec2.should_receive('create_security_group').with_args(
            'boogroup', 'AppScale security group').and_return()
        fake_ec2.should_receive('authorize_security_group').and_return()

        # next, add in mocks for run_instances
        # the first time around, let's say that no machines are running
        # the second time around, let's say that our machine is pending
        # and that it's up the third time around
        fake_pending_instance = flexmock(state='pending')
        fake_pending_reservation = flexmock(instances=fake_pending_instance)

        fake_running_instance = flexmock(state='running',
                                         key_name='bookey',
                                         id='i-12345678',
                                         public_dns_name='public1',
                                         private_dns_name='private1')
        fake_running_reservation = flexmock(instances=fake_running_instance)

        fake_ec2.should_receive('get_all_instances').and_return([]) \
          .and_return([fake_pending_reservation]) \
          .and_return([fake_running_reservation])

        # next, assume that our run_instances command succeeds
        fake_ec2.should_receive('run_instances').and_return()

        # finally, inject our mocked EC2
        flexmock(boto)
        boto.should_receive('connect_ec2').and_return(fake_ec2)

        # assume that ssh comes up on the third attempt
        fake_socket = flexmock(name='fake_socket')
        fake_socket.should_receive('connect').with_args(('public1',
          RemoteHelper.SSH_PORT)).and_raise(Exception).and_raise(Exception) \
          .and_return(None)
        flexmock(socket)
        socket.should_receive('socket').and_return(fake_socket)

        # throw some default mocks together for when invoking via shell succeeds
        # and when it fails
        self.fake_temp_file = flexmock(name='fake_temp_file')
        self.fake_temp_file.should_receive('seek').with_args(0).and_return()
        self.fake_temp_file.should_receive('read').and_return('boo out')
        self.fake_temp_file.should_receive('close').and_return()

        flexmock(tempfile)
        tempfile.should_receive('NamedTemporaryFile')\
          .and_return(self.fake_temp_file)

        self.success = flexmock(name='success', returncode=0)
        self.success.should_receive('wait').and_return(0)

        self.failed = flexmock(name='success', returncode=1)
        self.failed.should_receive('wait').and_return(1)

        # assume that root login isn't already enabled
        local_state = flexmock(LocalState)
        local_state.should_receive('shell') \
          .with_args(re.compile('^ssh .*root'), False, 1, stdin='ls') \
          .and_return('Please login as the ubuntu user rather than root user.')

        # and assume that we can ssh in as ubuntu to enable root login
        local_state = flexmock(LocalState)
        local_state.should_receive('shell')\
          .with_args(re.compile('^ssh .*ubuntu'),False,5)\
          .and_return()

        # also assume that we can scp over our ssh keys
        local_state.should_receive('shell')\
          .with_args(re.compile('scp .*/root/.ssh/id_'),False,5)\
          .and_return()

        local_state.should_receive('shell')\
          .with_args(re.compile('scp .*/root/.appscale/bookey.key'),False,5)\
          .and_return()
    def setup_ec2_mocks(self):
        # first, pretend that our image does exist in EC2
        self.fake_ec2.should_receive("get_image").with_args("ami-ABCDEFG").and_return()

        # Also pretend that the availability zone we want to use exists.
        self.fake_ec2.should_receive("get_all_zones").with_args("my-zone-1b").and_return("anything")

        # next, assume that our keypair doesn't exist yet
        self.fake_ec2.should_receive("get_key_pair").with_args(self.keyname).and_return(None)

        # next, assume there are no security groups up at first, but then it gets
        # created.
        udp_rule = flexmock(from_port=1, to_port=65535, ip_protocol="udp")
        tcp_rule = flexmock(from_port=1, to_port=65535, ip_protocol="tcp")
        icmp_rule = flexmock(from_port=-1, to_port=-1, ip_protocol="icmp")
        group = flexmock(name=self.group, rules=[tcp_rule, udp_rule, icmp_rule])
        self.fake_ec2.should_receive("get_all_security_groups").with_args().and_return([])
        self.fake_ec2.should_receive("get_all_security_groups").with_args(self.group).and_return([group])

        # mock out creating the keypair
        fake_key = flexmock(name="fake_key", material="baz")
        self.local_state.should_receive("write_key_file").with_args(
            re.compile(self.keyname), fake_key.material
        ).and_return()
        self.fake_ec2.should_receive("create_key_pair").with_args(self.keyname).and_return(fake_key)

        # and the same for the security group
        self.fake_ec2.should_receive("create_security_group").with_args(self.group, str).and_return()
        self.fake_ec2.should_receive("authorize_security_group").with_args(
            self.group, from_port=1, to_port=65535, ip_protocol="udp", cidr_ip="0.0.0.0/0"
        )
        self.fake_ec2.should_receive("authorize_security_group").with_args(
            self.group, from_port=1, to_port=65535, ip_protocol="tcp", cidr_ip="0.0.0.0/0"
        )
        self.fake_ec2.should_receive("authorize_security_group").with_args(
            self.group, from_port=-1, to_port=-1, ip_protocol="icmp", cidr_ip="0.0.0.0/0"
        )

        # assume that there are no instances running initially, and that the
        # instance we spawn starts as pending, then becomes running
        no_instances = flexmock(name="no_instances", instances=[])

        pending_instance = flexmock(name="pending_instance", state="pending", key_name=self.keyname, id="i-ABCDEFG")
        pending_reservation = flexmock(name="pending_reservation", instances=[pending_instance])

        running_instance = flexmock(
            name="running_instance",
            state="running",
            key_name=self.keyname,
            id="i-ABCDEFG",
            public_dns_name="public1",
            private_dns_name="private1",
        )
        running_reservation = flexmock(name="running_reservation", instances=[running_instance])

        self.fake_ec2.should_receive("get_all_instances").and_return(no_instances).and_return(
            pending_reservation
        ).and_return(running_reservation)

        # finally, inject the mocked EC2 in
        flexmock(boto)
        boto.should_receive("connect_ec2").and_return(self.fake_ec2)
Пример #24
0
    def setUp(self):
        # mock out printing to stdout
        builtins = flexmock(sys.modules['__builtin__'])
        builtins.should_receive('print').and_return()

        # next, pretend our ec2 credentials are properly set
        for credential in EC2Agent.REQUIRED_CREDENTIALS:
            os.environ[credential] = "baz"

        # finally, pretend that our ec2 image to use exists
        fake_ec2 = flexmock(name="fake_ec2")
        fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \
          .and_return()
        flexmock(boto)
        boto.should_receive('connect_ec2').with_args(
            'baz', 'baz').and_return(fake_ec2)

        # do argument parsing here, since the below tests do it the
        # same way every time
        argv = [
            "--min", "1", "--max", "1", "--infrastructure", "ec2", "--machine",
            "ami-ABCDEFG", "--group", "blargscale"
        ]
        function = "appscale-run-instances"
        self.options = ParseArgs(argv, function).args
        self.my_id = "12345"

        self.expected = {
            "EC2_ACCESS_KEY": None,
            "EC2_SECRET_KEY": None,
            "EC2_URL": None,
            "admin_pass": None,
            "admin_user": None,
            "appengine": 1,
            "autoscale": True,
            "min": 1,
            "max": 1,
            "infrastructure": "ec2",
            "machine": "ami-ABCDEFG",
            "force": False,
            "group": "blargscale",
            "instance_type": "m1.large",
            "ips": None,
            "ips_layout": None,
            "keyname": "appscale",
            "login_host": None,
            "max_spot_price": None,
            "replication": None,
            "scp": None,
            "table": "cassandra",
            "test": False,
            "use_spot_instances": False,
            "verbose": False,
            "version": False
        }

        # finally, construct a http payload for mocking that the below
        # tests can use
        self.payload = "?boo=baz&min=1&max=1&infrastructure=ec2" + \
          "&machine=ami-ABCDEFG&force=False&group=appscale" + \
          "&instance_type=m1.large&ips=None&keyname=appscale&n=None" + \
          "table=cassandra&test=False&version=False"