示例#1
0
文件: kploy.py 项目: kubernauts/kploy
def cmd_list(param):
    """
    Lists app resources and their status.
    """
    here = os.path.realpath(".")
    kployfile = os.path.join(here, DEPLOYMENT_DESCRIPTOR)
    if VERBOSE: logging.info("Listing resource status of app based on %s " %(kployfile))
    try:
        kploy, _  = util.load_yaml(filename=kployfile)
        print("Resources of app `%s/%s`:\n" %(kploy["namespace"], kploy["name"]))
        pyk_client = kploycommon._connect(api_server=kploy["apiserver"], debug=DEBUG)
        rc_manifests_confirmed, svc_manifests_confirmed = [], []
        services = os.path.join(here, SVC_DIR)
        rcs = os.path.join(here, RC_DIR)
        svc_list = kploycommon._visit(services, 'service', cache_remotes=True)
        rc_list = kploycommon._visit(rcs, 'RC', cache_remotes=True)
        res_list = []
        # gather Services status:
        print("[Services and RCs]\n")
        for svc in svc_list:
            svc_manifest, _  = util.load_yaml(filename=os.path.join(here, SVC_DIR, svc))
            svc_name = svc_manifest["metadata"]["name"]
            svc_path = "".join(["/api/v1/namespaces/", kploy["namespace"], "/services/", svc_name])
            svc_URL = "".join([kploy["apiserver"], svc_path])
            svc_status = kploycommon._check_status(pyk_client, svc_path)
            res_list.append([svc_name, os.path.join(SVC_DIR, svc), "service", svc_status, svc_URL])
        # gather RC status:
        for rc in rc_list:
            rc_manifest, _  = util.load_yaml(filename=os.path.join(here, RC_DIR, rc))
            rc_name = rc_manifest["metadata"]["name"]
            rc_path = "".join(["/api/v1/namespaces/", kploy["namespace"], "/replicationcontrollers/", rc_name])
            rc_URL = "".join([kploy["apiserver"], rc_path])
            rc_status = kploycommon._check_status(pyk_client, rc_path)
            res_list.append([rc_name, os.path.join(RC_DIR, rc), "RC", rc_status, rc_URL])
        print(tabulate(res_list, ["NAME", "MANIFEST", "TYPE", "STATUS", "URL"], tablefmt="plain"))
        # gather Secrets status:
        print("\n" + 80*"=")
        print("[Secrets]")
        sec_list = []
        secret_path = "".join(["/api/v1/namespaces/", kploy["namespace"], "/secrets/kploy-secrets"])
        sec_URL = "".join([kploy["apiserver"], secret_path])
        secret = pyk_client.describe_resource(secret_path)
        if secret.status_code == 200:
            print("URL: %s" %(sec_URL))
            secret_data = secret.json()["data"]
            for k, v in secret_data.iteritems():
                sec_list.append([k, base64.b64decode(v)])
            print(tabulate(sec_list, ["KEY", "VALUE"], tablefmt="plain"))
        else:
            print("No env data deployed.")
        print("\n" + 80*"=")
    except (Exception) as e:
        print("Something went wrong:\n%s" %(e))
        print("Consider validating your deployment with `kploy dryrun` first!")
        sys.exit(1)
示例#2
0
    def create_rc(self, manifest_filename, namespace="default"):
        """
        Creates an RC based on a manifest.

        :Parameters:
           - `manifest_filename`: The manifest file containing the ReplicationController definition, for example: `manifest/nginx-webserver-rc.yaml`
           - `namespace`: In which namespace the RC should be created, defaults to, well, `default`
        """
        rc_manifest, rc_manifest_json = util.load_yaml(
            filename=manifest_filename)
        logging.debug("%s" % (rc_manifest_json))
        create_rc_path = "".join(
            ["/api/v1/namespaces/", namespace, "/replicationcontrollers"])
        res = self.execute_operation(method="POST",
                                     ops_path=create_rc_path,
                                     payload=rc_manifest_json)
        try:
            rc_url = res.json()["metadata"]["selfLink"]
        except KeyError:
            raise ResourceCRUDException("".join([
                "Sorry, can not create the RC: ",
                rc_manifest["metadata"]["name"], ". Maybe it exists already?"
            ]))
        logging.info(
            "From %s I created the RC %s at %s" %
            (manifest_filename, rc_manifest["metadata"]["name"], rc_url))
        return (res, rc_url)
示例#3
0
    def scale_rc(self, manifest_filename, namespace="default", num_replicas=0):
        """
        Changes the replicas of an RC based on a manifest.
        Note that it defaults to 0, meaning to effectively disable this RC.

        :Parameters:
           - `manifest_filename`: The manifest file containing the ReplicationController definition, for example: `manifest/nginx-webserver-rc.yaml`
           - `namespace`: In which namespace the RC is, defaulting to `default`
           - `num_replicas`: How many copies of the pods that match the selector are supposed to run
        """
        rc_manifest, rc_manifest_json = util.load_yaml(
            filename=manifest_filename)
        logging.debug("%s" % (rc_manifest_json))
        rc_path = "".join([
            "/api/v1/namespaces/", namespace, "/replicationcontrollers/",
            rc_manifest["metadata"]["name"]
        ])
        rc_manifest["spec"]["replicas"] = num_replicas
        res = self.execute_operation(
            method="PUT",
            ops_path=rc_path,
            payload=util.serialize_tojson(rc_manifest))
        try:
            rc_url = res.json()["metadata"]["selfLink"]
        except KeyError:
            raise ResourceCRUDException("".join([
                "Sorry, can not scale the RC: ",
                rc_manifest["metadata"]["name"]
            ]))
        logging.info("I scaled the RC %s at %s to %d replicas" %
                     (rc_manifest["metadata"]["name"], rc_url, num_replicas))
        return (res, rc_url)
示例#4
0
def cmd_export(param):
    """
    Creates an archive of all relevant app files, incl. Kployfile and manifest directories.
    You can use the resulting archive then with `kploy init` to bootstrap you app in a different location.
    """
    here = os.path.realpath(".")
    kployfile = os.path.join(here, DEPLOYMENT_DESCRIPTOR)
    if VERBOSE:
        logging.info("Exporting app based on content from %s " % (here))
    try:
        kploy, _ = util.load_yaml(filename=kployfile)
        if not param:
            param = EXPORT_ARCHIVE_FILENAME
        archive_filename, archive_file = kploycommon._export_init(
            here, DEPLOYMENT_DESCRIPTOR, param)
        print("Adding content of app `%s/%s` to %s" %
              (kploy["namespace"], kploy["name"], archive_filename))
        rc_manifests_confirmed, svc_manifests_confirmed = [], []
        services = os.path.join(here, SVC_DIR)
        rcs = os.path.join(here, RC_DIR)
        svc_list = kploycommon._visit(services, 'service', cache_remotes=True)
        rc_list = kploycommon._visit(rcs, 'RC', cache_remotes=True)
        res_list = []
        for svc in svc_list:
            svc_file_name = os.path.join(SVC_DIR, svc)
            kploycommon._export_add(archive_file, svc_file_name)
        for rc in rc_list:
            rc_file_name = os.path.join(RC_DIR, rc)
            kploycommon._export_add(archive_file, rc_file_name)
        kploycommon._export_done(archive_file)
    except (Exception) as e:
        print("Something went wrong:\n%s" % (e))
        print("Consider validating your deployment with `kploy dryrun` first!")
        sys.exit(1)
示例#5
0
文件: kploy.py 项目: kubernauts/kploy
def cmd_debug(pod_name):
    """
    Enables you to debug a Pod by taking it offline through removing the `guard=pyk` label.
    Usage: `debug pod`, for example, `debug webserver-42abc`.
    """
    if not pod_name:
        print("Sorry, I need a Pod name in order to do my work. Do a `kploy stats` first to glean the Pod name you want to debug, e.g. `webserver-42abc`.")
        print("With the Pod name you can then run `kploy debug webserver-42abc` to take the Pod offline and subsequently for example use `kubectl exec` to enter the Pod.")
        sys.exit(1)
    here = os.path.realpath(".")
    kployfile = os.path.join(here, DEPLOYMENT_DESCRIPTOR)
    print("Trying to take Pod %s offline for debugging ..." %(pod_name))
    try:
        kploy, _  = util.load_yaml(filename=kployfile)
        logging.debug(kploy)
        pyk_client = kploycommon._connect(api_server=kploy["apiserver"], debug=DEBUG)
        pod_path = "".join(["/api/v1/namespaces/", kploy["namespace"], "/pods/", pod_name])
        pod = pyk_client.describe_resource(pod_path)
        resource = pod.json()
        resource["metadata"]["labels"] = {}
        logging.debug("Removed guard label from Pod, now labeled with: %s" %(resource["metadata"]["labels"]))
        pyk_client.execute_operation(method='PUT', ops_path=pod_path, payload=util.serialize_tojson(resource))
        # now we just need to make sure that the newly created Pod is again owned by kploy:
        rc_name = pod_name[0:pod_name.rfind("-")] # NOTE: this is a hack, it assumes a certain generator pattern; need to figure a better way to find a Pod's RC
        logging.debug("Generating RC name from Pod: %s" %(rc_name))
        rc_path = "".join(["/api/v1/namespaces/", kploy["namespace"], "/replicationcontrollers/", rc_name])
        rc = pyk_client.describe_resource(rc_path)
        kploycommon._own_pods_of_rc(pyk_client, rc, kploy["namespace"], rc_path, VERBOSE)
    except (Exception) as e:
        print("Something went wrong when taking the Pod offline:\n%s" %(e))
        sys.exit(1)
    print(80*"=")
    print("\nOK, the Pod %s is offline. Now you can, for example, use `kubectl exec` now to debug it." %(pod_name))
示例#6
0
文件: kploy.py 项目: kubernauts/kploy
def cmd_export(param):
    """
    Creates an archive of all relevant app files, incl. Kployfile and manifest directories.
    You can use the resulting archive then with `kploy init` to bootstrap you app in a different location.
    """
    here = os.path.realpath(".")
    kployfile = os.path.join(here, DEPLOYMENT_DESCRIPTOR)
    if VERBOSE: logging.info("Exporting app based on content from %s " %(here))
    try:
        kploy, _  = util.load_yaml(filename=kployfile)
        if not param:
            param = EXPORT_ARCHIVE_FILENAME
        archive_filename, archive_file = kploycommon._export_init(here, DEPLOYMENT_DESCRIPTOR, param)
        print("Adding content of app `%s/%s` to %s" %(kploy["namespace"], kploy["name"], archive_filename))
        rc_manifests_confirmed, svc_manifests_confirmed = [], []
        services = os.path.join(here, SVC_DIR)
        rcs = os.path.join(here, RC_DIR)
        svc_list = kploycommon._visit(services, 'service', cache_remotes=True)
        rc_list = kploycommon._visit(rcs, 'RC', cache_remotes=True)
        res_list = []
        for svc in svc_list:
            svc_file_name = os.path.join(SVC_DIR, svc)
            kploycommon._export_add(archive_file, svc_file_name)
        for rc in rc_list:
            rc_file_name = os.path.join(RC_DIR, rc)
            kploycommon._export_add(archive_file, rc_file_name)
        kploycommon._export_done(archive_file)
    except (Exception) as e:
        print("Something went wrong:\n%s" %(e))
        print("Consider validating your deployment with `kploy dryrun` first!")
        sys.exit(1)
示例#7
0
文件: kploy.py 项目: kubernauts/kploy
def cmd_destroy(param):
    """
    Destroys the app, removing all resources.
    """
    here = os.path.realpath(".")
    kployfile = os.path.join(here, DEPLOYMENT_DESCRIPTOR)
    if VERBOSE: logging.info("Trying to destroy app based on %s " %(kployfile))
    try:
        kploy, _  = util.load_yaml(filename=kployfile)
        logging.debug(kploy)
        pyk_client = kploycommon._connect(api_server=kploy["apiserver"], debug=DEBUG)
        # delete all services and RCs:
        rc_manifests_confirmed, svc_manifests_confirmed = [], []
        services = os.path.join(here, SVC_DIR)
        rcs = os.path.join(here, RC_DIR)
        svc_manifests_confirmed = kploycommon._visit(services, 'service', cache_remotes=True)
        rc_manifests_confirmed = kploycommon._visit(rcs, 'RC', cache_remotes=True)
        kploycommon._destroy(pyk_client, kploy["namespace"], here, SVC_DIR, svc_manifests_confirmed, 'service', VERBOSE)
        kploycommon._destroy(pyk_client, kploy["namespace"], here, RC_DIR, rc_manifests_confirmed, 'RC', VERBOSE)
        # delete secrets:
        secret_path = "".join(["/api/v1/namespaces/", kploy["namespace"], "/secrets/kploy-secrets"])
        pyk_client.delete_resource(resource_path=secret_path)
        # delete the namespace:
        ns_path = "".join(["/api/v1/namespaces/", kploy["namespace"]])
        pyk_client.delete_resource(resource_path=ns_path)
    except (Exception) as e:
        print("Something went wrong destroying your app:\n%s" %(e))
        print("Consider validating your deployment with `kploy dryrun` first!")
        sys.exit(1)
    print(80*"=")
    print("\nOK, I've destroyed `%s/%s`\n" %(kploy["namespace"], kploy["name"]))
示例#8
0
def _destroy(pyk_client, namespace, here, dir_name, alist, resource_name, verbose):
    """
    Destroys resources based on manifest files. Currently the following resources are supported:
    replication controllers, services.
    """
    for litem in alist:
        file_name = os.path.join(os.path.join(here, dir_name), litem)
        if file_name.endswith(".url"):
            file_name = _deref_remote(file_name)
        if verbose: logging.info("Trying to destroy %s %s" %(resource_name, file_name))
        res_manifest, _  = util.load_yaml(filename=file_name)
        res_name = res_manifest["metadata"]["name"]
        if resource_name == "service":
            res_path = "".join(["/api/v1/namespaces/", namespace, "/services/", res_name])
        elif resource_name == "RC":
            res_path = "".join(["/api/v1/namespaces/", namespace, "/replicationcontrollers/", res_name])
            res = pyk_client.describe_resource(res_path)
            if res.status_code == 404:  # the replication controller is already gone
                break                   # ... don't try to scale down
            else:
                resource = res.json()
                resource["spec"]["replicas"] = 0
                if verbose: logging.info("Scaling down RC %s to 0" %(res_path))
                pyk_client.execute_operation(method='PUT', ops_path=res_path, payload=util.serialize_tojson(resource))
        else: return None
        pyk_client.delete_resource(resource_path=res_path)
示例#9
0
def cmd_scale(scale_def):
    """
    Enables you to scale an RC up or down by setting the number of replicas.
    Usage: `scale rc=replica_count`, for example, `scale webserver-rc=10`.
    """
    if not scale_def:
        print(
            "Sorry, I need a scale definition in order to do my work. Do a `kploy list` first to glean the RC name you want to scale, e.g. `webserver-rc`."
        )
        print(
            "With the RC name you can then run `kploy scale webserver-rc=5` to scale the respective RC to 5 replicas."
        )
        sys.exit(1)
    here = os.path.realpath(".")
    kployfile = os.path.join(here, DEPLOYMENT_DESCRIPTOR)
    try:
        rc_name = scale_def.split("=")[0]
        replica_count = int(scale_def.split("=")[1])
    except (Exception) as e:
        print("Can't parse scale definition `%s` due to: %s" % (scale_def, e))
        print(
            "The scale definition should look as follows: `rc=replica_count`, for example, `scale webserver-rc=10`."
        )
        sys.exit(1)
    print("Trying to scale RC %s to %d replicas" % (rc_name, replica_count))
    try:
        kploy, _ = util.load_yaml(filename=kployfile)
        logging.debug(kploy)
        pyk_client = kploycommon._connect(api_server=kploy["apiserver"],
                                          debug=DEBUG)
        rc_path = "".join([
            "/api/v1/namespaces/", kploy["namespace"],
            "/replicationcontrollers/", rc_name
        ])
        rc = pyk_client.describe_resource(rc_path)
        resource = rc.json()
        old_replica_count = resource["spec"]["replicas"]
        if VERBOSE:
            logging.info("Scaling RC from %d to %d replicas" %
                         (old_replica_count, replica_count))
        logging.debug("RC about to be scaled: %s" % (resource))
        resource["spec"]["replicas"] = replica_count
        pyk_client.execute_operation(method='PUT',
                                     ops_path=rc_path,
                                     payload=util.serialize_tojson(resource))
        # and make sure that the newly created Pods are owned by kploy (on scale up)
        if replica_count > old_replica_count:
            logging.debug("Scaling up, trying to own new Pods")
            rc = pyk_client.describe_resource(rc_path)
            kploycommon._own_pods_of_rc(pyk_client, rc, kploy["namespace"],
                                        rc_path, VERBOSE)
    except (Exception) as e:
        print("Something went wrong when scaling RC:\n%s" % (e))
        sys.exit(1)
    print(80 * "=")
    print(
        "OK, I've scaled RC %s to %d replicas. You can do a `kploy stats` now to verify it."
        % (rc_name, replica_count))
示例#10
0
def cmd_run(param):
    """
    Looks for a `Kployfile` file in the current directory and tries to run it.
    """
    here = os.path.realpath(".")
    kployfile = os.path.join(here, DEPLOYMENT_DESCRIPTOR)
    if VERBOSE: logging.info("Trying to run %s " % (kployfile))
    try:
        kploy, _ = util.load_yaml(filename=kployfile)
        logging.debug(kploy)
        pyk_client = kploycommon._connect(api_server=kploy["apiserver"],
                                          debug=DEBUG)
        # set up a Namespace for this app:
        kploycommon._create_ns(pyk_client, kploy["namespace"], VERBOSE)
        # set up a Secrets for this app:
        env = os.path.join(here, ENV_DIR)
        secrets = {}
        logging.debug("Visiting %s" % env)
        for _, _, file_names in os.walk(env):
            for afile in file_names:
                if afile.endswith(SECRETS_FILE_EXT):
                    logging.debug("Got a secret input: %s" % (afile))
                    key = os.path.splitext(afile)[0]
                    logging.debug("Secret key: %s" % (key))
                    with open(os.path.join(env, afile), "r") as sec_file:
                        raw_data = sec_file.read().strip()
                    logging.debug("Secret data: %s" % (raw_data))
                    val = base64.b64encode(raw_data)
                    logging.debug("Secret base64 encoded data: %s" % (val))
                    secrets[key] = val
        kploycommon._create_secrets(pyk_client, kploy["name"],
                                    kploy["namespace"], secrets, VERBOSE)
        # collect Services and RCs ...
        rc_manifests_confirmed, svc_manifests_confirmed = [], []
        services = os.path.join(here, SVC_DIR)
        rcs = os.path.join(here, RC_DIR)
        svc_manifests_confirmed = kploycommon._visit(
            services, 'service', cache_remotes=kploy["cache_remotes"])
        rc_manifests_confirmed = kploycommon._visit(
            rcs, 'RC', cache_remotes=kploy["cache_remotes"])
        # ... and deploy them:
        kploycommon._deploy(pyk_client, kploy["namespace"], here, SVC_DIR,
                            svc_manifests_confirmed, 'service', VERBOSE)
        kploycommon._deploy(pyk_client, kploy["namespace"], here, RC_DIR,
                            rc_manifests_confirmed, 'RC', VERBOSE)
    except (Exception) as e:
        print("Something went wrong deploying your app:\n%s" % (e))
        print("Consider validating your deployment with `kploy dryrun` first!")
        sys.exit(1)
    print(80 * "=")
    print(
        "\nOK, I've deployed `%s/%s`.\nUse `kploy list` and `kploy stats` to check how it's doing."
        % (kploy["namespace"], kploy["name"]))
示例#11
0
文件: kploy.py 项目: kubernauts/kploy
def cmd_stats(param):
    """
    Shows cluster utilization and provides summary of the pods' state, from the point of view of your app.
    """
    here = os.path.realpath(".")
    kployfile = os.path.join(here, DEPLOYMENT_DESCRIPTOR)
    if VERBOSE: logging.info("Providing stats for your app based on %s " %(kployfile))
    try:
        kploy, _  = util.load_yaml(filename=kployfile)
        print("Runtime stats for app `%s/%s`:" %(kploy["namespace"], kploy["name"]))
        pyk_client = kploycommon._connect(api_server=kploy["apiserver"], debug=DEBUG)
        # provide container summary:
        print("\n[Your app's pods]\n")
        guarded_pods_path = "".join(["/api/v1/namespaces/", kploy["namespace"], "/pods?labelSelector=guard%3Dpyk"])
        pods = pyk_client.execute_operation(method="GET", ops_path=guarded_pods_path)
        pods_list = pods.json()["items"]
        if not pods_list:
            print "No pods are online. "
            return
        pod_details = []
        used_nodes = []
        for pod in pods_list:
            if pod["status"]["hostIP"] not in used_nodes:
                used_nodes.append(pod["status"]["hostIP"])
            pod_details.append([
                pod["metadata"]["name"],
                pod["status"]["hostIP"],
                pod["status"]["phase"],
                "".join([kploy["apiserver"], pod["metadata"]["selfLink"]])
            ])
        print(tabulate(pod_details, ["NAME", "HOST", "STATUS", "URL"], tablefmt="plain"))
        print("\n" + 80*"=")
        # provide utilization info:
        print("[Nodes used by your app]\n")
        nodes = pyk_client.execute_operation(method="GET", ops_path="/api/v1/nodes")
        nodes_list = nodes.json()["items"]
        node_ips = []
        for node in nodes_list:
            if node["metadata"]["name"] in used_nodes:
                node_ips.append([
                    node["metadata"]["name"],
                    node["status"]["nodeInfo"]["osImage"],
                    node["status"]["nodeInfo"]["containerRuntimeVersion"],
                    node["status"]["capacity"]["pods"] + ", " + node["status"]["capacity"]["cpu"] + ", " + node["status"]["capacity"]["memory"],
                    "".join([kploy["apiserver"], node["metadata"]["selfLink"]])
                ])
        print(tabulate(node_ips, ["IP", "HOST OS", "CONTAINER RUNTIME", "CAPACITY (PODS, CPU, MEM)", "URL"], tablefmt="plain"))
        print("\n" + 80*"=")
    except (Exception) as e:
        print("Something went wrong:\n%s" %(e))
        print("Consider validating your deployment with `kploy dryrun` first!")
        sys.exit(1)
示例#12
0
def cmd_debug(pod_name):
    """
    Enables you to debug a Pod by taking it offline through removing the `guard=pyk` label.
    Usage: `debug pod`, for example, `debug webserver-42abc`.
    """
    if not pod_name:
        print(
            "Sorry, I need a Pod name in order to do my work. Do a `kploy stats` first to glean the Pod name you want to debug, e.g. `webserver-42abc`."
        )
        print(
            "With the Pod name you can then run `kploy debug webserver-42abc` to take the Pod offline and subsequently for example use `kubectl exec` to enter the Pod."
        )
        sys.exit(1)
    here = os.path.realpath(".")
    kployfile = os.path.join(here, DEPLOYMENT_DESCRIPTOR)
    print("Trying to take Pod %s offline for debugging ..." % (pod_name))
    try:
        kploy, _ = util.load_yaml(filename=kployfile)
        logging.debug(kploy)
        pyk_client = kploycommon._connect(api_server=kploy["apiserver"],
                                          debug=DEBUG)
        pod_path = "".join(
            ["/api/v1/namespaces/", kploy["namespace"], "/pods/", pod_name])
        pod = pyk_client.describe_resource(pod_path)
        resource = pod.json()
        resource["metadata"]["labels"] = {}
        logging.debug("Removed guard label from Pod, now labeled with: %s" %
                      (resource["metadata"]["labels"]))
        pyk_client.execute_operation(method='PUT',
                                     ops_path=pod_path,
                                     payload=util.serialize_tojson(resource))
        # now we just need to make sure that the newly created Pod is again owned by kploy:
        rc_name = pod_name[0:pod_name.rfind(
            "-"
        )]  # NOTE: this is a hack, it assumes a certain generator pattern; need to figure a better way to find a Pod's RC
        logging.debug("Generating RC name from Pod: %s" % (rc_name))
        rc_path = "".join([
            "/api/v1/namespaces/", kploy["namespace"],
            "/replicationcontrollers/", rc_name
        ])
        rc = pyk_client.describe_resource(rc_path)
        kploycommon._own_pods_of_rc(pyk_client, rc, kploy["namespace"],
                                    rc_path, VERBOSE)
    except (Exception) as e:
        print("Something went wrong when taking the Pod offline:\n%s" % (e))
        sys.exit(1)
    print(80 * "=")
    print(
        "\nOK, the Pod %s is offline. Now you can, for example, use `kubectl exec` now to debug it."
        % (pod_name))
示例#13
0
文件: kploy.py 项目: kubernauts/kploy
def cmd_run(param):
    """
    Looks for a `Kployfile` file in the current directory and tries to run it.
    """
    here = os.path.realpath(".")
    kployfile = os.path.join(here, DEPLOYMENT_DESCRIPTOR)
    if VERBOSE: logging.info("Trying to run %s " %(kployfile))
    try:
        kploy, _  = util.load_yaml(filename=kployfile)
        logging.debug(kploy)
        pyk_client = kploycommon._connect(api_server=kploy["apiserver"], debug=DEBUG)
        # set up a Namespace for this app:
        kploycommon._create_ns(pyk_client, kploy["namespace"], VERBOSE)
        # set up a Secrets for this app:
        env = os.path.join(here, ENV_DIR)
        secrets = {}
        logging.debug("Visiting %s" %env)
        for _, _, file_names in os.walk(env):
            for afile in file_names:
                if afile.endswith(SECRETS_FILE_EXT):
                    logging.debug("Got a secret input: %s" %(afile))
                    key = os.path.splitext(afile)[0]
                    logging.debug("Secret key: %s" %(key))
                    with open(os.path.join(env, afile), "r") as sec_file:
                        raw_data = sec_file.read().strip()
                    logging.debug("Secret data: %s" %(raw_data))
                    val = base64.b64encode(raw_data)
                    logging.debug("Secret base64 encoded data: %s" %(val))
                    secrets[key] = val
        kploycommon._create_secrets(pyk_client, kploy["name"], kploy["namespace"], secrets, VERBOSE)
        # collect Services and RCs ...
        rc_manifests_confirmed, svc_manifests_confirmed = [], []
        services = os.path.join(here, SVC_DIR)
        rcs = os.path.join(here, RC_DIR)
        svc_manifests_confirmed = kploycommon._visit(services, 'service', cache_remotes=kploy["cache_remotes"])
        rc_manifests_confirmed = kploycommon._visit(rcs, 'RC', cache_remotes=kploy["cache_remotes"])
        # ... and deploy them:
        kploycommon._deploy(pyk_client, kploy["namespace"], here, SVC_DIR, svc_manifests_confirmed, 'service', VERBOSE)
        kploycommon._deploy(pyk_client, kploy["namespace"], here, RC_DIR, rc_manifests_confirmed, 'RC', VERBOSE)
    except (Exception) as e:
        print("Something went wrong deploying your app:\n%s" %(e))
        print("Consider validating your deployment with `kploy dryrun` first!")
        sys.exit(1)
    print(80*"=")
    print("\nOK, I've deployed `%s/%s`.\nUse `kploy list` and `kploy stats` to check how it's doing." %(kploy["namespace"], kploy["name"]))
示例#14
0
    def create_rc(self, manifest_filename, namespace="default"):
        """
        Creates an RC based on a manifest.

        :Parameters:
           - `manifest_filename`: The manifest file containing the ReplicationController definition, for example: `manifest/nginx-webserver-rc.yaml`
           - `namespace`: In which namespace the RC should be created, defaults to, well, `default`
        """
        rc_manifest, rc_manifest_json  = util.load_yaml(filename=manifest_filename)
        logging.debug("%s" %(rc_manifest_json))
        create_rc_path = "".join(["/api/v1/namespaces/", namespace, "/replicationcontrollers"])
        res = self.execute_operation(method="POST", ops_path=create_rc_path, payload=rc_manifest_json)
        try:
            rc_url = res.json()["metadata"]["selfLink"]
        except KeyError:
            raise ResourceCRUDException("".join(["Sorry, can not create the RC: ", rc_manifest["metadata"]["name"], ". Maybe it exists already?"]))
        logging.info("From %s I created the RC %s at %s" %(manifest_filename, rc_manifest["metadata"]["name"], rc_url))
        return (res, rc_url)
示例#15
0
文件: kploy.py 项目: kubernauts/kploy
def cmd_dryrun(param):
    """
    Looks for a `Kployfile` file in the current directory and tries
    to validate its content, incl. syntax validation and mock execution.
    """
    here = os.path.realpath(".")
    kployfile = os.path.join(here, DEPLOYMENT_DESCRIPTOR)
    if VERBOSE: logging.info("Trying to execute a dry run on %s " %(kployfile))
    try:
        kploy, _  = util.load_yaml(filename=kployfile)
        logging.debug(kploy)
        print("Validating application `%s/%s` ..." %(kploy["namespace"], kploy["name"]))

        print("\n  CHECK: Is the Kubernetes cluster up & running and accessible via `%s`?" %(kploy["apiserver"]))
        pyk_client = kploycommon._connect(api_server=kploy["apiserver"], debug=DEBUG)
        nodes = pyk_client.execute_operation(method="GET", ops_path="/api/v1/nodes")
        if VERBOSE: logging.info("Got node list %s " %(util.serialize_tojson(nodes.json())))
        print("  \o/ ... I found %d node(s) to deploy your wonderful app onto." %(len(nodes.json()["items"])))

        print("\n  CHECK: Are there RC and service manifests available around here?")
        try:
            rcs = os.path.join(here, RC_DIR)
            logging.debug("Asserting %s exists" %(os.path.dirname(rcs)))
            assert os.path.exists(rcs)
            rc_manifests_confirmed = kploycommon._visit(rcs, "RC", cache_remotes=kploy["cache_remotes"])
            print("         I found %s RC manifest(s) in %s" %(int(len(rc_manifests_confirmed)), os.path.dirname(rcs)))
            if VERBOSE: kploycommon._dump(rc_manifests_confirmed)

            services = os.path.join(here, SVC_DIR)
            logging.debug("Asserting %s exists" %(os.path.dirname(services)))
            assert os.path.exists(services)
            svc_manifests_confirmed = kploycommon._visit(services, "service", cache_remotes=kploy["cache_remotes"])
            print("         I found %s service manifest(s) in %s" %(int(len(svc_manifests_confirmed)), os.path.dirname(services)))
            if VERBOSE: kploycommon._dump(svc_manifests_confirmed)
            print("  \o/ ... I found both RC and service manifests to deploy your wonderful app!")
        except:
            print("No RC and/or service manifests found to deploy your app. You can use `kploy init` to create missing artefacts.")
            sys.exit(1)
    except (IOError, IndexError, KeyError) as e:
        print("Something went wrong:\n%s" %(e))
        sys.exit(1)
    print(80*"=")
    print("\nOK, we're looking good! You're ready to deploy your app with `kploy run` now :)\n")
示例#16
0
def cmd_push(param):
    """
    Exports the app and uploads it to KAR, the kploy app registry (https://github.com/kubernauts/kploy.net).
    Note that you MUST set the `source` field in the `Kployfile` file to a GitHub username or repo URL,
    otherwise the push operation will fail. For example, you can use `source : https://github.com/mhausenblas`
    if you don't have a project repo for the app (yet) or `source : https://github.com/mhausenblas/abc`
    if you want to explicitly set the app's project repo.
    """
    here = os.path.realpath(".")
    kployfile = os.path.join(here, DEPLOYMENT_DESCRIPTOR)
    archivefile = os.path.join(here, "".join([".", EXPORT_ARCHIVE_FILENAME]))
    app_link = KAR_BASE_URL
    if VERBOSE:
        logging.info("Creating temporary app archive %s" % (archivefile))
    cmd_export(archivefile)
    if VERBOSE: logging.info("Trying to upload %s" % (archivefile))
    try:
        kploy, _ = util.load_yaml(filename=kployfile)
        logging.debug(kploy)
        if kploy["source"].startswith(VALID_WORKSPACE_PREFIXES):
            print("Using %s as the app's workspace" % (kploy["source"]))
            res = kploycommon._push_app_archive(kploy["source"], archivefile,
                                                KAR_BASE_URL, VERBOSE)
            app_link = "".join(
                [res.json()["selfLink"], "?workspace=", kploy["source"]])
        else:
            raise InvalidWorkspaceError
    except (InvalidWorkspaceError) as iwe:
        print(iwe.__doc__)
        print("To learn how to fix this, run `kploy explain push`")
        sys.exit(1)
    except (Exception) as e:
        print("Something went wrong pushing your app to the registry:\n%s" %
              (e))
        sys.exit(1)
    finally:
        if os.path.exists(archivefile):
            os.remove(archivefile)
    print(80 * "=")
    print("\nOK, I've successfully pushed the app archive to the registry:")
    print("%s" % (app_link))
    print("\nTo list the available app(s), use the `kploy pull` command.\n")
示例#17
0
def cmd_destroy(param):
    """
    Destroys the app, removing all resources.
    """
    here = os.path.realpath(".")
    kployfile = os.path.join(here, DEPLOYMENT_DESCRIPTOR)
    if VERBOSE:
        logging.info("Trying to destroy app based on %s " % (kployfile))
    try:
        kploy, _ = util.load_yaml(filename=kployfile)
        logging.debug(kploy)
        pyk_client = kploycommon._connect(api_server=kploy["apiserver"],
                                          debug=DEBUG)
        # delete all services and RCs:
        rc_manifests_confirmed, svc_manifests_confirmed = [], []
        services = os.path.join(here, SVC_DIR)
        rcs = os.path.join(here, RC_DIR)
        svc_manifests_confirmed = kploycommon._visit(services,
                                                     'service',
                                                     cache_remotes=True)
        rc_manifests_confirmed = kploycommon._visit(rcs,
                                                    'RC',
                                                    cache_remotes=True)
        kploycommon._destroy(pyk_client, kploy["namespace"], here, SVC_DIR,
                             svc_manifests_confirmed, 'service', VERBOSE)
        kploycommon._destroy(pyk_client, kploy["namespace"], here, RC_DIR,
                             rc_manifests_confirmed, 'RC', VERBOSE)
        # delete secrets:
        secret_path = "".join([
            "/api/v1/namespaces/", kploy["namespace"], "/secrets/kploy-secrets"
        ])
        pyk_client.delete_resource(resource_path=secret_path)
        # delete the namespace:
        ns_path = "".join(["/api/v1/namespaces/", kploy["namespace"]])
        pyk_client.delete_resource(resource_path=ns_path)
    except (Exception) as e:
        print("Something went wrong destroying your app:\n%s" % (e))
        print("Consider validating your deployment with `kploy dryrun` first!")
        sys.exit(1)
    print(80 * "=")
    print("\nOK, I've destroyed `%s/%s`\n" %
          (kploy["namespace"], kploy["name"]))
示例#18
0
文件: kploy.py 项目: kubernauts/kploy
def cmd_scale(scale_def):
    """
    Enables you to scale an RC up or down by setting the number of replicas.
    Usage: `scale rc=replica_count`, for example, `scale webserver-rc=10`.
    """
    if not scale_def:
        print("Sorry, I need a scale definition in order to do my work. Do a `kploy list` first to glean the RC name you want to scale, e.g. `webserver-rc`.")
        print("With the RC name you can then run `kploy scale webserver-rc=5` to scale the respective RC to 5 replicas.")
        sys.exit(1)
    here = os.path.realpath(".")
    kployfile = os.path.join(here, DEPLOYMENT_DESCRIPTOR)
    try:
        rc_name = scale_def.split("=")[0]
        replica_count = int(scale_def.split("=")[1])
    except (Exception) as e:
        print("Can't parse scale definition `%s` due to: %s" %(scale_def, e))
        print("The scale definition should look as follows: `rc=replica_count`, for example, `scale webserver-rc=10`.")
        sys.exit(1)
    print("Trying to scale RC %s to %d replicas" %(rc_name, replica_count))
    try:
        kploy, _  = util.load_yaml(filename=kployfile)
        logging.debug(kploy)
        pyk_client = kploycommon._connect(api_server=kploy["apiserver"], debug=DEBUG)
        rc_path = "".join(["/api/v1/namespaces/", kploy["namespace"], "/replicationcontrollers/", rc_name])
        rc = pyk_client.describe_resource(rc_path)
        resource = rc.json()
        old_replica_count = resource["spec"]["replicas"]
        if VERBOSE: logging.info("Scaling RC from %d to %d replicas" %(old_replica_count, replica_count))
        logging.debug("RC about to be scaled: %s" %(resource))
        resource["spec"]["replicas"] = replica_count
        pyk_client.execute_operation(method='PUT', ops_path=rc_path, payload=util.serialize_tojson(resource))
        # and make sure that the newly created Pods are owned by kploy (on scale up)
        if replica_count > old_replica_count:
            logging.debug("Scaling up, trying to own new Pods")
            rc = pyk_client.describe_resource(rc_path)
            kploycommon._own_pods_of_rc(pyk_client, rc, kploy["namespace"], rc_path, VERBOSE)
    except (Exception) as e:
        print("Something went wrong when scaling RC:\n%s" %(e))
        sys.exit(1)
    print(80*"=")
    print("OK, I've scaled RC %s to %d replicas. You can do a `kploy stats` now to verify it." %(rc_name, replica_count))
示例#19
0
    def scale_rc(self, manifest_filename, namespace="default", num_replicas=0):
        """
        Changes the replicas of an RC based on a manifest.
        Note that it defaults to 0, meaning to effectively disable this RC.

        :Parameters:
           - `manifest_filename`: The manifest file containing the ReplicationController definition, for example: `manifest/nginx-webserver-rc.yaml`
           - `namespace`: In which namespace the RC is, defaulting to `default`
           - `num_replicas`: How many copies of the pods that match the selector are supposed to run
        """
        rc_manifest, rc_manifest_json = util.load_yaml(filename=manifest_filename)
        logging.debug("%s" %(rc_manifest_json))
        rc_path = "".join(["/api/v1/namespaces/", namespace, "/replicationcontrollers/", rc_manifest["metadata"]["name"]])
        rc_manifest["spec"]["replicas"] = num_replicas
        res = self.execute_operation(method="PUT", ops_path=rc_path, payload=util.serialize_tojson(rc_manifest))
        try:
            rc_url = res.json()["metadata"]["selfLink"]
        except KeyError:
            raise ResourceCRUDException("".join(["Sorry, can not scale the RC: ", rc_manifest["metadata"]["name"]]))
        logging.info("I scaled the RC %s at %s to %d replicas" %(rc_manifest["metadata"]["name"], rc_url, num_replicas))
        return (res, rc_url)
示例#20
0
文件: kploy.py 项目: kubernauts/kploy
def cmd_push(param):
    """
    Exports the app and uploads it to KAR, the kploy app registry (https://github.com/kubernauts/kploy.net).
    Note that you MUST set the `source` field in the `Kployfile` file to a GitHub username or repo URL,
    otherwise the push operation will fail. For example, you can use `source : https://github.com/mhausenblas`
    if you don't have a project repo for the app (yet) or `source : https://github.com/mhausenblas/abc`
    if you want to explicitly set the app's project repo.
    """
    here = os.path.realpath(".")
    kployfile = os.path.join(here, DEPLOYMENT_DESCRIPTOR)
    archivefile = os.path.join(here, "".join([".", EXPORT_ARCHIVE_FILENAME]))
    app_link = KAR_BASE_URL
    if VERBOSE: logging.info("Creating temporary app archive %s" %(archivefile))
    cmd_export(archivefile)
    if VERBOSE: logging.info("Trying to upload %s" %(archivefile))
    try:
        kploy, _ = util.load_yaml(filename=kployfile)
        logging.debug(kploy)
        if kploy["source"].startswith(VALID_WORKSPACE_PREFIXES):
            print("Using %s as the app's workspace" %(kploy["source"]))
            res = kploycommon._push_app_archive(kploy["source"], archivefile, KAR_BASE_URL, VERBOSE)
            app_link = "".join([res.json()["selfLink"], "?workspace=", kploy["source"]])
        else:
            raise InvalidWorkspaceError
    except (InvalidWorkspaceError) as iwe:
        print(iwe.__doc__)
        print("To learn how to fix this, run `kploy explain push`")
        sys.exit(1)
    except (Exception) as e:
        print("Something went wrong pushing your app to the registry:\n%s" %(e))
        sys.exit(1)
    finally:
        if os.path.exists(archivefile):
           os.remove(archivefile)
    print(80*"=")
    print("\nOK, I've successfully pushed the app archive to the registry:")
    print("%s" %(app_link))
    print("\nTo list the available app(s), use the `kploy pull` command.\n")
示例#21
0
def _destroy(pyk_client, namespace, here, dir_name, alist, resource_name,
             verbose):
    """
    Destroys resources based on manifest files. Currently the following resources are supported:
    replication controllers, services.
    """
    for litem in alist:
        file_name = os.path.join(os.path.join(here, dir_name), litem)
        if file_name.endswith(".url"):
            file_name = _deref_remote(file_name)
        if verbose:
            logging.info("Trying to destroy %s %s" %
                         (resource_name, file_name))
        res_manifest, _ = util.load_yaml(filename=file_name)
        res_name = res_manifest["metadata"]["name"]
        if resource_name == "service":
            res_path = "".join(
                ["/api/v1/namespaces/", namespace, "/services/", res_name])
        elif resource_name == "RC":
            res_path = "".join([
                "/api/v1/namespaces/", namespace, "/replicationcontrollers/",
                res_name
            ])
            res = pyk_client.describe_resource(res_path)
            if res.status_code == 404:  # the replication controller is already gone
                break  # ... don't try to scale down
            else:
                resource = res.json()
                resource["spec"]["replicas"] = 0
                if verbose:
                    logging.info("Scaling down RC %s to 0" % (res_path))
                pyk_client.execute_operation(
                    method='PUT',
                    ops_path=res_path,
                    payload=util.serialize_tojson(resource))
        else:
            return None
        pyk_client.delete_resource(resource_path=res_path)
    running_mypods = len(mypods)
    print "{} running".format(running_mypods)

    # too many?
    if running_mypods > REPLICAS:
        to_delete = running_mypods - REPLICAS
        print "  Too many are running. Deleting {} pods:".format(to_delete)
        for pod in mypods[:to_delete]:
            print "    Deleting pod {}".format(pod['metadata']['name'])
            kubeclient.delete_resource(pod['metadata']['selfLink'])

    # too few?
    elif REPLICAS > running_mypods:
        to_launch = REPLICAS - running_mypods

        for n in range(0, to_launch):
            mypod_spec, _ = util.load_yaml(filename="mypod.yaml")
            mypod_spec["metadata"]["name"] += "-" + shortuuid.uuid()[:4].lower(
            )

            print "Launching pod {}".format(mypod_spec["metadata"]["name"])
            response = kubeclient.execute_operation(
                method='POST',
                ops_path="/api/v1/namespaces/default/pods",
                payload=util.serialize_tojson(mypod_spec))
            if response.status_code >= 300:
                print "ERROR {}: {}".format(response.status_code,
                                            response.content)

    time.sleep(1)
示例#23
0
def cmd_pull(param):
    """
    Lists apps or downloads + imports app from KAR, the kploy app registry (https://github.com/kubernauts/kploy.net).
    Note that you MUST set the `source` field in the `Kployfile` file to a GitHub username or repo URL,
    otherwise the pull operation will fail. For example, you can use `source : https://github.com/mhausenblas`
    if you don't have a project repo for the app (yet) or `source : https://github.com/mhausenblas/abc`
    if you want to explicitly set the app's project repo.

    Without argument all available apps are listed, with an argument the respective app is first
    downloaded and then imported (as with `kploy init`):

    kploy pull

    kploy pull $ID
    """
    here = os.path.realpath(".")
    kployfile = os.path.join(here, DEPLOYMENT_DESCRIPTOR)
    archivefile = os.path.join(here, "".join([".", EXPORT_ARCHIVE_FILENAME]))
    app_link = KAR_BASE_URL
    try:
        kploy, _ = util.load_yaml(filename=kployfile)
        logging.debug(kploy)
        if kploy["source"].startswith(VALID_WORKSPACE_PREFIXES):
            print("Using %s as the app's workspace" % (kploy["source"]))
            if not param:
                if VERBOSE:
                    logging.info("Trying to list apps in the workspace ...")
                res = kploycommon._list_apps(kploy["source"], KAR_BASE_URL,
                                             VERBOSE)
                apps = res.json()
                app_list = []
                for app in apps:
                    app_list.append([
                        app["timeCreated"],
                        app["name"].split("/")[-1].split(".")[0], app["size"]
                    ])
                print(
                    tabulate(sorted(app_list, reverse=True),
                             ["TIMESTAMP", "ID", "SIZE"],
                             tablefmt="plain"))
            else:
                app_id = param
                if VERBOSE:
                    logging.info(
                        "Trying to download app %s from the workspace ..." %
                        (app_id))
                if not kploycommon._download_app(kploy["source"], app_id,
                                                 archivefile, KAR_BASE_URL,
                                                 VERBOSE):
                    raise NoSuchAppError
                else:
                    cmd_init(archivefile)
        else:
            raise InvalidWorkspaceError
    except (InvalidWorkspaceError) as iwe:
        print(iwe.__doc__)
        print("To learn how to fix this, run `kploy explain push`")
        sys.exit(1)
    except (NoSuchAppError) as nsae:
        print(nsae.__doc__)
        print("To learn how to fix this, run `kploy explain pull`")
        sys.exit(1)
    except (Exception) as e:
        print("Something went wrong pulling from the registry:\n%s" % (e))
        sys.exit(1)
    finally:
        if os.path.exists(archivefile):
            os.remove(archivefile)
    if not param:
        print(80 * "=")
        print("\nOK, I've successfully pulled from the registry.")
        print("\nYou can now `kploy pull $ID` to download and init an app.")
        print(
            "\nWARNING: a `kploy pull $ID` will overwrite whatever you had locally.\n"
        )
示例#24
0
def cmd_dryrun(param):
    """
    Looks for a `Kployfile` file in the current directory and tries
    to validate its content, incl. syntax validation and mock execution.
    """
    here = os.path.realpath(".")
    kployfile = os.path.join(here, DEPLOYMENT_DESCRIPTOR)
    if VERBOSE:
        logging.info("Trying to execute a dry run on %s " % (kployfile))
    try:
        kploy, _ = util.load_yaml(filename=kployfile)
        logging.debug(kploy)
        print("Validating application `%s/%s` ..." %
              (kploy["namespace"], kploy["name"]))

        print(
            "\n  CHECK: Is the Kubernetes cluster up & running and accessible via `%s`?"
            % (kploy["apiserver"]))
        pyk_client = kploycommon._connect(api_server=kploy["apiserver"],
                                          debug=DEBUG)
        nodes = pyk_client.execute_operation(method="GET",
                                             ops_path="/api/v1/nodes")
        if VERBOSE:
            logging.info("Got node list %s " %
                         (util.serialize_tojson(nodes.json())))
        print(
            "  \o/ ... I found %d node(s) to deploy your wonderful app onto." %
            (len(nodes.json()["items"])))

        print(
            "\n  CHECK: Are there RC and service manifests available around here?"
        )
        try:
            rcs = os.path.join(here, RC_DIR)
            logging.debug("Asserting %s exists" % (os.path.dirname(rcs)))
            assert os.path.exists(rcs)
            rc_manifests_confirmed = kploycommon._visit(
                rcs, "RC", cache_remotes=kploy["cache_remotes"])
            print("         I found %s RC manifest(s) in %s" %
                  (int(len(rc_manifests_confirmed)), os.path.dirname(rcs)))
            if VERBOSE: kploycommon._dump(rc_manifests_confirmed)

            services = os.path.join(here, SVC_DIR)
            logging.debug("Asserting %s exists" % (os.path.dirname(services)))
            assert os.path.exists(services)
            svc_manifests_confirmed = kploycommon._visit(
                services, "service", cache_remotes=kploy["cache_remotes"])
            print(
                "         I found %s service manifest(s) in %s" %
                (int(len(svc_manifests_confirmed)), os.path.dirname(services)))
            if VERBOSE: kploycommon._dump(svc_manifests_confirmed)
            print(
                "  \o/ ... I found both RC and service manifests to deploy your wonderful app!"
            )
        except:
            print(
                "No RC and/or service manifests found to deploy your app. You can use `kploy init` to create missing artefacts."
            )
            sys.exit(1)
    except (IOError, IndexError, KeyError) as e:
        print("Something went wrong:\n%s" % (e))
        sys.exit(1)
    print(80 * "=")
    print(
        "\nOK, we're looking good! You're ready to deploy your app with `kploy run` now :)\n"
    )
示例#25
0
文件: kploy.py 项目: kubernauts/kploy
def cmd_pull(param):
    """
    Lists apps or downloads + imports app from KAR, the kploy app registry (https://github.com/kubernauts/kploy.net).
    Note that you MUST set the `source` field in the `Kployfile` file to a GitHub username or repo URL,
    otherwise the pull operation will fail. For example, you can use `source : https://github.com/mhausenblas`
    if you don't have a project repo for the app (yet) or `source : https://github.com/mhausenblas/abc`
    if you want to explicitly set the app's project repo.

    Without argument all available apps are listed, with an argument the respective app is first
    downloaded and then imported (as with `kploy init`):

    kploy pull

    kploy pull $ID
    """
    here = os.path.realpath(".")
    kployfile = os.path.join(here, DEPLOYMENT_DESCRIPTOR)
    archivefile = os.path.join(here, "".join([".", EXPORT_ARCHIVE_FILENAME]))
    app_link = KAR_BASE_URL
    try:
        kploy, _ = util.load_yaml(filename=kployfile)
        logging.debug(kploy)
        if kploy["source"].startswith(VALID_WORKSPACE_PREFIXES):
            print("Using %s as the app's workspace" %(kploy["source"]))
            if not param:
                if VERBOSE: logging.info("Trying to list apps in the workspace ...")
                res = kploycommon._list_apps(kploy["source"], KAR_BASE_URL, VERBOSE)
                apps = res.json()
                app_list = []
                for app in apps:
                    app_list.append([
                        app["timeCreated"],
                        app["name"].split("/")[-1].split(".")[0],
                        app["size"]
                    ])
                print(tabulate(sorted(app_list, reverse=True), ["TIMESTAMP", "ID", "SIZE"], tablefmt="plain"))
            else:
                app_id = param
                if VERBOSE: logging.info("Trying to download app %s from the workspace ..." %(app_id))
                if not kploycommon._download_app(kploy["source"], app_id, archivefile, KAR_BASE_URL, VERBOSE):
                    raise NoSuchAppError
                else:
                    cmd_init(archivefile)
        else:
            raise InvalidWorkspaceError
    except (InvalidWorkspaceError) as iwe:
        print(iwe.__doc__)
        print("To learn how to fix this, run `kploy explain push`")
        sys.exit(1)
    except (NoSuchAppError) as nsae:
        print(nsae.__doc__)
        print("To learn how to fix this, run `kploy explain pull`")
        sys.exit(1)
    except (Exception) as e:
        print("Something went wrong pulling from the registry:\n%s" %(e))
        sys.exit(1)
    finally:
        if os.path.exists(archivefile):
           os.remove(archivefile)
    if not param:
        print(80*"=")
        print("\nOK, I've successfully pulled from the registry.")
        print("\nYou can now `kploy pull $ID` to download and init an app.")
        print("\nWARNING: a `kploy pull $ID` will overwrite whatever you had locally.\n")
示例#26
0
def cmd_stats(param):
    """
    Shows cluster utilization and provides summary of the pods' state, from the point of view of your app.
    """
    here = os.path.realpath(".")
    kployfile = os.path.join(here, DEPLOYMENT_DESCRIPTOR)
    if VERBOSE:
        logging.info("Providing stats for your app based on %s " % (kployfile))
    try:
        kploy, _ = util.load_yaml(filename=kployfile)
        print("Runtime stats for app `%s/%s`:" %
              (kploy["namespace"], kploy["name"]))
        pyk_client = kploycommon._connect(api_server=kploy["apiserver"],
                                          debug=DEBUG)
        # provide container summary:
        print("\n[Your app's pods]\n")
        guarded_pods_path = "".join([
            "/api/v1/namespaces/", kploy["namespace"],
            "/pods?labelSelector=guard%3Dpyk"
        ])
        pods = pyk_client.execute_operation(method="GET",
                                            ops_path=guarded_pods_path)
        pods_list = pods.json()["items"]
        if not pods_list:
            print "No pods are online. "
            return
        pod_details = []
        used_nodes = []
        for pod in pods_list:
            if pod["status"]["hostIP"] not in used_nodes:
                used_nodes.append(pod["status"]["hostIP"])
            pod_details.append([
                pod["metadata"]["name"], pod["status"]["hostIP"],
                pod["status"]["phase"],
                "".join([kploy["apiserver"], pod["metadata"]["selfLink"]])
            ])
        print(
            tabulate(pod_details, ["NAME", "HOST", "STATUS", "URL"],
                     tablefmt="plain"))
        print("\n" + 80 * "=")
        # provide utilization info:
        print("[Nodes used by your app]\n")
        nodes = pyk_client.execute_operation(method="GET",
                                             ops_path="/api/v1/nodes")
        nodes_list = nodes.json()["items"]
        node_ips = []
        for node in nodes_list:
            if node["metadata"]["name"] in used_nodes:
                node_ips.append([
                    node["metadata"]["name"],
                    node["status"]["nodeInfo"]["osImage"],
                    node["status"]["nodeInfo"]["containerRuntimeVersion"],
                    node["status"]["capacity"]["pods"] + ", " +
                    node["status"]["capacity"]["cpu"] + ", " +
                    node["status"]["capacity"]["memory"],
                    "".join([kploy["apiserver"], node["metadata"]["selfLink"]])
                ])
        print(
            tabulate(node_ips, [
                "IP", "HOST OS", "CONTAINER RUNTIME",
                "CAPACITY (PODS, CPU, MEM)", "URL"
            ],
                     tablefmt="plain"))
        print("\n" + 80 * "=")
    except (Exception) as e:
        print("Something went wrong:\n%s" % (e))
        print("Consider validating your deployment with `kploy dryrun` first!")
        sys.exit(1)
示例#27
0
def cmd_list(param):
    """
    Lists app resources and their status.
    """
    here = os.path.realpath(".")
    kployfile = os.path.join(here, DEPLOYMENT_DESCRIPTOR)
    if VERBOSE:
        logging.info("Listing resource status of app based on %s " %
                     (kployfile))
    try:
        kploy, _ = util.load_yaml(filename=kployfile)
        print("Resources of app `%s/%s`:\n" %
              (kploy["namespace"], kploy["name"]))
        pyk_client = kploycommon._connect(api_server=kploy["apiserver"],
                                          debug=DEBUG)
        rc_manifests_confirmed, svc_manifests_confirmed = [], []
        services = os.path.join(here, SVC_DIR)
        rcs = os.path.join(here, RC_DIR)
        svc_list = kploycommon._visit(services, 'service', cache_remotes=True)
        rc_list = kploycommon._visit(rcs, 'RC', cache_remotes=True)
        res_list = []
        # gather Services status:
        print("[Services and RCs]\n")
        for svc in svc_list:
            svc_manifest, _ = util.load_yaml(
                filename=os.path.join(here, SVC_DIR, svc))
            svc_name = svc_manifest["metadata"]["name"]
            svc_path = "".join([
                "/api/v1/namespaces/", kploy["namespace"], "/services/",
                svc_name
            ])
            svc_URL = "".join([kploy["apiserver"], svc_path])
            svc_status = kploycommon._check_status(pyk_client, svc_path)
            res_list.append([
                svc_name,
                os.path.join(SVC_DIR, svc), "service", svc_status, svc_URL
            ])
        # gather RC status:
        for rc in rc_list:
            rc_manifest, _ = util.load_yaml(
                filename=os.path.join(here, RC_DIR, rc))
            rc_name = rc_manifest["metadata"]["name"]
            rc_path = "".join([
                "/api/v1/namespaces/", kploy["namespace"],
                "/replicationcontrollers/", rc_name
            ])
            rc_URL = "".join([kploy["apiserver"], rc_path])
            rc_status = kploycommon._check_status(pyk_client, rc_path)
            res_list.append(
                [rc_name,
                 os.path.join(RC_DIR, rc), "RC", rc_status, rc_URL])
        print(
            tabulate(res_list, ["NAME", "MANIFEST", "TYPE", "STATUS", "URL"],
                     tablefmt="plain"))
        # gather Secrets status:
        print("\n" + 80 * "=")
        print("[Secrets]")
        sec_list = []
        secret_path = "".join([
            "/api/v1/namespaces/", kploy["namespace"], "/secrets/kploy-secrets"
        ])
        sec_URL = "".join([kploy["apiserver"], secret_path])
        secret = pyk_client.describe_resource(secret_path)
        if secret.status_code == 200:
            print("URL: %s" % (sec_URL))
            secret_data = secret.json()["data"]
            for k, v in secret_data.iteritems():
                sec_list.append([k, base64.b64decode(v)])
            print(tabulate(sec_list, ["KEY", "VALUE"], tablefmt="plain"))
        else:
            print("No env data deployed.")
        print("\n" + 80 * "=")
    except (Exception) as e:
        print("Something went wrong:\n%s" % (e))
        print("Consider validating your deployment with `kploy dryrun` first!")
        sys.exit(1)
    # count mypods
    response = kubeclient.execute_operation(method="GET", ops_path="/api/v1/namespaces/default/pods?labelSelector=name%3Dmypod")
    mypods = response.json()['items']
    running_mypods = len(mypods)
    print "{} running".format(running_mypods)

    # too many?
    if running_mypods > REPLICAS:
        to_delete = running_mypods - REPLICAS
        print "  Too many are running. Deleting {} pods:".format(to_delete)
        for pod in mypods[:to_delete]:
            print "    Deleting pod {}".format(pod['metadata']['name'])
            kubeclient.delete_resource(pod['metadata']['selfLink'])

    # too few?
    elif REPLICAS > running_mypods:
        to_launch = REPLICAS - running_mypods

        for n in range(0, to_launch):
            mypod_spec, _  = util.load_yaml(filename="mypod.yaml")
            mypod_spec["metadata"]["name"] += "-" + shortuuid.uuid()[:4].lower()

            print "Launching pod {}".format(mypod_spec["metadata"]["name"])
            response = kubeclient.execute_operation(method='POST',
                                         ops_path="/api/v1/namespaces/default/pods",
                                         payload=util.serialize_tojson(mypod_spec))
            if response.status_code >= 300:
                print "ERROR {}: {}".format(response.status_code, response.content)

    time.sleep(1)