'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.'

def upsert_load_balancer(self):

    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.AwsPythonContractBuilder(self.aws_observer)
    builder.new_clause_builder('Load    Balancer    Added', retryable_for_secs=30).call_method(self.elb_client.describe_load_balancers, LoadBalancerNames=[self.__use_lb_name]).EXPECT(ov_factory.value_list_path_contains('LoadBalancerDescriptions', jp.LIST_MATCHES([jp.DICT_MATCHES({'HealthCheck': jp.DICT_MATCHES({key: jp.EQUIVALENT(value) for (key, value) in health_check.items()}), 'AvailabilityZones': jp.LIST_MATCHES([jp.STR_SUBSTR(zone) for zone in avail_zones]), 'ListenerDescriptions/Listener': jp.DICT_MATCHES({key: jp.EQUIVALENT(value) for (key, value) in listener['Listener'].items()})})])))
    return st.OperationContract(self.new_post_operation(title='upsert_amazon_load_balancer', data=payload, path='ops'), contract=builder.build())
