def paasta_start_or_stop(args, desired_state): """Requests a change of state to start or stop given branches of a service.""" instance = args.instance clusters = args.clusters soa_dir = args.soa_dir service = figure_out_service_name(args=args, soa_dir=soa_dir) if args.clusters is not None: clusters = args.clusters.split(",") else: clusters = list_clusters(service) try: remote_refs = remote_git.list_remote_refs( utils.get_git_url(service, soa_dir)) except remote_git.LSRemoteException as e: msg = ( "Error talking to the git server: %s\n" "This PaaSTA command requires access to the git server to operate.\n" "The git server may be down or not reachable from here.\n" "Try again from somewhere where the git server can be reached, " "like your developer environment.") % str(e) print msg return 1 invalid_deploy_groups = [] for cluster in clusters: service_config = get_instance_config( service=service, cluster=cluster, instance=instance, soa_dir=soa_dir, load_deployments=False, ) deploy_group = service_config.get_deploy_group() (deploy_tag, _) = get_latest_deployment_tag(remote_refs, deploy_group) if deploy_tag not in remote_refs: invalid_deploy_groups.append(deploy_group) else: force_bounce = utils.format_timestamp(datetime.datetime.utcnow()) issue_state_change_for_service( service_config=service_config, force_bounce=force_bounce, desired_state=desired_state, ) return_val = 0 if invalid_deploy_groups: print "No branches found for %s in %s." % \ (", ".join(invalid_deploy_groups), remote_refs) print "Has %s been deployed there yet?" % service return_val = 1 return return_val
def paasta_start_or_stop(args, desired_state): """Requests a change of state to start or stop given branches of a service.""" instance = args.instance clusters = args.clusters soa_dir = args.soa_dir service = figure_out_service_name(args=args, soa_dir=soa_dir) if args.clusters is not None: clusters = args.clusters.split(",") else: clusters = list_clusters(service) try: remote_refs = remote_git.list_remote_refs(utils.get_git_url(service, soa_dir)) except remote_git.LSRemoteException as e: msg = ( "Error talking to the git server: %s\n" "This PaaSTA command requires access to the git server to operate.\n" "The git server may be down or not reachable from here.\n" "Try again from somewhere where the git server can be reached, " "like your developer environment." ) % str(e) print msg return 1 invalid_deploy_groups = [] for cluster in clusters: service_config = get_instance_config( service=service, cluster=cluster, instance=instance, soa_dir=soa_dir, load_deployments=False, ) deploy_group = service_config.get_deploy_group() (deploy_tag, _) = get_latest_deployment_tag(remote_refs, deploy_group) if deploy_tag not in remote_refs: invalid_deploy_groups.append(deploy_group) else: force_bounce = utils.format_timestamp(datetime.datetime.utcnow()) issue_state_change_for_service( service_config=service_config, force_bounce=force_bounce, desired_state=desired_state, ) return_val = 0 if invalid_deploy_groups: print "No branches found for %s in %s." % \ (", ".join(invalid_deploy_groups), remote_refs) print "Has %s been deployed there yet?" % service return_val = 1 return return_val
def paasta_get_latest_deployment(args): service = args.service deploy_group = args.deploy_group soa_dir = args.soa_dir validate_service_name(service, soa_dir) git_url = get_git_url( service=service, soa_dir=soa_dir, ) remote_refs = list_remote_refs(git_url) _, git_sha = get_latest_deployment_tag(remote_refs, deploy_group) if not git_sha: print PaastaColors.red("A deployment could not be found for %s in %s" % (deploy_group, service)) return 1 else: print git_sha return 0
def mutate_refs(refs): deploy_group = service_config.get_deploy_group() (_, head_sha) = get_latest_deployment_tag(refs, deploy_group) refs[format_tag(service_config.get_branch(), force_bounce, desired_state)] = \ head_sha return refs
def paasta_start_or_stop(args, desired_state): """Requests a change of state to start or stop given branches of a service.""" soa_dir = args.soa_dir pargs = apply_args_filters(args) if len(pargs) == 0: return 1 affected_services = {s for service_list in pargs.values() for s in service_list.keys()} if len(affected_services) > 1: paasta_print(PaastaColors.red("Warning: trying to start/stop/restart multiple services:")) for cluster, services_instances in pargs.items(): paasta_print("Cluster %s:" % cluster) for service, instances in services_instances.items(): paasta_print(" Service %s:" % service) paasta_print(" Instances %s" % ",".join(instances)) if sys.stdin.isatty(): confirm = choice.Binary('Are you sure you want to continue?', False).ask() else: confirm = False if not confirm: paasta_print() paasta_print("exiting") return 1 invalid_deploy_groups = [] marathon_message_printed, chronos_message_printed = False, False for cluster, services_instances in pargs.items(): for service, instances in services_instances.items(): try: remote_refs = remote_git.list_remote_refs(utils.get_git_url(service, soa_dir)) except remote_git.LSRemoteException as e: msg = ( "Error talking to the git server: %s\n" "This PaaSTA command requires access to the git server to operate.\n" "The git server may be down or not reachable from here.\n" "Try again from somewhere where the git server can be reached, " "like your developer environment." ) % str(e) paasta_print(msg) return 1 for instance in instances: service_config = get_instance_config( service=service, cluster=cluster, instance=instance, soa_dir=soa_dir, load_deployments=False, ) deploy_group = service_config.get_deploy_group() (deploy_tag, _) = get_latest_deployment_tag(remote_refs, deploy_group) if deploy_tag not in remote_refs: invalid_deploy_groups.append(deploy_group) else: force_bounce = utils.format_timestamp(datetime.datetime.utcnow()) if isinstance(service_config, MarathonServiceConfig) and not marathon_message_printed: print_marathon_message(desired_state) marathon_message_printed = True elif isinstance(service_config, ChronosJobConfig) and not chronos_message_printed: print_chronos_message(desired_state) chronos_message_printed = True issue_state_change_for_service( service_config=service_config, force_bounce=force_bounce, desired_state=desired_state, ) return_val = 0 if invalid_deploy_groups: paasta_print("No branches found for %s in %s." % (", ".join(invalid_deploy_groups), remote_refs)) paasta_print("Has %s been deployed there yet?" % service) return_val = 1 return return_val
def paasta_start_or_stop(args, desired_state): """Requests a change of state to start or stop given branches of a service.""" soa_dir = args.soa_dir service = figure_out_service_name(args=args, soa_dir=soa_dir) instances = args.instances.split(",") if args.instances else None # assert that each of the clusters that the user specifies are 'valid' # for the instance list provided; that is, assert that at least one of the instances # provided in the -i argument is deployed there. # if there are no instances defined in the args, then assert that the service # is deployed to that cluster. # If args.clusters is falsey, then default to *all* clusters that a service is deployed to, # and we figure out which ones are needed for each service later. if instances: instance_clusters = [ list_clusters(service, soa_dir, instance) for instance in args.instances ] valid_clusters = sorted( list( set([ cluster for cluster_list in instance_clusters for cluster in cluster_list ]))) else: valid_clusters = list_clusters(service, soa_dir) if args.clusters: clusters = args.clusters.split(",") invalid_clusters = [ cluster for cluster in clusters if cluster not in valid_clusters ] if invalid_clusters: print("Invalid cluster name(s) specified: %s." "Valid options: %s") % (" ".join(invalid_clusters), " ".join(valid_clusters)) return 1 else: clusters = valid_clusters try: remote_refs = remote_git.list_remote_refs( utils.get_git_url(service, soa_dir)) except remote_git.LSRemoteException as e: msg = ( "Error talking to the git server: %s\n" "This PaaSTA command requires access to the git server to operate.\n" "The git server may be down or not reachable from here.\n" "Try again from somewhere where the git server can be reached, " "like your developer environment.") % str(e) print msg return 1 invalid_deploy_groups = [] marathon_message_printed, chronos_message_printed = False, False for cluster in clusters: # If they haven't specified what instances to act on, do it for all of them. # If they have specified what instances, only iterate over them if they're # actually within this cluster. if instances is None: cluster_instances = list_all_instances_for_service( service, clusters=[cluster], soa_dir=soa_dir) print( "no instances specified; restarting all instances for service") else: all_cluster_instances = list_all_instances_for_service( service, clusters=[cluster], soa_dir=soa_dir) cluster_instances = all_cluster_instances.intersection( set(instances)) for instance in cluster_instances: service_config = get_instance_config( service=service, cluster=cluster, instance=instance, soa_dir=soa_dir, load_deployments=False, ) deploy_group = service_config.get_deploy_group() (deploy_tag, _) = get_latest_deployment_tag(remote_refs, deploy_group) if deploy_tag not in remote_refs: invalid_deploy_groups.append(deploy_group) else: force_bounce = utils.format_timestamp( datetime.datetime.utcnow()) if isinstance(service_config, MarathonServiceConfig ) and not marathon_message_printed: print_marathon_message(desired_state) marathon_message_printed = True elif isinstance( service_config, ChronosJobConfig) and not chronos_message_printed: print_chronos_message(desired_state) chronos_message_printed = True issue_state_change_for_service( service_config=service_config, force_bounce=force_bounce, desired_state=desired_state, ) return_val = 0 if invalid_deploy_groups: print "No branches found for %s in %s." % \ (", ".join(invalid_deploy_groups), remote_refs) print "Has %s been deployed there yet?" % service return_val = 1 return return_val
def paasta_start_or_stop(args, desired_state): """Requests a change of state to start or stop given branches of a service.""" soa_dir = args.soa_dir service = figure_out_service_name(args=args, soa_dir=soa_dir) instances = args.instances.split(",") if args.instances else None # assert that each of the clusters that the user specifies are 'valid' # for the instance list provided; that is, assert that at least one of the instances # provided in the -i argument is deployed there. # if there are no instances defined in the args, then assert that the service # is deployed to that cluster. # If args.clusters is falsey, then default to *all* clusters that a service is deployed to, # and we figure out which ones are needed for each service later. if instances: instance_clusters = [list_clusters(service, soa_dir, instance) for instance in args.instances] valid_clusters = sorted(list(set([cluster for cluster_list in instance_clusters for cluster in cluster_list]))) else: valid_clusters = list_clusters(service, soa_dir) if args.clusters: clusters = args.clusters.split(",") invalid_clusters = [cluster for cluster in clusters if cluster not in valid_clusters] if invalid_clusters: print ("Invalid cluster name(s) specified: %s." "Valid options: %s") % ( " ".join(invalid_clusters), " ".join(valid_clusters), ) return 1 else: clusters = valid_clusters try: remote_refs = remote_git.list_remote_refs(utils.get_git_url(service, soa_dir)) except remote_git.LSRemoteException as e: msg = ( "Error talking to the git server: %s\n" "This PaaSTA command requires access to the git server to operate.\n" "The git server may be down or not reachable from here.\n" "Try again from somewhere where the git server can be reached, " "like your developer environment." ) % str(e) print msg return 1 invalid_deploy_groups = [] marathon_message_printed, chronos_message_printed = False, False for cluster in clusters: # If they haven't specified what instances to act on, do it for all of them. # If they have specified what instances, only iterate over them if they're # actually within this cluster. if instances is None: cluster_instances = list_all_instances_for_service(service, clusters=[cluster], soa_dir=soa_dir) print ("no instances specified; restarting all instances for service") else: all_cluster_instances = list_all_instances_for_service(service, clusters=[cluster], soa_dir=soa_dir) cluster_instances = all_cluster_instances.intersection(set(instances)) for instance in cluster_instances: service_config = get_instance_config( service=service, cluster=cluster, instance=instance, soa_dir=soa_dir, load_deployments=False ) deploy_group = service_config.get_deploy_group() (deploy_tag, _) = get_latest_deployment_tag(remote_refs, deploy_group) if deploy_tag not in remote_refs: invalid_deploy_groups.append(deploy_group) else: force_bounce = utils.format_timestamp(datetime.datetime.utcnow()) if isinstance(service_config, MarathonServiceConfig) and not marathon_message_printed: print_marathon_message(desired_state) marathon_message_printed = True elif isinstance(service_config, ChronosJobConfig) and not chronos_message_printed: print_chronos_message(desired_state) chronos_message_printed = True issue_state_change_for_service( service_config=service_config, force_bounce=force_bounce, desired_state=desired_state ) return_val = 0 if invalid_deploy_groups: print "No branches found for %s in %s." % (", ".join(invalid_deploy_groups), remote_refs) print "Has %s been deployed there yet?" % service return_val = 1 return return_val
def paasta_start_or_stop(args, desired_state): """Requests a change of state to start or stop given branches of a service.""" soa_dir = args.soa_dir pargs = apply_args_filters(args) if len(pargs) == 0: return 1 affected_services = { s for service_list in pargs.values() for s in service_list.keys() } if len(affected_services) > 1: print( PaastaColors.red( "Warning: trying to start/stop/restart multiple services:")) for cluster, services_instances in pargs.items(): print("Cluster %s:" % cluster) for service, instances in services_instances.items(): print(" Service %s:" % service) print(" Instances %s" % ",".join(instances.keys())) if sys.stdin.isatty(): confirm = choice.Binary("Are you sure you want to continue?", False).ask() else: confirm = False if not confirm: print() print("exiting") return 1 invalid_deploy_groups = [] marathon_message_printed = False affected_flinks = [] if args.clusters is None or args.instances is None: if confirm_to_continue(pargs.items(), desired_state) is False: print() print("exiting") return 1 for cluster, services_instances in pargs.items(): for service, instances in services_instances.items(): for instance in instances.keys(): service_config = get_instance_config( service=service, cluster=cluster, instance=instance, soa_dir=soa_dir, load_deployments=False, ) if isinstance(service_config, FlinkDeploymentConfig): affected_flinks.append(service_config) continue try: remote_refs = get_remote_refs(service, soa_dir) except remote_git.LSRemoteException as e: msg = ( "Error talking to the git server: %s\n" "This PaaSTA command requires access to the git server to operate.\n" "The git server may be down or not reachable from here.\n" "Try again from somewhere where the git server can be reached, " "like your developer environment.") % str(e) print(msg) return 1 deploy_group = service_config.get_deploy_group() (deploy_tag, _) = get_latest_deployment_tag(remote_refs, deploy_group) if deploy_tag not in remote_refs: invalid_deploy_groups.append(deploy_group) else: force_bounce = utils.format_timestamp( datetime.datetime.utcnow()) if (isinstance(service_config, MarathonServiceConfig) and not marathon_message_printed): print_marathon_message(desired_state) marathon_message_printed = True issue_state_change_for_service( service_config=service_config, force_bounce=force_bounce, desired_state=desired_state, ) return_val = 0 # TODO: Refactor to discover if set_state is available for given # instance_type in API if affected_flinks: print_flink_message(desired_state) csi = defaultdict(lambda: defaultdict(list)) for service_config in affected_flinks: csi[service_config.cluster][service_config.service].append( service_config.instance) system_paasta_config = load_system_paasta_config() for cluster, services_instances in csi.items(): client = get_paasta_api_client(cluster, system_paasta_config) if not client: print("Cannot get a paasta-api client") exit(1) for service, instances in services_instances.items(): for instance in instances: try: client.service.instance_set_state( service=service, instance=instance, desired_state=desired_state, ).result() except HTTPError as exc: print(exc.response.text) return exc.status_code return_val = 0 if invalid_deploy_groups: print(f"No deploy tags found for {', '.join(invalid_deploy_groups)}.") print(f"Has {service} been deployed there yet?") return_val = 1 return return_val
def paasta_start_or_stop(args, desired_state): """Requests a change of state to start or stop given branches of a service.""" soa_dir = args.soa_dir service = figure_out_service_name(args=args, soa_dir=soa_dir) if args.clusters is not None: clusters = args.clusters.split(",") else: clusters = list_clusters(service) if args.instances is not None: instances = args.instances.split(",") else: instances = None try: remote_refs = remote_git.list_remote_refs(utils.get_git_url(service, soa_dir)) except remote_git.LSRemoteException as e: msg = ( "Error talking to the git server: %s\n" "This PaaSTA command requires access to the git server to operate.\n" "The git server may be down or not reachable from here.\n" "Try again from somewhere where the git server can be reached, " "like your developer environment." ) % str(e) print msg return 1 invalid_deploy_groups = [] marathon_message_printed, chronos_message_printed = False, False for cluster in clusters: # If they haven't specified what instances to act on, do it for all of them. # If they have specified what instances, only iterate over them if they're # actually within this cluster. if instances is None: cluster_instances = list_all_instances_for_service(service, clusters=[cluster], soa_dir=soa_dir) else: all_cluster_instances = list_all_instances_for_service(service, clusters=[cluster], soa_dir=soa_dir) cluster_instances = all_cluster_instances.intersection(set(instances)) for instance in cluster_instances: service_config = get_instance_config( service=service, cluster=cluster, instance=instance, soa_dir=soa_dir, load_deployments=False, ) deploy_group = service_config.get_deploy_group() (deploy_tag, _) = get_latest_deployment_tag(remote_refs, deploy_group) if deploy_tag not in remote_refs: invalid_deploy_groups.append(deploy_group) else: force_bounce = utils.format_timestamp(datetime.datetime.utcnow()) if isinstance(service_config, MarathonServiceConfig) and not marathon_message_printed: print_marathon_message(desired_state) marathon_message_printed = True elif isinstance(service_config, ChronosJobConfig) and not chronos_message_printed: print_chronos_message(desired_state) chronos_message_printed = True issue_state_change_for_service( service_config=service_config, force_bounce=force_bounce, desired_state=desired_state, ) return_val = 0 if invalid_deploy_groups: print "No branches found for %s in %s." % \ (", ".join(invalid_deploy_groups), remote_refs) print "Has %s been deployed there yet?" % service return_val = 1 return return_val
def paasta_start_or_stop(args, desired_state): """Requests a change of state to start or stop given branches of a service.""" soa_dir = args.soa_dir pargs = apply_args_filters(args) if len(pargs) == 0: return 1 affected_services = { s for service_list in pargs.values() for s in service_list.keys() } if len(affected_services) > 1: paasta_print( PaastaColors.red( "Warning: trying to start/stop/restart multiple services:")) for cluster, services_instances in pargs.items(): paasta_print("Cluster %s:" % cluster) for service, instances in services_instances.items(): paasta_print(" Service %s:" % service) paasta_print(" Instances %s" % ",".join(instances.keys())) if sys.stdin.isatty(): confirm = choice.Binary('Are you sure you want to continue?', False).ask() else: confirm = False if not confirm: paasta_print() paasta_print("exiting") return 1 invalid_deploy_groups = [] marathon_message_printed = False chronos_message_printed = False affected_flinkclusters = [] if args.clusters is None or args.instances is None: if confirm_to_continue(pargs.items(), desired_state) is False: paasta_print() paasta_print("exiting") return 1 for cluster, services_instances in pargs.items(): for service, instances in services_instances.items(): for instance in instances.keys(): service_config = get_instance_config( service=service, cluster=cluster, instance=instance, soa_dir=soa_dir, load_deployments=False, ) if isinstance(service_config, FlinkClusterConfig): affected_flinkclusters.append(service_config) continue try: remote_refs = get_remote_refs(service, soa_dir) except remote_git.LSRemoteException as e: msg = ( "Error talking to the git server: %s\n" "This PaaSTA command requires access to the git server to operate.\n" "The git server may be down or not reachable from here.\n" "Try again from somewhere where the git server can be reached, " "like your developer environment.") % str(e) paasta_print(msg) return 1 deploy_group = service_config.get_deploy_group() (deploy_tag, _) = get_latest_deployment_tag(remote_refs, deploy_group) if deploy_tag not in remote_refs: invalid_deploy_groups.append(deploy_group) else: force_bounce = utils.format_timestamp( datetime.datetime.utcnow()) if isinstance(service_config, MarathonServiceConfig ) and not marathon_message_printed: print_marathon_message(desired_state) marathon_message_printed = True elif isinstance( service_config, ChronosJobConfig) and not chronos_message_printed: print_chronos_message(desired_state) chronos_message_printed = True issue_state_change_for_service( service_config=service_config, force_bounce=force_bounce, desired_state=desired_state, ) return_val = 0 if affected_flinkclusters: if os.environ.get('ON_PAASTA_MASTER'): print_flinkcluster_message(desired_state) kube_client = KubeClient() for service_config in affected_flinkclusters: set_flinkcluster_desired_state( kube_client=kube_client, service=service_config.service, instance=service_config.instance, desired_state=dict(start='running', stop='stopped')[desired_state], ) else: csi = defaultdict(lambda: defaultdict(list)) for service_config in affected_flinkclusters: csi[service_config.cluster][service_config.service].append( service_config.instance) system_paasta_config = load_system_paasta_config() for cluster, services_instances in csi.items(): for service, instances in services_instances.items(): cmd_parts = [ 'ON_PAASTA_MASTER=1', 'paasta', desired_state, '-c', cluster, '-s', service, '-i', ','.join(instances), ] return_val, _ = run_on_master( cluster=cluster, system_paasta_config=system_paasta_config, cmd_parts=cmd_parts, graceful_exit=True, ) if invalid_deploy_groups: paasta_print("No branches found for %s in %s." % (", ".join(invalid_deploy_groups), remote_refs)) paasta_print("Has %s been deployed there yet?" % service) return_val = 1 return return_val