def create_server_group(self): group_name = frigga.Naming.server_group( app=self.TEST_APP, stack=self.bindings['TEST_STACK'], version='v000') payload = self.agent.make_json_payload_from_kwargs( job=[{ 'application': self.TEST_APP, 'stack': self.TEST_STACK, 'credentials': self.bindings['SPINNAKER_APPENGINE_ACCOUNT'], 'gitCredentialType': 'NONE', 'repositoryUrl': self.__repo_url, 'applicationDirectoryRoot': self.__app_directory_root, 'configFiles': [self.__app_yaml], 'branch': self.__branch, 'type': 'createServerGroup', 'cloudProvider': 'appengine', 'region': 'us-central' }], description='Create Server Group in ' + group_name, application=self.TEST_APP) builder = gcp.GcpContractBuilder(self.appengine_observer) (builder.new_clause_builder('Version Added', retryable_for_secs=30).inspect_resource( 'apps.services.versions', group_name, no_resource_ok=False, appsId=self.__gcp_project, servicesId=self.__lb_name)) return st.OperationContract(self.new_post_operation( title='create_server_group', data=payload, path='tasks'), contract=builder.build())
def upsert_full_load_balancer(self): """Upserts L7 LB with full hostRules, pathMatchers, etc. Calls the upsertLoadBalancer operation with a payload, then verifies that the expected resources are visible on GCP. """ hc = copy.deepcopy(self.__proto_hc) hc["requestPath"] = "/" hc["port"] = 80 upsert = copy.deepcopy(self.__proto_upsert) self._set_all_hcs(upsert, hc) payload = self.agent.make_json_payload_from_kwargs( job=[upsert], description="Upsert L7 Load Balancer: " + self.__lb_name, application=self.TEST_APP, ) contract_builder = gcp.GcpContractBuilder(self.gcp_observer) self._add_contract_clauses(contract_builder, upsert) return st.OperationContract( self.new_post_operation( title="upsert full http lb", data=payload, path="tasks" ), contract=contract_builder.build(), )
def test_inspect_not_found_ok(self): context = ExecutionContext() response = Mock() response.status = 404 response.reason = 'Not Found' default_variables = {'project': 'PROJECT'} service = MyFakeGcpService([HttpError(response, 'Not Found')]) agent = TestGcpAgent.make_test_agent( service=service, default_variables=default_variables) contract_builder = gt.GcpContractBuilder(agent) c1 = contract_builder.new_clause_builder('TITLE') verifier = c1.inspect_resource('regions', resource_id='us-central1-f') verifier.EXPECT( ov_factory.error_list_contains( gt.HttpErrorPredicate(http_code=404))) self.assertTrue( isinstance(verifier, jc.ValueObservationVerifierBuilder)) contract = contract_builder.build() verification_result = contract.verify(context) self.assertTrue( verification_result, JsonSnapshotHelper.ValueToEncodedJson(verification_result)) self.assertEquals({ 'project': 'PROJECT', 'region': 'us-central1-f' }, agent.service.last_get_args)
def delete_load_balancer(self): bindings = self.bindings payload = self.agent.make_json_payload_from_kwargs( job=[{ 'type': 'deleteLoadBalancer', 'cloudProvider': 'appengine', 'loadBalancerName': self.__lb_name, 'account': bindings['SPINNAKER_APPENGINE_ACCOUNT'], 'credentials': bindings['SPINNAKER_APPENGINE_ACCOUNT'], 'user': '******' }], description='Delete Load Balancer: {0} in {1}'.format( self.__lb_name, bindings['SPINNAKER_APPENGINE_ACCOUNT']), application=self.TEST_APP) builder = gcp.GcpContractBuilder(self.appengine_observer) (builder.new_clause_builder('Service Deleted', retryable_for_secs=30) .inspect_resource('apps.services', self.__lb_name, appsId=self.__gcp_project) .EXPECT( ov_factory.error_list_contains(gcp.HttpErrorPredicate(http_code=404)))) return st.OperationContract( self.new_post_operation( title='delete_load_balancer', data=payload, path='tasks'), contract=builder.build())
def test_inspect_indirect(self): context = ExecutionContext(test_id='TESTID', test_project='PROJECT') default_variables = { 'project': lambda x: x.get('test_project', 'UNKNOWN') } service = MyFakeGcpService(['Hello, World']) agent = TestGcpAgent.make_test_agent( service=service, default_variables=default_variables) contract_builder = gt.GcpContractBuilder(agent) c1 = contract_builder.new_clause_builder('TITLE') verifier = c1.inspect_resource('regions', resource_id=lambda x: x['test_id']) verifier.EXPECT( ov_factory.value_list_contains(jp.STR_EQ('Hello, World'))) self.assertTrue( isinstance(verifier, jc.ValueObservationVerifierBuilder)) contract = contract_builder.build() verification_result = contract.verify(context) self.assertTrue( verification_result, JsonSnapshotHelper.ValueToEncodedJson(verification_result)) self.assertEquals({ 'project': 'PROJECT', 'region': 'TESTID' }, agent.service.last_get_args)
def delete_load_balancer(self): job = [{ "loadBalancerName": self.__lb_name, "networkLoadBalancerName": self.__lb_name, "region": self.TEST_REGION, "type": "deleteLoadBalancer", "regions": [self.TEST_REGION], "credentials": self.bindings['SPINNAKER_GOOGLE_ACCOUNT'], "cloudProvider": "gce", "user": "******" }] builder = gcp.GcpContractBuilder(self.gcp_observer) (builder.new_clause_builder( 'Load Balancer Created', retryable_for_secs=30).list_resource('forwardingRules').EXPECT( ov_factory.value_list_path_excludes( 'name', jp.STR_SUBSTR(self.__lb_name)))) payload = self.agent.make_json_payload_from_kwargs( job=job, description=self.__mig_title + ' Test - delete load balancer', application=self.TEST_APP) return st.OperationContract(self.new_post_operation( title='delete_load_balancer', data=payload, path=self.__path), contract=builder.build())
def delete_load_balancer(self): bindings = self.bindings payload = self.agent.make_json_payload_from_kwargs( job=[{ 'type': 'deleteLoadBalancer', 'cloudProvider': 'gce', 'loadBalancerName': self.__full_lb_name, 'region': bindings['TEST_GCE_REGION'], 'regions': [bindings['TEST_GCE_REGION']], 'credentials': bindings['SPINNAKER_GOOGLE_ACCOUNT'], 'user': '******' }], description='Delete Load Balancer: {0} in {1}:{2}'.format( self.__full_lb_name, bindings['SPINNAKER_GOOGLE_ACCOUNT'], bindings['TEST_GCE_REGION']), application=self.TEST_APP) builder = gcp.GcpContractBuilder(self.gcp_observer) (builder.new_clause_builder( 'Health Check Removed', retryable_for_secs=30).list_resource( 'httpHealthChecks').excludes_path_value( 'name', self.__full_lb_name + '-hc')) return st.OperationContract(self.new_post_operation( title='delete_load_balancer', data=payload, path=('applications/{app}/tasks').format(app=self.TEST_APP)), contract=builder.build())
def delete_security_group(self): """Deletes a security group.""" bindings = self.bindings sec_group_payload = self.agent.make_json_payload_from_kwargs( job=[ { "cloudProvider": "gce", "credentials": bindings["SPINNAKER_GOOGLE_ACCOUNT"], "regions": ["global"], "securityGroupName": self.__lb_name + "-rule", "type": "deleteSecurityGroup", "user": "******", } ], description="Delete a Security Group.", application=self.TEST_APP, ) builder = gcp.GcpContractBuilder(self.gcp_observer) ( builder.new_clause_builder("Security Group Deleted", retryable_for_secs=30) .list_resource("firewalls") .EXPECT( ov_factory.value_list_path_excludes( "name", jp.STR_SUBSTR(self.__lb_name + "-rule") ) ) ) return st.OperationContract( self.new_post_operation( title="delete security group", data=sec_group_payload, path="tasks" ), contract=builder.build(), )
def delete_load_balancer(self): # pylint: disable=bad-continuation payload = self.agent.type_to_payload( 'deleteGoogleLoadBalancerDescription', { 'region': self.bindings['TEST_GCE_REGION'], 'credentials': self.bindings['SPINNAKER_GOOGLE_ACCOUNT'], 'loadBalancerName': self.__use_lb_name }) builder = gcp.GcpContractBuilder(self.gcp_observer) (builder.new_clause_builder('Health Check Removed').list_resource( 'httpHealthChecks').EXPECT( ov_factory.value_list_path_excludes( 'name', jp.STR_SUBSTR(self.__use_lb_hc_name)))) (builder.new_clause_builder('Target Pool Removed').list_resource( 'targetPools').EXPECT( ov_factory.value_list_path_excludes( 'name', jp.STR_SUBSTR(self.__use_lb_tp_name)))) (builder.new_clause_builder('Forwarding Rule Removed').list_resource( 'forwardingRules').EXPECT( ov_factory.value_list_path_excludes( 'name', jp.STR_SUBSTR(self.__use_lb_name)))) return st.OperationContract(self.new_post_operation( title='delete_load_balancer', data=payload, path='ops'), contract=builder.build())
def test_empty_builder(self): context = ExecutionContext() agent = self.testing_agent contract_builder = gt.GcpContractBuilder(agent) contract = contract_builder.build() results = contract.verify(context) self.assertTrue(results)
def upsert_google_server_group_tags(self): # pylint: disable=bad-continuation server_group_name = 'katotest-server-group' payload = self.agent.type_to_payload( 'upsertGoogleServerGroupTagsDescription', { 'credentials': self.bindings['SPINNAKER_GOOGLE_ACCOUNT'], 'zone': self.bindings['TEST_GCE_ZONE'], 'serverGroupName': 'katotest-server-group', 'tags': ['test-tag-1', 'test-tag-2'] }) builder = gcp.GcpContractBuilder(self.gcp_observer) (builder.new_clause_builder( 'Server Group Tags Added').inspect_resource( 'instanceGroupManagers', server_group_name).EXPECT( ov_factory.value_list_contains( jp.DICT_MATCHES({ 'name': jp.STR_SUBSTR(server_group_name), jp.build_path('tags', 'items'): jp.LIST_MATCHES(['test-tag-1', 'test-tag-2']) })))) return st.OperationContract(self.new_post_operation( title='upsert_server_group_tags', data=payload, path='ops'), contract=builder.build())
def delete_http_load_balancer(self): # pylint: disable=bad-continuation payload = self.agent.type_to_payload( 'deleteGoogleHttpLoadBalancerDescription', { 'loadBalancerName': self.__use_http_lb_name, 'credentials': self.bindings['SPINNAKER_GOOGLE_ACCOUNT'] }) builder = gcp.GcpContractBuilder(self.gcp_observer) (builder.new_clause_builder('Health Check Removed').list_resource( 'httpHealthChecks').EXPECT( ov_factory.value_list_path_excludes( 'name', jp.STR_SUBSTR(self.__use_http_lb_hc_name)))) (builder.new_clause_builder('Global Forwarding Rules Removed'). list_resource('globalForwardingRules').EXPECT( ov_factory.value_list_path_excludes( 'name', jp.STR_SUBSTR(self.__use_http_lb_fr_name)))) (builder.new_clause_builder('Backend Service Removed').list_resource( 'backendServices').EXPECT( ov_factory.value_list_path_excludes( 'name', jp.STR_SUBSTR(self.__use_http_lb_bs_name)))) (builder.new_clause_builder('Url Map Removed').list_resource( 'urlMaps').EXPECT( ov_factory.value_list_path_excludes( 'name', jp.STR_SUBSTR(self.__use_http_lb_map_name)))) (builder.new_clause_builder('Target Http Proxy Removed').list_resource( 'targetHttpProxies').EXPECT( ov_factory.value_list_path_excludes( 'name', jp.STR_SUBSTR(self.__use_http_lb_proxy_name)))) return st.OperationContract(self.new_post_operation( title='delete_http_load_balancer', data=payload, path='ops'), contract=builder.build())
def delete_http_load_balancer(self): '''Deletes the L7 LB. ''' bindings = self.bindings delete = copy.deepcopy(self.__proto_delete) payload = self.agent.make_json_payload_from_kwargs( job=[delete], description='Delete L7 Load Balancer: {0} in {1}:{2}'.format( self.__lb_name, bindings['SPINNAKER_GOOGLE_ACCOUNT'], bindings['TEST_GCE_REGION'], ), application=self.TEST_APP) contract_builder = gcp.GcpContractBuilder(self.gcp_observer) (contract_builder.new_clause_builder( 'Health Check Removed', retryable_for_secs=30).list_resource('httpHealthChecks').EXPECT( ov_factory.value_list_path_excludes( 'name', jp.STR_SUBSTR(self.__proto_hc['name'])))) (contract_builder.new_clause_builder( 'Url Map Removed', retryable_for_secs=30).list_resource('urlMaps').EXPECT( ov_factory.value_list_path_excludes( 'name', jp.STR_SUBSTR(self.__lb_name)))) (contract_builder.new_clause_builder( 'Forwarding Rule Removed', retryable_for_secs=30).list_resource( 'globalForwardingRules').EXPECT( ov_factory.value_list_path_excludes( 'name', jp.STR_SUBSTR(self.__lb_name)))) return st.OperationContract(self.new_post_operation( title='delete_http_load_balancer', data=payload, path='tasks'), contract=contract_builder.build())
def delete_security_group(self): '''Deletes a security group. ''' bindings = self.bindings sec_group_payload = self.agent.make_json_payload_from_kwargs( job=[{ 'cloudProvider': 'gce', 'credentials': bindings['SPINNAKER_GOOGLE_ACCOUNT'], 'regions': ['global'], 'securityGroupName': self.__lb_name + '-rule', 'type': 'deleteSecurityGroup', 'user': '******' }], description='Delete a Security Group.', application=self.TEST_APP) builder = gcp.GcpContractBuilder(self.gcp_observer) (builder.new_clause_builder( 'Security Group Deleted', retryable_for_secs=30).list_resource('firewalls').EXPECT( ov_factory.value_list_path_excludes( 'name', jp.STR_SUBSTR(self.__lb_name + '-rule')))) return st.OperationContract(self.new_post_operation( title='delete security group', data=sec_group_payload, path='tasks'), contract=builder.build())
def run_deploy_upsert_load_balancer_pipeline(self): url_path = 'pipelines/{0}/{1}'.format(self.TEST_APP, self.pipeline_id) previous_group_name = frigga.Naming.server_group( app=self.TEST_APP, stack=self.TEST_STACK, version='v000') deployed_group_name = frigga.Naming.server_group( app=self.TEST_APP, stack=self.TEST_STACK, version='v001') payload = self.agent.make_json_payload_from_kwargs( type='manual', user='******') builder = gcp.GcpContractBuilder(self.appengine_observer) (builder.new_clause_builder('Service Modified', retryable_for_secs=60) .inspect_resource('apps.services', self.__lb_name, appsId=self.__gcp_project) .EXPECT( ov_factory.value_list_path_contains( jp.build_path('split', 'allocations'), jp.DICT_MATCHES({previous_group_name: jp.NUM_EQ(0.9), deployed_group_name: jp.NUM_EQ(0.1)})))) return st.OperationContract( self.new_post_operation( title='run_deploy_upsert_load_balancer_pipeline', data=payload, path=url_path), builder.build())
def enable_server_group(self): job = [{ 'cloudProvider': 'gce', 'asgName': self.__server_group_name, 'serverGroupName': self.__server_group_name, 'region': self.TEST_REGION, 'zone': self.TEST_ZONE, 'type': 'enableServerGroup', 'regions': [self.TEST_REGION], 'zones': [self.TEST_ZONE], 'credentials': self.bindings['SPINNAKER_GOOGLE_ACCOUNT'], 'user': '******' }] builder = gcp.GcpContractBuilder(self.gcp_observer) (builder.new_clause_builder( 'Server Group Enabled', retryable_for_secs=90).list_resource( 'instanceGroupManagers').contains_match({ 'baseInstanceName': jp.STR_SUBSTR(self.__server_group_name), 'targetPools': jp.LIST_MATCHES([jp.STR_SUBSTR('https')]) })) payload = self.agent.make_json_payload_from_kwargs( job=job, description='Server Group Test - enable server group', application=self.TEST_APP) return st.OperationContract(self.new_post_operation( title='enable_server_group', data=payload, path=self.__path), contract=builder.build())
def destroy_server_group(self, version): serverGroupName = '%s-%s' % (self.__cluster_name, version) job = [{ 'cloudProvider': 'gce', 'asgName': serverGroupName, 'serverGroupName': serverGroupName, 'region': self.TEST_REGION, 'zone': self.TEST_ZONE, 'type': 'destroyServerGroup', 'regions': [self.TEST_REGION], 'zones': [self.TEST_ZONE], 'credentials': self.bindings['SPINNAKER_GOOGLE_ACCOUNT'], 'user': '******' }] job[0].update(self.__mig_payload_extra) builder = gcp.GcpContractBuilder(self.gcp_observer) (builder.new_clause_builder( self.__mig_title + ' Destroyed', retryable_for_secs=90).list_resource( self.__mig_manager_name, **self.__mig_manager_kwargs).EXPECT( ov_factory.value_list_path_excludes( 'baseInstanceName', jp.STR_SUBSTR(serverGroupName)))) payload = self.agent.make_json_payload_from_kwargs( job=job, description=self.__mig_title + ' Test - destroy server group', application=self.TEST_APP) return st.OperationContract(self.new_post_operation( title='destroy_server_group', data=payload, path=self.__path), contract=builder.build())
def create_server_group(self): """Creates OperationContract for createServerGroup. To verify the operation, we just check that Managed Instance Group for the server was created. """ bindings = self.bindings # Spinnaker determines the group name created, # which will be the following: group_name = '{app}-{stack}-v000'.format(app=self.TEST_APP, stack=bindings['TEST_STACK']) payload = self.agent.make_json_payload_from_kwargs( job=[{ 'cloudProvider': 'gce', 'application': self.TEST_APP, 'credentials': bindings['SPINNAKER_GOOGLE_ACCOUNT'], 'strategy': '', 'capacity': { 'min': 2, 'max': 2, 'desired': 2 }, 'targetSize': 2, 'image': bindings['TEST_GCE_IMAGE_NAME'], 'zone': bindings['TEST_GCE_ZONE'], 'stack': bindings['TEST_STACK'], 'instanceType': 'f1-micro', 'type': 'createServerGroup', 'loadBalancers': [self.__lb_name], 'availabilityZones': { bindings['TEST_GCE_REGION']: [bindings['TEST_GCE_ZONE']] }, 'instanceMetadata': { 'startup-script': ('sudo apt-get update' ' && sudo apt-get install apache2 -y'), 'load-balancer-names': self.__lb_name }, 'account': bindings['SPINNAKER_GOOGLE_ACCOUNT'], 'authScopes': ['compute'], 'user': '******' }], description='Create Server Group in ' + group_name, application=self.TEST_APP) builder = gcp.GcpContractBuilder(self.gcp_observer) (builder.new_clause_builder( 'Managed Instance Group Added', retryable_for_secs=30).inspect_resource( 'instanceGroupManagers', group_name).EXPECT( ov_factory.value_list_path_contains( 'targetSize', jp.NUM_EQ(2)))) return st.OperationContract(self.new_post_operation( title='create_server_group', data=payload, path='tasks'), contract=builder.build())
def create_server_group(self): """Creates OperationContract for createServerGroup. To verify the operation, we just check that Managed Instance Group for the server was created. """ bindings = self.bindings # Spinnaker determines the group name created, # which will be the following: group_name = "{app}-{stack}-v000".format( app=self.TEST_APP, stack=bindings["TEST_STACK"] ) payload = self.agent.make_json_payload_from_kwargs( job=[ { "cloudProvider": "gce", "application": self.TEST_APP, "credentials": bindings["SPINNAKER_GOOGLE_ACCOUNT"], "strategy": "", "capacity": {"min": 2, "max": 2, "desired": 2}, "targetSize": 2, "image": bindings["TEST_GCE_IMAGE_NAME"], "zone": bindings["TEST_GCE_ZONE"], "stack": bindings["TEST_STACK"], "instanceType": "f1-micro", "type": "createServerGroup", "loadBalancers": [self.__lb_name], "availabilityZones": { bindings["TEST_GCE_REGION"]: [bindings["TEST_GCE_ZONE"]] }, "instanceMetadata": {"load-balancer-names": self.__lb_name}, "account": bindings["SPINNAKER_GOOGLE_ACCOUNT"], "authScopes": ["compute"], "user": "******", } ], description="Create Server Group in " + group_name, application=self.TEST_APP, ) builder = gcp.GcpContractBuilder(self.gcp_observer) ( builder.new_clause_builder( "Managed Instance Group Added", retryable_for_secs=30 ) .inspect_resource("instanceGroupManagers", group_name) .EXPECT(ov_factory.value_list_path_contains("targetSize", jp.NUM_EQ(2))) ) return st.OperationContract( self.new_post_operation( title="create_server_group", data=payload, path="tasks" ), contract=builder.build(), )
def create_load_balancer(self): bindings = self.bindings load_balancer_name = self.__full_lb_name spec = { 'checkIntervalSec': 5, 'healthyThreshold': 2, 'unhealthyThreshold': 2, 'timeoutSec': 5, 'port': 80 } payload = self.agent.make_json_payload_from_kwargs( job=[{ 'cloudProvider': 'gce', 'provider': 'gce', 'stack': bindings['TEST_STACK'], 'detail': self.__short_lb_name, 'credentials': bindings['SPINNAKER_GOOGLE_ACCOUNT'], 'region': bindings['TEST_GCE_REGION'], 'ipProtocol': 'TCP', 'portRange': spec['port'], 'loadBalancerName': load_balancer_name, 'healthCheck': { 'port': spec['port'], 'timeoutSec': spec['timeoutSec'], 'checkIntervalSec': spec['checkIntervalSec'], 'healthyThreshold': spec['healthyThreshold'], 'unhealthyThreshold': spec['unhealthyThreshold'], }, 'type': 'upsertLoadBalancer', 'availabilityZones': { bindings['TEST_GCE_REGION']: [] }, 'user': '******' }], description='Create Load Balancer: ' + load_balancer_name, application=self.TEST_APP) # We arent testing load balancers, so assume it is working, # but we'll look for at the health check to know it is ready. builder = gcp.GcpContractBuilder(self.gcp_observer) (builder.new_clause_builder( 'Health Check Added', retryable_for_secs=30).list_resource( 'httpHealthChecks').contains_path_value( 'name', load_balancer_name + '-hc')) (builder.new_clause_builder('Load Balancer Created', retryable_for_secs=60).list_resource( 'forwardingRules').contains_path_value( 'name', self.__full_lb_name)) return st.OperationContract(self.new_post_operation( title='create_load_balancer', data=payload, path=('applications/{app}/tasks').format(app=self.TEST_APP)), contract=builder.build())
def upsert_load_balancer(self): self.__use_lb_name = 'katotest-lb-' + self.test_id self.__use_lb_hc_name = '%s-hc' % self.__use_lb_name self.__use_lb_tp_name = '%s-tp' % self.__use_lb_name self.__use_lb_target = '{0}/targetPools/{1}'.format( self.bindings['TEST_GCE_REGION'], self.__use_lb_tp_name) interval = 123 healthy = 4 unhealthy = 5 timeout = 78 path = '/' + self.__use_lb_target health_check = { 'checkIntervalSec': interval, 'healthyThreshold': healthy, 'unhealthyThreshold': unhealthy, 'timeoutSec': timeout, 'requestPath': path } # pylint: disable=bad-continuation payload = self.agent.type_to_payload( 'upsertGoogleLoadBalancerDescription', { 'healthCheck': health_check, 'region': self.bindings['TEST_GCE_REGION'], 'credentials': self.bindings['SPINNAKER_GOOGLE_ACCOUNT'], 'loadBalancerName': self.__use_lb_name }) builder = gcp.GcpContractBuilder(self.gcp_observer) (builder.new_clause_builder('Forwarding Rules Added', retryable_for_secs=30) .list_resource('forwardingRules') .contains_path_value('name', self.__use_lb_name) .contains_path_value('target', self.__use_lb_target)) (builder.new_clause_builder('Target Pool Added', retryable_for_secs=15) .list_resource('targetPools') .contains_path_value('name', self.__use_lb_tp_name)) # We list the resources here because the name isnt exact # and the list also returns the details we need. hc_dict = dict(health_check) del hc_dict['requestPath'] hc_match = {name: jp.NUM_EQ(value) for name, value in hc_dict.items()} hc_match['requestPath'] = jp.STR_EQ(path) hc_match['name'] = jp.STR_SUBSTR(self.__use_http_lb_hc_name) (builder.new_clause_builder('Health Check Added', retryable_for_secs=15) .list_resource('httpHealthChecks') .contains_match(hc_match)) return st.OperationContract( self.new_post_operation( title='upsert_load_balancer', data=payload, path='ops'), contract=builder.build())
def delete_server_group(self): """Creates OperationContract for deleteServerGroup. To verify the operation, we just check that the GCP managed instance group is no longer visible on GCP (or is in the process of terminating). """ bindings = self.bindings group_name = "{app}-{stack}-v000".format( app=self.TEST_APP, stack=bindings["TEST_STACK"] ) # TODO(ttomsu): Change this back from asgName to serverGroupName # once it is fixed in orca. payload = self.agent.make_json_payload_from_kwargs( job=[ { "cloudProvider": "gce", "serverGroupName": group_name, "region": bindings["TEST_GCE_REGION"], "zone": bindings["TEST_GCE_ZONE"], "asgName": group_name, "type": "destroyServerGroup", "regions": [bindings["TEST_GCE_REGION"]], "zones": [bindings["TEST_GCE_ZONE"]], "credentials": bindings["SPINNAKER_GOOGLE_ACCOUNT"], "user": "******", } ], application=self.TEST_APP, description="DestroyServerGroup: " + group_name, ) builder = gcp.GcpContractBuilder(self.gcp_observer) ( builder.new_clause_builder("Managed Instance Group Removed") .inspect_resource("instanceGroupManagers", group_name) .EXPECT( ov_factory.error_list_contains(gcp.HttpErrorPredicate(http_code=404)) ) .OR(ov_factory.value_list_path_contains("targetSize", jp.NUM_EQ(0))) ) ( builder.new_clause_builder("Instances Are Removed", retryable_for_secs=30) .list_resource("instances") .EXPECT( ov_factory.value_list_path_excludes("name", jp.STR_SUBSTR(group_name)) ) ) return st.OperationContract( self.new_post_operation( title="delete_server_group", data=payload, path="tasks" ), contract=builder.build(), )
def clone_server_group(self): job = [{ 'application': self.TEST_APP, 'stack': self.TEST_STACK, 'credentials': self.bindings['SPINNAKER_GOOGLE_ACCOUNT'], 'loadBalancers': [self.__lb_name], 'targetSize': 1, 'capacity': { 'min': 1, 'max': 1, 'desired': 1 }, 'zone': self.TEST_ZONE, 'network': 'default', 'instanceMetadata': {'load-balancer-names': self.__lb_name}, 'availabilityZones': {self.TEST_REGION: [self.TEST_ZONE]}, 'cloudProvider': 'gce', 'source': { 'account': self.bindings['SPINNAKER_GOOGLE_ACCOUNT'], 'region': self.TEST_REGION, 'zone': self.TEST_ZONE, 'serverGroupName': self.__server_group_name, 'asgName': self.__server_group_name }, 'instanceType': 'f1-micro', 'image': self.bindings['TEST_GCE_IMAGE_NAME'], 'initialNumReplicas': 1, 'loadBalancers': [self.__lb_name], 'type': 'cloneServerGroup', 'account': self.bindings['SPINNAKER_GOOGLE_ACCOUNT'], 'user': '******' }] job[0].update(self.__mig_payload_extra) builder = gcp.GcpContractBuilder(self.gcp_observer) (builder.new_clause_builder(self.__mig_title + ' Cloned', retryable_for_secs=90) .list_resource(self.__mig_manager_name, **self.__mig_manager_kwargs) .contains_path_value('baseInstanceName', self.__cloned_server_group_name)) (builder.new_clause_builder('Instance template preserved', retryable_for_secs=150) .list_resource('instanceTemplates') .contains_path_pred('properties/metadata/items', jp.DICT_MATCHES({ 'key': jp.EQUIVALENT(self.__custom_user_data_key), 'value': jp.EQUIVALENT(self.__custom_user_data_value)}))) payload = self.agent.make_json_payload_from_kwargs( job=job, description=self.__mig_title + ' Test - clone server group', application=self.TEST_APP) return st.OperationContract( self.new_post_operation( title='clone_server_group', data=payload, path=self.__path), contract=builder.build())
def create_load_balancer(self): job = [{ "cloudProvider": "gce", "loadBalancerName": self.__lb_name, "ipProtocol": "TCP", "portRange": "8080", "provider": "gce", "stack": self.TEST_STACK, "detail": "frontend", "credentials": self.bindings["SPINNAKER_GOOGLE_ACCOUNT"], "region": self.TEST_REGION, "listeners": [{ "protocol": "TCP", "portRange": "8080", "healthCheck": False }], "name": self.__lb_name, "type": "upsertLoadBalancer", "availabilityZones": { self.TEST_REGION: [] }, "user": "******", }] builder = gcp.GcpContractBuilder(self.gcp_observer) (builder.new_clause_builder( "Load Balancer Created", retryable_for_secs=30).list_resource("forwardingRules").EXPECT( ov_factory.value_list_path_contains( "name", jp.STR_SUBSTR(self.__lb_name)))) payload = self.agent.make_json_payload_from_kwargs( job=job, description=self.__mig_title + " Test - create load balancer", application=self.TEST_APP, ) return st.OperationContract( self.new_post_operation(title="create_load_balancer", data=payload, path=self.__path), contract=builder.build(), )
def delete_http_load_balancer(self): """Deletes the L7 LB.""" bindings = self.bindings delete = copy.deepcopy(self.__proto_delete) payload = self.agent.make_json_payload_from_kwargs( job=[delete], description="Delete L7 Load Balancer: {0} in {1}".format( self.__lb_name, bindings["SPINNAKER_GOOGLE_ACCOUNT"], ), application=self.TEST_APP, ) contract_builder = gcp.GcpContractBuilder(self.gcp_observer) ( contract_builder.new_clause_builder( "Health Check Removed", retryable_for_secs=30 ) .list_resource("healthChecks") .EXPECT( ov_factory.value_list_path_excludes( "name", jp.STR_SUBSTR(self.__proto_hc["name"]) ) ) ) ( contract_builder.new_clause_builder( "Url Map Removed", retryable_for_secs=30 ) .list_resource("urlMaps") .EXPECT( ov_factory.value_list_path_excludes( "name", jp.STR_SUBSTR(self.__lb_name) ) ) ) ( contract_builder.new_clause_builder( "Forwarding Rule Removed", retryable_for_secs=30 ) .list_resource("globalForwardingRules") .EXPECT( ov_factory.value_list_path_excludes( "name", jp.STR_SUBSTR(self.__lb_name) ) ) ) return st.OperationContract( self.new_post_operation( title="delete_http_load_balancer", data=payload, path="tasks" ), contract=contract_builder.build(), )
def upsert_load_balancer(self): self.__use_lb_name = 'katotest-lb-' + self.test_id self.__use_lb_hc_name = '%s-hc' % self.__use_lb_name self.__use_lb_tp_name = '%s-tp' % self.__use_lb_name self.__use_lb_target = '{0}/targetPools/{1}'.format( self.bindings['TEST_GCE_REGION'], self.__use_lb_tp_name) interval = 123 healthy = 4 unhealthy = 5 timeout = 78 path = '/' + self.__use_lb_target health_check = { 'checkIntervalSec': interval, 'healthyThreshold': healthy, 'unhealthyThreshold': unhealthy, 'timeoutSec': timeout, 'requestPath': path } # pylint: disable=bad-continuation payload = self.agent.type_to_payload( 'upsertGoogleLoadBalancerDescription', { 'healthCheck': health_check, 'region': self.bindings['TEST_GCE_REGION'], 'credentials': self.bindings['GCE_CREDENTIALS'], 'loadBalancerName': self.__use_lb_name }) builder = gcp.GcpContractBuilder(self.gcp_observer) (builder.new_clause_builder('Forwarding Rules Added', retryable_for_secs=30). list_resource('forwardingRules').contains_path_value( 'name', self.__use_lb_name).contains_path_value('target', self.__use_lb_target)) (builder.new_clause_builder('Target Pool Added', retryable_for_secs=15).list_resource( 'targetPools').contains_path_value( 'name', self.__use_lb_tp_name)) # We list the resources here because the name isnt exact # and the list also returns the details we need. (builder.new_clause_builder( 'Health Check Added', retryable_for_secs=15).list_resource( 'httpHealthChecks').contains_pred_list([ jp.PathContainsPredicate('name', self.__use_lb_hc_name), jp.PathContainsPredicate(None, health_check) ])) return st.OperationContract(self.new_post_operation( title='upsert_load_balancer', data=payload, path='ops'), contract=builder.build())
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").EXPECT( ov_factory.value_list_contains( jp.DICT_MATCHES({ "name": jp.STR_SUBSTR(self.__use_lb_tp_name), "instances": jp.LIST_MATCHES([ jp.STR_SUBSTR(self.use_instance_names[0]), jp.STR_SUBSTR(self.use_instance_names[1]), ]), }))).AND( ov_factory.value_list_excludes( jp.DICT_MATCHES({ "name": jp.STR_SUBSTR(self.__use_lb_tp_name), "instances": jp.LIST_MATCHES([ jp.STR_SUBSTR(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 create_load_balancer(self): job = [{ 'cloudProvider': 'gce', 'loadBalancerName': self.__lb_name, 'ipProtocol': 'TCP', 'portRange': '8080', 'provider': 'gce', 'stack': self.TEST_STACK, 'detail': 'frontend', 'credentials': self.bindings['SPINNAKER_GOOGLE_ACCOUNT'], 'region': self.TEST_REGION, 'listeners': [{ 'protocol': 'TCP', 'portRange': '8080', 'healthCheck': False }], 'name': self.__lb_name, 'type': 'upsertLoadBalancer', 'availabilityZones': { self.TEST_REGION: [] }, 'user': '******' }] builder = gcp.GcpContractBuilder(self.gcp_observer) (builder.new_clause_builder( 'Load Balancer Created', retryable_for_secs=30).list_resource('forwardingRules').EXPECT( ov_factory.value_list_path_contains( 'name', jp.STR_SUBSTR(self.__lb_name)))) payload = self.agent.make_json_payload_from_kwargs( job=job, description=self.__mig_title + ' Test - create load balancer', application=self.TEST_APP) return st.OperationContract(self.new_post_operation( title='create_load_balancer', data=payload, path=self.__path), contract=builder.build())
def clone_server_group(self): job = [{ 'application': self.TEST_APP, 'stack': self.TEST_STACK, 'credentials': self.bindings['GCE_CREDENTIALS'], 'loadBalancers': [self.__lb_name], 'targetSize': 1, 'capacity': { 'min': 1, 'max': 1, 'desired': 1 }, 'zone': self.TEST_ZONE, 'network': 'default', 'instanceMetadata': { 'load-balancer-names': self.__lb_name }, 'availabilityZones': { self.TEST_REGION: [self.TEST_ZONE] }, 'cloudProvider': 'gce', 'source': { 'account': self.bindings['GCE_CREDENTIALS'], 'region': self.TEST_REGION, 'zone': self.TEST_ZONE, 'serverGroupName': self.__server_group_name, 'asgName': self.__server_group_name }, 'instanceType': 'f1-micro', 'image': self.bindings['TEST_GCE_IMAGE_NAME'], 'initialNumReplicas': 1, 'loadBalancers': [self.__lb_name], 'type': 'cloneServerGroup', 'account': self.bindings['GCE_CREDENTIALS'], 'user': '******' }] builder = gcp.GcpContractBuilder(self.gcp_observer) (builder.new_clause_builder( 'Server Group Cloned', retryable_for_secs=90).list_resource( 'instanceGroupManagers').contains_path_value( 'baseInstanceName', self.__cloned_server_group_name)) payload = self.agent.make_json_payload_from_kwargs( job=job, description='Server Group Test - clone server group', application=self.TEST_APP) return st.OperationContract(self.new_post_operation( title='clone_server_group', data=payload, path=self.__path), contract=builder.build())
def resize_server_group(self): job = [{ "targetSize": 2, "capacity": { "min": 2, "max": 2, "desired": 2 }, "replicaPoolName": self.__server_group_name, "numReplicas": 2, "region": self.TEST_REGION, "zone": self.TEST_ZONE, "asgName": self.__server_group_name, "serverGroupName": self.__server_group_name, "type": "resizeServerGroup", "regions": [self.TEST_REGION], "zones": [self.TEST_ZONE], "credentials": self.bindings["SPINNAKER_GOOGLE_ACCOUNT"], "cloudProvider": "gce", "user": "******", }] job[0].update(self.__mig_payload_extra) # We set the timeout to 10 minutes, as Spinnaker is returning success once # it has seen the new instance appear, but the contract is waiting for the # instance group's self-reported size to be the new size. There is sometimes a # delay of several minutes between the instance first appearing and the instance # group manager reporting the new size. In order to avoid intermittently failing # tests, we set a reasonably long timeout to wait for consistency between the # Spinnaker internal contract and the contract this test is measuring. builder = gcp.GcpContractBuilder(self.gcp_observer) (builder.new_clause_builder( self.__mig_title + " Resized", retryable_for_secs=600).inspect_resource( self.__mig_resource_name, self.__server_group_name, **self.__mig_resource_kwargs).EXPECT( ov_factory.value_list_path_contains("size", jp.NUM_EQ(2)))) payload = self.agent.make_json_payload_from_kwargs( job=job, description=self.__mig_title + " Test - resize to 2 instances", application=self.TEST_APP, ) return st.OperationContract( self.new_post_operation(title="resize_instances", data=payload, path=self.__path), contract=builder.build(), )