def register_load_balancer_instances(self): """Creates test registering the first two instances with a load balancer. Assumes that create_instances test has been run to add the instances. Note by design these were in two different zones but same region as required by the API this is testing. Assumes that upsert_load_balancer has been run to create the load balancer itself. Returns: st.OperationContract """ # pylint: disable=bad-continuation payload = self.agent.type_to_payload( 'registerInstancesWithGoogleLoadBalancerDescription', { 'loadBalancerNames': [self.__use_lb_name], 'instanceIds': self.use_instance_names[:2], 'region': self.bindings['TEST_GCE_REGION'], 'credentials': self.bindings['SPINNAKER_GOOGLE_ACCOUNT'] }) builder = gcp.GcpContractBuilder(self.gcp_observer) (builder.new_clause_builder('Instances in Target Pool', retryable_for_secs=15). list_resource('targetPools').contains_pred_list([ jp.PathContainsPredicate('name', self.__use_lb_tp_name), jp.PathContainsPredicate('region', self.bindings['TEST_GCE_REGION']), jp.PathElementsContainPredicate('instances', self.use_instance_names[0]), jp.PathElementsContainPredicate('instances', self.use_instance_names[1]) ]).excludes_pred_list([ jp.PathContainsPredicate('name', self.__use_lb_tp_name), jp.PathElementsContainPredicate('instances', self.use_instance_names[2]) ])) return st.OperationContract( self.new_post_operation(title='register_load_balancer_instances', data=payload, path='ops'), contract=builder.build())
def deregister_load_balancer_instances(self): """Creates a test unregistering instances from load balancer. Returns: st.OperationContract """ # pylint: disable=bad-continuation payload = self.agent.type_to_payload( 'deregisterInstancesFromGoogleLoadBalancerDescription', { 'loadBalancerNames': [self.__use_lb_name], 'instanceIds': self.use_instance_names[:2], 'region': self.bindings['TEST_GCE_REGION'], 'credentials': self.bindings['GCE_CREDENTIALS'] }) # NOTE(ewiseblatt): 20150530 # This displays an error that 'instances' field doesnt exist. # That's because it was removed because all the instances are gone. # I dont have a way to express that the field itself is optional, # just the record. Leaving it as is because displaying this type of # error is usually helpful for development. builder = gcp.GceContractBuilder(self.gce_observer) (builder.new_clause_builder( 'Instances not in Target Pool', retryable_for_secs=5).list_resources( 'target-pools', extra_args=[ '--region', self.bindings['TEST_GCE_REGION'] ]).excludes_pred_list([ jp.PathContainsPredicate('name', self.__use_lb_tp_name), jp.PathElementsContainPredicate( 'instances', self.use_instance_names[0]), jp.PathElementsContainPredicate('instances', self.use_instance_names[1]) ])) return st.OperationContract(self.new_post_operation( title='deregister_load_balancer_instances', data=payload, path='ops'), contract=builder.build())
def upsert_load_balancer(self): """Creates OperationContract for upsertLoadBalancer. Calls Spinnaker's upsertLoadBalancer with a configuration, then verifies that the expected resources and configurations are visible on AWS. See the contract builder for more info on what the expectations are. """ detail_raw_name = 'katotestlb' + self.test_id self.__use_lb_name = detail_raw_name bindings = self.bindings region = bindings['TEST_AWS_REGION'] avail_zones = [region + 'a', region + 'b'] listener = { 'Listener': { 'InstancePort':7001, 'LoadBalancerPort':80 } } health_check = { 'HealthyThreshold':8, 'UnhealthyThreshold':3, 'Interval':123, 'Timeout':12, 'Target':'HTTP:%d/healthcheck' % listener['Listener']['InstancePort'] } payload = self.agent.type_to_payload( 'upsertAmazonLoadBalancerDescription', { 'credentials': bindings['SPINNAKER_AWS_ACCOUNT'], 'clusterName': bindings['TEST_APP'], 'name': detail_raw_name, 'availabilityZones': {region: avail_zones}, 'listeners': [{ 'internalProtocol': 'HTTP', 'internalPort': listener['Listener']['InstancePort'], 'externalProtocol': 'HTTP', 'externalPort': listener['Listener']['LoadBalancerPort'] }], 'healthCheck': health_check['Target'], 'healthTimeout': health_check['Timeout'], 'healthInterval': health_check['Interval'], 'healthyThreshold': health_check['HealthyThreshold'], 'unhealthyThreshold': health_check['UnhealthyThreshold'] }) builder = aws.AwsContractBuilder(self.aws_observer) (builder.new_clause_builder('Load Balancer Added', retryable_for_secs=30) .collect_resources( aws_module='elb', command='describe-load-balancers', args=['--load-balancer-names', self.__use_lb_name]) .contains_pred_list([ jp.PathContainsPredicate( 'LoadBalancerDescriptions/HealthCheck', health_check), jp.PathPredicate( 'LoadBalancerDescriptions/AvailabilityZones{0}'.format( jp.DONT_ENUMERATE_TERMINAL), jp.LIST_SIMILAR(avail_zones)), jp.PathElementsContainPredicate( 'LoadBalancerDescriptions/ListenerDescriptions', listener) ]) ) return st.OperationContract( self.new_post_operation( title='upsert_amazon_load_balancer', data=payload, path='ops'), contract=builder.build())
def create_http_load_balancer(self): logical_http_lb_name = 'katotest-httplb-' + self.test_id self.__use_http_lb_name = logical_http_lb_name # TODO(ewiseblatt): 20150530 # This needs to be abbreviated to hc. self.__use_http_lb_hc_name = logical_http_lb_name + '-health-check' # TODO(ewiseblatt): 20150530 # This needs to be abbreviated to bs. self.__use_http_lb_bs_name = logical_http_lb_name + '-backend-service' self.__use_http_lb_fr_name = logical_http_lb_name # TODO(ewiseblatt): 20150530 # This should be abbreviated (um?). self.__use_http_lb_map_name = logical_http_lb_name + '-url-map' # TODO(ewiseblatt): 20150530 # This should be abbreviated (px)?. self.__use_http_lb_proxy_name = logical_http_lb_name + '-target-http-proxy' interval = 231 healthy = 8 unhealthy = 9 timeout = 65 path = '/hello/world' # TODO(ewiseblatt): 20150530 # This field might be broken. 123-456 still resolves to 80-80 # Changing it for now so the test passes. port_range = "80-80" # TODO(ewiseblatt): 20150530 # Specify explicit backends? health_check = { 'checkIntervalSec': interval, 'healthyThreshold': healthy, 'unhealthyThreshold': unhealthy, 'timeoutSec': timeout, 'requestPath': path } # pylint: disable=bad-continuation payload = self.agent.type_to_payload( 'createGoogleHttpLoadBalancerDescription', { 'healthCheck': health_check, 'portRange': port_range, 'loadBalancerName': logical_http_lb_name, 'credentials': self.bindings['SPINNAKER_GOOGLE_ACCOUNT'] }) builder = gcp.GcpContractBuilder(self.gcp_observer) (builder.new_clause_builder('Http Health Check Added').list_resource( 'httpHealthChecks').contains_pred_list([ jp.PathContainsPredicate('name', self.__use_http_lb_hc_name), jp.PathContainsPredicate(None, health_check) ])) (builder.new_clause_builder( 'Global Forwarding Rule Added', retryable_for_secs=15).list_resource( 'globalForwardingRules').contains_pred_list([ jp.PathContainsPredicate('name', self.__use_http_lb_fr_name), jp.PathContainsPredicate('portRange', port_range) ])) (builder.new_clause_builder('Backend Service Added').list_resource( 'backendServices').contains_pred_list([ jp.PathContainsPredicate('name', self.__use_http_lb_bs_name), jp.PathElementsContainPredicate('healthChecks', self.__use_http_lb_hc_name) ])) (builder.new_clause_builder('Url Map Added').list_resource( 'urlMaps').contains_pred_list([ jp.PathContainsPredicate('name', self.__use_http_lb_map_name), jp.PathContainsPredicate('defaultService', self.__use_http_lb_bs_name) ])) (builder.new_clause_builder('Target Http Proxy Added').list_resource( 'targetHttpProxies').contains_pred_list([ jp.PathContainsPredicate('name', self.__use_http_lb_proxy_name), jp.PathContainsPredicate('urlMap', self.__use_http_lb_map_name) ])) return st.OperationContract(self.new_post_operation( title='create_http_load_balancer', data=payload, path='ops'), contract=builder.build())
def upsert_load_balancer(self, use_vpc): """Creates OperationContract for upsertLoadBalancer. Calls Spinnaker's upsertLoadBalancer with a configuration, then verifies that the expected resources and configurations are visible on AWS. See the contract builder for more info on what the expectations are. Args: use_vpc: [bool] if True configure a VPC otherwise dont. """ bindings = self.bindings # We're assuming that the given region has 'A' and 'B' availability # zones. This seems conservative but might be brittle since we permit # any region. region = bindings['TEST_AWS_REGION'] avail_zones = [region + 'a', region + 'b'] load_balancer_name = self.__lb_name if use_vpc: # TODO(ewiseblatt): 20160301 # We're hardcoding the VPC here, but not sure which we really want. # I think this comes from the spinnaker.io installation instructions. # What's interesting about this is that it is a 10.* CidrBlock, # as opposed to the others, which are public IPs. All this is sensitive # as to where the TEST_AWS_VPC_ID came from so this is going to be # brittle. Ideally we only need to know the vpc_id and can figure the # rest out based on what we have available. subnet_type = 'internal (defaultvpc)' vpc_id = bindings['TEST_AWS_VPC_ID'] # Not really sure how to determine this value in general. security_groups = ['default'] # The resulting load balancer will only be available in the zone of # the subnet we are using. We'll figure that out by looking up the # subnet we want. subnet_details = self.aws_observer.get_resource_list( root_key='Subnets', aws_command='describe-subnets', aws_module='ec2', args=['--filters', 'Name=vpc-id,Values={vpc_id}' ',Name=tag:Name,Values=defaultvpc.internal.{region}' .format(vpc_id=vpc_id, region=region)]) try: expect_avail_zones = [subnet_details[0]['AvailabilityZone']] except KeyError: raise ValueError('vpc_id={0} appears to be unknown'.format(vpc_id)) else: subnet_type = "" vpc_id = None security_groups = None expect_avail_zones = avail_zones # This will be a second load balancer not used in other tests. # Decorate the name so as not to confuse it. load_balancer_name += '-pub' listener = { 'Listener': { 'InstancePort':80, 'LoadBalancerPort':80 } } health_check = { 'HealthyThreshold': 8, 'UnhealthyThreshold': 3, 'Interval': 12, 'Timeout': 6, 'Target':'HTTP:%d/' % listener['Listener']['InstancePort'] } payload = self.agent.make_json_payload_from_kwargs( job=[{ 'type': 'upsertLoadBalancer', 'cloudProvider': 'aws', # 'loadBalancerName': load_balancer_name, 'credentials': bindings['AWS_CREDENTIALS'], 'name': load_balancer_name, 'stack': bindings['TEST_STACK'], 'detail': self.__lb_detail, 'region': bindings['TEST_AWS_REGION'], 'availabilityZones': {region: avail_zones}, 'regionZones': avail_zones, 'listeners': [{ 'internalProtocol': 'HTTP', 'internalPort': listener['Listener']['InstancePort'], 'externalProtocol': 'HTTP', 'externalPort': listener['Listener']['LoadBalancerPort'] }], 'healthCheck': health_check['Target'], 'healthCheckProtocol': 'HTTP', 'healthCheckPort': listener['Listener']['LoadBalancerPort'], 'healthCheckPath': '/', 'healthTimeout': health_check['Timeout'], 'healthInterval': health_check['Interval'], 'healthyThreshold': health_check['HealthyThreshold'], 'unhealthyThreshold': health_check['UnhealthyThreshold'], 'user': '******', 'usePreferredZones': True, 'vpcId': vpc_id, 'subnetType': subnet_type, # If I set security group to this then I get an error it is missing. # bindings['TEST_AWS_SECURITY_GROUP_ID']], 'securityGroups': security_groups }], description='Create Load Balancer: ' + load_balancer_name, application=self.TEST_APP) builder = aws.AwsContractBuilder(self.aws_observer) (builder.new_clause_builder('Load Balancer Added', retryable_for_secs=10) .collect_resources( aws_module='elb', command='describe-load-balancers', args=['--load-balancer-names', load_balancer_name]) .contains_pred_list([ jp.PathContainsPredicate( 'LoadBalancerDescriptions/HealthCheck', health_check), jp.PathPredicate( 'LoadBalancerDescriptions/AvailabilityZones{0}'.format( jp.DONT_ENUMERATE_TERMINAL), jp.LIST_SIMILAR(expect_avail_zones)), jp.PathElementsContainPredicate( 'LoadBalancerDescriptions/ListenerDescriptions', listener) ]) ) title_decorator = '_with_vpc' if use_vpc else '_without_vpc' return st.OperationContract( self.new_post_operation( title='upsert_load_balancer' + title_decorator, data=payload, path='tasks'), contract=builder.build())