Exemplo n.º 1
0
def check_phase(phase):
    if phase not in PHASE_CHOICES:
        error('phase %s not in available phases: %s.' % (phase, PHASE_CHOICES))
        warn(
            'phase can be added using: lain config save %s domain {{ domain }}'
            % phase)
        exit(1)
Exemplo n.º 2
0
def lain_yaml_data():
    if not os.path.exists(LAIN_YAML_PATH):
        error('Missing lain.yaml under current directory')
        sys.exit(1)
    with open(LAIN_YAML_PATH) as f:
        data = f.read()
    return yaml.load(data)
Exemplo n.º 3
0
def tag(phase):
    """
    Tag release and meta images
    """

    check_phase(phase)
    info("Taging meta and relese image ...")
    yml = lain_yaml(ignore_prepare=True)
    meta_version = yml.repo_meta_version()
    if meta_version is None:
        error("please git commit.")
        return None
    domain = get_domain(phase)
    registry = "registry.%s" % domain
    meta_tag = "%s:meta-%s" % (yml.appname, meta_version)
    release_tag = "%s:release-%s" % (yml.appname, meta_version)
    phase_meta_tag = docker.gen_image_name(yml.appname, 'meta', meta_version,
                                           registry)
    phase_release_tag = docker.gen_image_name(yml.appname, 'release',
                                              meta_version, registry)
    meta_code = docker.tag(meta_tag, phase_meta_tag)
    release_code = docker.tag(release_tag, phase_release_tag)
    if meta_code or release_code:
        error("Error lain tag.")
    else:
        info("Done lain tag.")
Exemplo n.º 4
0
def get_domain(phase):
    domain = user_config.get_config().get(phase, {}).get(DOMAIN_KEY, None)
    if not domain:
        error('please set %s domain by "lain config save %s %s ${%s_domain}"'
              % (phase, phase, DOMAIN_KEY, phase))
        exit(1)
    return domain
Exemplo n.º 5
0
def lain_yaml_data():
    if not os.path.exists(LAIN_YAML_PATH):
        error('Missing lain.yaml under current directory')
        sys.exit(1)
    with open(LAIN_YAML_PATH) as f:
        data = f.read()
    return yaml.load(data)
Exemplo n.º 6
0
def authorize_and_check(phase, appname):
    role = get_role(phase, appname)

    # if unauthorized, refresh first
    if role == 'unauthorized':
        if not sso_refresh(phase):
            error('please login first')
            exit(1)
        role = get_role(phase, appname)
    # after refresh, should be authorized
    if role == 'unauthorized':
        error('still unauthorized after refresh')
        exit(1)
    elif role in ['wrong status', 'error', 'unknown']:
        error('shit happened when getting role')
        exit(1)
    elif role == 'no role':
        error('you have not a role of the app {}'.format(appname))
        error('please contact maintainers of the app')
        exit(1)
    elif role == 'no app':
        # no app, let it go
        warn('app {} does not exist, passed by.'.format(appname))
        return None
    else:
        # valid role
        return role
Exemplo n.º 7
0
def gen_run_ctx(proc_name):
    yml = lain_yaml(ignore_prepare=True)
    proc = yml.procs.get(proc_name, None)
    if proc is None:
        error('proc {} does not exist'.format(proc_name))
        exit(1)
    container_name = "{}.{}.{}".format(yml.appname, proc.type.name, proc.name)
    image = yml.img_names['release']
    port = proc.port.keys()[0] if proc.port.keys() else None
    working_dir = proc.working_dir or DOCKER_APP_ROOT
    cmd = proc.cmd
    env = proc.env
    extra_env = [
        'TZ=Asia/Shanghai',
        'LAIN_APPNAME={}'.format(yml.appname),
        'LAIN_PROCNAME={}'.format(proc.name),
        'LAIN_DOMAIN=lain.local',
        'DEPLOYD_POD_INSTANCE_NO=1',
        'DEPLOYD_POD_NAME={}'.format(container_name),
        'DEPLOYD_POD_NAMESPACE={}'.format(yml.appname)
    ]
    volumes = {}
    local_proc_volume_base = os.path.join(LOCAL_VOLUME_BASE, container_name)
    if proc.volumes:
        for v in proc.volumes:
            container_path = os.path.join(local_proc_volume_base, v)
            host_path = local_proc_volume_base + container_path
            volumes[host_path] = container_path
    return container_name, image, working_dir, port, cmd, env + extra_env, volumes, local_proc_volume_base
Exemplo n.º 8
0
def get_domain(phase):
    domain = user_config.get_config().get(phase, {}).get(DOMAIN_KEY, None)
    if not domain:
        error('please set %s domain by "lain config save %s %s ${%s_domain}"' %
              (phase, phase, DOMAIN_KEY, phase))
        exit(1)
    return domain
Exemplo n.º 9
0
    def show(cls, phase, procname, path=None):
        """
        show secret file of special procname in different phase

        path: absolute path of config file, eg : /lain/app/config
        """

        check_phase(phase)
        yml = lain_yaml(ignore_prepare=True)
        authorize_and_check(phase, yml.appname)
        auth_header = get_auth_header(SSOAccess.get_token(phase))
        proc = yml.procs.get(procname, None)
        if proc is None:
            error('proc {} does not exist'.format(procname))
            exit(1)

        podgroup_name = "{}.{}.{}".format(yml.appname, proc.type.name,
                                          proc.name)
        lvault_url = "http://lvault.%s/v2/secrets?app=%s&proc=%s" % (
            get_domain(phase), yml.appname, podgroup_name)
        if path:
            lvault_url += "&path=%s" % path

        show_response = requests.get(lvault_url, headers=auth_header)
        if show_response.status_code < 300:
            info("secret file detail:")
            print(
                json.dumps(show_response.json(),
                           encoding="utf-8",
                           ensure_ascii=False,
                           indent=2))
        else:
            error("shit happened : %s" % show_response.text)
Exemplo n.º 10
0
def gen_run_ctx(proc_name):
    yml = lain_yaml(ignore_prepare=True)
    proc = yml.procs.get(proc_name, None)
    if proc is None:
        error('proc {} does not exist'.format(proc_name))
        exit(1)
    container_name = "{}.{}.{}".format(yml.appname, proc.type.name, proc.name)
    image = yml.img_names['release']
    port = proc.port.keys()[0] if proc.port.keys() else None
    working_dir = proc.working_dir or DOCKER_APP_ROOT
    cmd = proc.cmd
    env = proc.env
    extra_env = [
        'TZ=Asia/Shanghai', 'LAIN_APPNAME={}'.format(yml.appname),
        'LAIN_PROCNAME={}'.format(proc.name), 'LAIN_DOMAIN=lain.local',
        'DEPLOYD_POD_INSTANCE_NO=1',
        'DEPLOYD_POD_NAME={}'.format(container_name),
        'DEPLOYD_POD_NAMESPACE={}'.format(yml.appname)
    ]
    volumes = {}
    local_proc_volume_base = os.path.join(LOCAL_VOLUME_BASE, container_name)
    if proc.volumes:
        for v in proc.volumes:
            container_path = os.path.join(local_proc_volume_base, v)
            host_path = local_proc_volume_base + container_path
            volumes[host_path] = container_path
    return container_name, image, working_dir, port, cmd, env + extra_env, volumes, local_proc_volume_base
Exemplo n.º 11
0
    def show(cls, phase, procname, path=None):
        """
        show secret file of special procname in different phase

        path: absolute path of config file, eg : /lain/app/config
        """

        check_phase(phase)
        yml = lain_yaml(ignore_prepare=True)
        authorize_and_check(phase, yml.appname)
        auth_header = get_auth_header(SSOAccess.get_token(phase))
        proc = yml.procs.get(procname, None)
        if proc is None:
            error('proc {} does not exist'.format(procname))
            exit(1)

        podgroup_name = "{}.{}.{}".format(yml.appname, proc.type.name, proc.name)       
        lvault_url = "http://lvault.%s/v2/secrets?app=%s&proc=%s" % (
            get_domain(phase), yml.appname, podgroup_name)
        if path:
            lvault_url += "&path=%s" % path
        
        show_response = requests.get(lvault_url, headers=auth_header)
        if show_response.status_code < 300:
            info("secret file detail:")
            print(json.dumps(show_response.json(), encoding="utf-8", ensure_ascii=False, indent=2))
        else:
            error("shit happened : %s" % show_response.text)
Exemplo n.º 12
0
def push(phase):
    """
    Push release and meta images
    """

    check_phase(phase)
    info("Pushing meta and release images ...")
    yml = lain_yaml(ignore_prepare=True)
    meta_version = yml.repo_meta_version()
    if meta_version is None:
        error("please git commit.")
        return None
    domain = get_domain(phase)

    registry = "registry.%s" % domain
    phase_meta_tag = docker.gen_image_name(yml.appname, 'meta', meta_version,
                                           registry)
    phase_release_tag = docker.gen_image_name(yml.appname, 'release',
                                              meta_version, registry)
    meta_code = docker.push(phase_meta_tag)
    release_code = docker.push(phase_release_tag)
    if meta_code or release_code:
        error("Error lain push.")
        sys.exit(1)
    else:
        info("Done lain push.")
        info("notifying lain push.")
        access_token = SSOAccess.get_token(phase)
        auth_header = get_auth_header(access_token)
        last_commit_id = fetch_last_commit_id(domain, yml.appname, auth_header)
        if last_commit_id is not None:
            notify_diffs(domain, yml.appname, last_commit_id, auth_header)
        else:
            warn("Notified Nothing!")
        info("Done notifying lain push.")
Exemplo n.º 13
0
def build(push=False, release=False):
    """
    Build release and meta images
    """

    info("Building meta and release images ...")
    validate_only_warning()
    yml = lain_yaml()
    meta_version = yml.repo_meta_version()
    use_prepare = docker.exist(yml.img_names['prepare'])
    use_build = release and docker.exist(yml.img_names['build'])
    release_suc, release_name = yml.build_release(use_prepare, use_build)
    (meta_suc, meta_name) = (False,
                             '') if not release_suc else yml.build_meta()
    if not (release_suc and meta_suc):
        sys.exit(1)
    if meta_version is None:
        warn("please git commit.")
    if push:
        if meta_version is None:
            error("need git commit SHA1.")
            return None
        tag_release_name = yml.tag_meta_version(release_name)
        docker.push(tag_release_name)

        tag_meta_name = yml.tag_meta_version(meta_name)
        docker.push(tag_meta_name)
    info("Done lain build.")
Exemplo n.º 14
0
def push(phase):
    """
    Push release and meta images
    """

    check_phase(phase)
    info("Pushing meta and release images ...")
    yml = lain_yaml(ignore_prepare=True)
    meta_version = yml.repo_meta_version()
    if meta_version is None:
        error("please git commit.")
        return None
    domain = get_domain(phase)

    registry = "registry.%s" % domain
    phase_meta_tag = docker.gen_image_name(
        yml.appname, 'meta', meta_version, registry)
    phase_release_tag = docker.gen_image_name(
        yml.appname, 'release', meta_version, registry)
    meta_code = docker.push(phase_meta_tag)
    release_code = docker.push(phase_release_tag)
    if meta_code or release_code:
        error("Error lain push.")
        sys.exit(1)
    else:
        info("Done lain push.")
        info("notifying lain push.")
        access_token = SSOAccess.get_token(phase)
        auth_header = get_auth_header(access_token)
        last_commit_id = fetch_last_commit_id(domain, yml.appname, auth_header)
        if last_commit_id is not None:
            notify_diffs(domain, yml.appname, last_commit_id, auth_header)
        else:
            warn("Notified Nothing!")
        info("Done notifying lain push.")
Exemplo n.º 15
0
def attach(phase, proc_name, instance_no, target=None):
    """
    Attach the stdout/stderr of the container
    """

    check_phase(phase)
    yml = lain_yaml(ignore_prepare=True)
    appname = target if target else yml.appname
    authorize_and_check(phase, appname)
    domain = get_domain(phase)
    access_token = SSOAccess.get_token(phase)
    endpoint = "wss://entry.%s/attach" % domain
    header_data = [
        "access-token: %s" % access_token,
        "app-name: %s" % appname,
        "proc-name: %s" % proc_name,
        "instance-no: %s" % instance_no
    ]
    try:
        client = EntryClient(endpoint, header=header_data)
        info(
            "Start to attach the stdout/stderr of the container. Press <Ctrl+c> to stop..."
        )
        client.attach_container()
    except KeyboardInterrupt:
        pass
    except:
        error("Server stops the connection. Ask admin for help.")
Exemplo n.º 16
0
def validate_only_warning():
    valid, _ = _validate()
    if not valid:
        error('##############################')
        error('#  maybe invalid lain.yaml   #')
        error('#  check the schema with     #')
        error('#    lain validate           #')
        error('##############################')
Exemplo n.º 17
0
def print_available_version(version, version_list):
    if not version_list:
        error("No available versions, please push first.")
        return
    if version:
        error("Version %s not exist." % version)
    info("Below are the available versions: ")
    for version in version_list:
        print(version)
Exemplo n.º 18
0
def print_available_version(version, version_list):
    if not version_list:
        error("No available versions, please push first.")
        return
    if version:
        error("Version %s not exist." % version)
    info("Below are the available versions: ")
    for version in version_list:
        print(version)
Exemplo n.º 19
0
def print_available_repos(console, auth_header):
    repos_url = "http://%s/api/v1/repos/" % console
    repos_res = requests.get(repos_url, headers=auth_header)
    info('Available repos are :')
    if repos_res.status_code == 200:
        repos = repos_res.json()["repos"]
        render_repos([repo["appname"] for repo in repos])
        print('')
    else:
        error("shit happened : %s" % repos_res.content)
Exemplo n.º 20
0
def print_available_repos(console, auth_header):
    repos_url = "http://%s/api/v1/repos/" % console
    repos_res = requests.get(repos_url, headers=auth_header)
    info('Available repos are :')
    if repos_res.status_code == 200:
        repos = repos_res.json()["repos"]
        render_repos([repo["appname"] for repo in repos])
        print('')
    else:
        error("shit happened : %s" % repos_res.content)
Exemplo n.º 21
0
def meta():
    """
    Show current meta version
    """

    meta_version = lain_yaml(ignore_prepare=True).repo_meta_version()
    if meta_version is None:
        error("please git commit.")
    else:
        info("meta version : %s" % lain_yaml(ignore_prepare=True).repo_meta_version())
Exemplo n.º 22
0
def check(phase):    
    """
    Check current version of release and meta images in the remote registry
    """

    check_phase(phase)
    tag_ok = _check_phase_tag(phase)
    if tag_ok:
        info("Image Tag OK in registry")
    else:
        error("Image Tag not OK in registry")
Exemplo n.º 23
0
def deploy_app(phase, appname, console, auth_header, version, output):
    info("Begin deploy app %s to %s ..." % (appname, phase))

    app_url = "http://%s/api/v1/apps/%s/" % (console, appname)
    apps_url = "http://%s/api/v1/apps/" % console

    app_r = requests.get(app_url, headers=auth_header)
    former_version, deploy_version = None, version
    if app_r.status_code == 200:
        operation = "upgrading"
        deploy_params = None
        if not is_resource_instance(appname):
            former_version = app_r.json()["app"]["metaversion"]
            exist, valid_version = check_meta_version(phase, appname,
                                                      deploy_version)
            if not exist:
                print_available_version(deploy_version, valid_version)
                exit(1)

            if deploy_version:
                deploy_params = {"meta_version": deploy_version}
            else:
                deploy_version = valid_version

        deploy_r = requests.put(app_url,
                                headers=auth_header,
                                json=deploy_params)
    elif app_r.status_code == 404:
        operation = "deploying"
        payload = {'appname': appname}
        deploy_r = requests.post(apps_url,
                                 headers=auth_header,
                                 data=json.dumps(payload),
                                 timeout=120)
    else:
        error("shit happend: %s" % app_r.content)
        exit(1)

    if deploy_r.status_code < 300:
        if output != 'pretty':
            info("%s" % deploy_r.json()['msg'])
            info("app status: ")
            render_app_status(deploy_r.json()['app'], output=output)
        else:
            check_deploy_result(operation, console, appname, auth_header)
        if former_version:
            info("app {} deploy operation:".format(appname))
            info("    last version: {}".format(former_version))
            info("    this version: {}".format(deploy_version))
            info("if shit happened, rollback your app by:")
            info("    lain deploy -v {}".format(former_version))
    else:
        error("deploy latest version of %s to %s failed: %s" %
              (appname, phase, deploy_r.json()['msg']))
Exemplo n.º 24
0
def meta():
    """
    Show current meta version
    """

    meta_version = lain_yaml(ignore_prepare=True).repo_meta_version()
    if meta_version is None:
        error("please git commit.")
    else:
        info("meta version : %s" %
             lain_yaml(ignore_prepare=True).repo_meta_version())
Exemplo n.º 25
0
def print_available_apps(console, auth_header, sort_type):
    apps_url = "http://%s/api/v1/apps/" % console
    apps_res = requests.get(apps_url, headers=auth_header)
    info('Available apps are :')
    print("{:<30}  {:<20}  {:<60}  {:<10}".format("Appname", "AppType",
                                                  "MetaVersion", "State"))
    if apps_res.status_code == 200:
        apps = apps_res.json()["apps"]
        render_apps([AppInfo.new(app) for app in apps], sort_type)
    else:
        error("shit happened: %s" % apps_res.content)
Exemplo n.º 26
0
def print_available_apps(console, auth_header, sort_type):
    apps_url = "http://%s/api/v1/apps/" % console
    apps_res = requests.get(apps_url, headers=auth_header)
    info('Available apps are :')
    print("{:<30}  {:<20}  {:<60}  {:<10}".format(
        "Appname", "AppType", "MetaVersion", "State"))
    if apps_res.status_code == 200:
        apps = apps_res.json()["apps"]
        render_apps([AppInfo.new(app) for app in apps], sort_type)
    else:
        error("shit happened: %s" % apps_res.content)
Exemplo n.º 27
0
 def get_sso_url(cls, phase):
     try:
         sso_url = user_config.get_config().get(phase, {}).get(SSO_URL_KEY, None)
         if not sso_url:
             error(
                 'please set %s sso url by "lain config save %s %s ${%s_sso_url}"'
                 % (phase, phase, SSO_URL_KEY, phase))
             exit(1)
         return sso_url
     except Exception as e:
         error('error get %s sso url: %s' % (phase, e))
         return ''
Exemplo n.º 28
0
def prepare():
    """
    Build prepare image
    """

    validate_only_warning()
    info("Generating prepare image...")
    if not lain_yaml().build_prepare()[0]:
        error("Error lain prepare.")
        sys.exit(1)
    else:
        info("Done lain prepare.")
        sys.exit(0)
Exemplo n.º 29
0
def undeploy_app(appname, console, auth_header):
    delete_url = "http://%s/api/v1/apps/%s/" % (console, appname)
    delete_r = requests.delete(delete_url, headers=auth_header)
    try:
        if delete_r.status_code == 202:
            info("delete app %s success." % appname)
            info("delete result details: ")
            print(delete_r.json()['msg'])
        else:
            warn("delete app %s fail: %s" % (appname, delete_r.json()['msg']))
    except Exception:
        error("shit happend: %s" % delete_r.content)
        exit(1)
Exemplo n.º 30
0
def undeploy_proc(proc, appname, console, auth_header):
    proc_url = "http://%s/api/v1/apps/%s/procs/%s/" % (console, appname, proc)
    delete_r = requests.delete(proc_url, headers=auth_header)
    try:
        if delete_r.status_code == 202:
            info("delete proc %s success." % proc)
            info("delete result details: ")
            print(delete_r.json()['msg'])
        else:
            warn("delete proc %s fail: %s" % (proc, delete_r.json()['msg']))
    except Exception:
        error("shit happend: %s" % delete_r.content)
        exit(1)
Exemplo n.º 31
0
def ps(phase, output='pretty'):
    """
    Show basic deploy messages of app
    """

    check_phase(phase)
    yml = lain_yaml(ignore_prepare=True)
    authorize_and_check(phase, yml.appname)
    console = "console.%s" % get_domain(phase)

    access_token = SSOAccess.get_token(phase)
    auth_header = get_auth_header(access_token)

    repo_url = "http://%s/api/v1/repos/%s/" % (console, yml.appname)
    repo_r = requests.get(repo_url, headers=auth_header)
    if repo_r.status_code == 404:
        error('app {} has not been reposited at {}'.format(yml.appname, phase))
        exit(1)
    elif repo_r.status_code == 200:
        pass
    else:
        error("shit happend: %s" % repo_r.content)
        exit(1)

    app_url = "http://%s/api/v1/apps/%s/" % (console, yml.appname)
    app_r = requests.get(app_url, headers=auth_header)
    if app_r.status_code == 200:
        app_status = app_r.json()["app"]
        render_app_status(app_status, output)
    elif app_r.status_code == 404:
        error('app {} has not been deployed at {}'.format(yml.appname, phase))
        exit(1)
    else:
        error("shit happend: %s" % repo_r.content)
        exit(1)
Exemplo n.º 32
0
def is_console_auth_activated(phase):
    domain = get_domain(phase)
    console = "console.%s" % domain
    apps_url = "http://%s/api/v1/apps/" % (console)

    apps_r = requests.get(apps_url)
    if apps_r.status_code == 401:
        return True
    elif apps_r.status_code == 200:
        return False
    else:
        error('shit happened when checking console auth status')
        error(apps_r.text)
        exit(1)
Exemplo n.º 33
0
def validate():
    """
    Validate lain.yaml
    """

    valid, msg = _validate()
    if valid:
        info('valid lain.yaml.')
    else:
        error('invalid lain.yaml.')
        warn('error message:')
        info(msg)
        # TODO : show related doc url
        warn('for details of lain.yaml schema please check related docs.')
        sys.exit(1)
Exemplo n.º 34
0
def get_role(phase, appname):
    # 404: {"msg": "user yisun4 does not exist in the app sso-ldap\n", "url": "/api/v1/repos/sso-ldap/maintainers/", "role": null}
    # 404: {"msg": "app with appname sso-ldap1 not exist", "url": "/api/v1/repos/", "role": null}
    # 401: {"msg": "unauthorized : don't have the access to the operation", "url": "/api/v1/docs/", "app": null}
    if not is_console_auth_activated(phase):
        return 'noauth-admin'
    no_role_pattern = re.compile(r"^user (.+) does not exist in the app (.+)$")
    no_app_pattern = re.compile(r"^app with appname (.+) not exist, has not been reposited yet")
    domain = get_domain(phase)
    console = "console.%s" % domain
    url = "http://%s/api/v1/repos/%s/roles/" % (console, appname)
    auth_header = get_auth_header(SSOAccess.get_token(phase))
    r = requests.get(url, headers=auth_header)
    if r.status_code == 401:
        return 'unauthorized'
    elif r.status_code == 200:
        try:
            r_json = r.json()
            return r_json["role"]["role"]
        except Exception as e:
            error(e)
            warn('DEBUG status: {}'.format(r.status_code))
            warn('DEBUG result: {}'.format(r.content))
            return 'error'
    elif r.status_code == 404:
        try:
            r_json = r.json()
            msg = r_json["msg"]
            if no_app_pattern.match(msg):
                return 'no app'
            elif no_role_pattern.match(msg):
                return 'no role'
            else:
                warn('DEBUG status: {}'.format(r.status_code))
                warn('unknown result: {}'.format(r_json))
                return 'unknown'
        except Exception as e:
            error(e)
            warn('DEBUG status: {}'.format(r.status_code))
            warn('DEBUG result: {}'.format(r.content))
            return 'error'
    else:
        warn('DEBUG status: {}'.format(r.status_code))
        warn('DEBUG content: {}'.format(r.content))
        return 'wrong status'
Exemplo n.º 35
0
def reposit_app(phase, appname, console, auth_header):
    payload = {'appname': appname}

    repo_url = "http://%s/api/v1/repos/%s/" % (console, appname)
    repos_url = "http://%s/api/v1/repos/" % console
    repo_r = requests.get(repo_url, headers=auth_header)
    if repo_r.status_code == 404:
        repos_r = requests.post(repos_url, headers=auth_header,
                                data=json.dumps(payload), timeout=120)
        if repos_r.status_code == 201:
            return 'reposit successfully'
        else:
            error("shit happened: %s" % repos_r.content)
            exit(1)
    elif repo_r.status_code == 200:
        return "already been reposited"
    else:
        error("shit happened: %s" % repo_r.content)
        exit(1)
Exemplo n.º 36
0
    def add(cls, phase, procname, path, content=None, file=None):
        """
        add secret file for different phase

        content: content of the secret file
        file: read secret content from a specify file
        """

        if file is None and content is None:
            error("need specify the content use -c or -f parameter")
            exit(1)

        if file is not None:
            try:
                f = open(file)
                content = f.read()
            except Exception, e:
                error("error read file %s : %s" % (file, str(e)))
                exit(1)
Exemplo n.º 37
0
    def add(cls, phase, procname, path, content=None, file=None):
        """
        add secret file for different phase

        content: content of the secret file
        file: read secret content from a specify file
        """

        if file is None and content is None:
            error("need specify the content use -c or -f parameter")
            exit(1)

        if file is not None:
            try:
                f = open(file)
                content = f.read()
            except Exception, e:
                error("error read file %s : %s" % (file, str(e)))
                exit(1)
Exemplo n.º 38
0
    def delete(cls, phase, username):
        """
        delete maintianer for different phase
        """

        check_phase(phase)
        yml = lain_yaml(ignore_prepare=True)
        authorize_and_check(phase, yml.appname)
        auth_header = get_auth_header(SSOAccess.get_token(phase))
        console = "console.%s" % get_domain(phase)
        
        maintainer_url = "http://%s/api/v1/repos/%s/maintainers/%s/" % (
            console, yml.appname, username)

        delete_response = requests.delete(maintainer_url, headers=auth_header)
        if delete_response.status_code < 300:
            info("delete successfully.")
        else:
            error("shit happened : %s" % delete_response.text)
Exemplo n.º 39
0
def reposit_app(phase, appname, console, auth_header):
    payload = {'appname': appname}

    repo_url = "http://%s/api/v1/repos/%s/" % (console, appname)
    repos_url = "http://%s/api/v1/repos/" % console
    repo_r = requests.get(repo_url, headers=auth_header)
    if repo_r.status_code == 404:
        repos_r = requests.post(repos_url,
                                headers=auth_header,
                                data=json.dumps(payload),
                                timeout=120)
        if repos_r.status_code == 201:
            return 'reposit successfully'
        else:
            error("shit happened: %s" % repos_r.content)
            exit(1)
    elif repo_r.status_code == 200:
        return "already been reposited"
    else:
        error("shit happened: %s" % repo_r.content)
        exit(1)
Exemplo n.º 40
0
    def add(cls, phase, username, role):
        """
        add maintianer for different phase
        """
        
        check_phase(phase)
        yml = lain_yaml(ignore_prepare=True)
        authorize_and_check(phase, yml.appname)
        auth_header = get_auth_header(SSOAccess.get_token(phase))
        console = "console.%s" % get_domain(phase)

        maintainer_url = "http://%s/api/v1/repos/%s/maintainers/" % (
            console, yml.appname)
        payload = {"username": username,
                   "role": role}

        add_response = requests.post(maintainer_url, headers=auth_header, json=payload)
        if add_response.status_code < 300:
            info("add successfully.")
        else:
            error("shit happened : %s" % add_response.text)
Exemplo n.º 41
0
def validate_parameters(cpu, memory, numinstances):
    if all([cpu is None, memory is None, numinstances is None]):
        warn("please input at least one param in cpu/memory/numinstances")
        exit(1)

    if numinstances is not None:
        try:
            numinstances = int(numinstances)
        except ValueError:
            warn('invalid parameter: num_instances (%s) should be integer' %
                 numinstances)
            exit(1)
        if numinstances <= 0:
            warn('invalid parameter: num_instances (%s) should > 0' %
                 numinstances)
            exit(1)

    if cpu is not None:
        try:
            cpu = int(cpu)
        except ValueError:
            warn('invalid parameter: cpu (%s) should be integer' % cpu)
            exit(1)
        if cpu < 0:
            warn('invalid parameter: cpu (%s) should >= 0' % cpu)
            exit(1)

    if memory is not None:
        memory = str(memory)
        try:
            if humanfriendly.parse_size(memory) < 4194304:
                error('invalid parameter: memory (%s) should >= 4M' % memory)
                exit(1)
        except humanfriendly.InvalidSize:
            error(
                'invalid parameter: memory (%s) humanfriendly.parse_size(memory) failed'
                % memory)
            exit(1)

    return cpu, memory, numinstances
Exemplo n.º 42
0
def deploy_proc(proc, appname, console, auth_header, output):
    info("Begin deploy proc %s from app %s ..." % (proc, appname))

    url = "http://%s/api/v1/apps/%s/procs/" % (console, appname)
    payload = {'procname': proc}
    deploy_r = requests.post(url, headers=auth_header,
                                 data=json.dumps(payload), timeout=120)
    if deploy_r.status_code < 300:
        info("deploy proc %s successfully." % proc)
        info("deploy result detail:")
        try:
            result = deploy_r.json()
            msg = result.pop('msg', '')
            if msg:
                print msg.decode('string_escape')
            info("proc status: ")
            render_proc_status(result.get('proc'), output=output)
        except Exception:
            pprint.pprint(deploy_r.content)
    else:
        error("deploy proc %s fail : %s" % (proc, deploy_r.json()['msg']))
        exit(1)
Exemplo n.º 43
0
    def delete(cls, phase, procname, path):
        """
        delete secret file for different phase
        """

        check_phase(phase)
        yml = lain_yaml(ignore_prepare=True)
        authorize_and_check(phase, yml.appname)
        auth_header = get_auth_header(SSOAccess.get_token(phase))
        proc = yml.procs.get(procname, None)
        if proc is None:
            error('proc {} does not exist'.format(procname))
            exit(1)

        podgroup_name = "{}.{}.{}".format(yml.appname, proc.type.name, proc.name)
        lvault_url = "http://lvault.%s/v2/secrets?app=%s&proc=%s&path=%s" % (
            get_domain(phase), yml.appname, podgroup_name, path)

        delete_response = requests.delete(lvault_url, headers=auth_header)
        if delete_response.status_code < 300:
            info("delete successfully.")
        else:
            error("shit happened : %s" % delete_response.text)
Exemplo n.º 44
0
def login(phase, cid=None, secret=None, redirect_uri=None):
    """
    Login specific phase, need open auth first

    cid: Client id get from the sso system, default: 3
    secret: Client secret get from the sso system, default: lain-cli_admin
    redirect_uri: Redirect uri get from the sso system, default: https://example.com/
    """

    check_phase(phase)
    username = raw_input('SSO Username:'******'SSO Password:'******'sso Login failed, Please try again!')
        exit(1)

    docker_login_success = docker_login(phase, username, password)
    if not docker_login_success:
        error('docker Login failed, Please try again!')
        exit(1)

    info("Login successfully!")
Exemplo n.º 45
0
def push(phase):
    """
    Push release and meta images
    """

    check_phase(phase)
    info("Pushing meta and release images ...")
    yml = lain_yaml(ignore_prepare=True)
    meta_version = yml.repo_meta_version()
    if meta_version is None:
        error("please git commit.")
        return None
    domain = get_domain(phase)
    registry = "registry.%s" % domain
    phase_meta_tag = docker.gen_image_name(yml.appname, 'meta', meta_version, registry)
    phase_release_tag = docker.gen_image_name(yml.appname, 'release', meta_version, registry)
    meta_code = docker.push(phase_meta_tag)
    release_code = docker.push(phase_release_tag)
    if meta_code or release_code:
        error("Error lain push.")
        sys.exit(1)
    else:
        info("Done lain push.")
Exemplo n.º 46
0
def tag(phase):
    """
    Tag release and meta images
    """

    check_phase(phase)
    info("Taging meta and relese image ...")
    yml = lain_yaml(ignore_prepare=True)
    meta_version = yml.repo_meta_version()
    if meta_version is None:
        error("please git commit.")
        return None
    domain = get_domain(phase)
    registry = "registry.%s" % domain
    meta_tag = "%s:meta-%s" % (yml.appname, meta_version)
    release_tag = "%s:release-%s" % (yml.appname, meta_version)
    phase_meta_tag = docker.gen_image_name(yml.appname, 'meta', meta_version, registry)
    phase_release_tag = docker.gen_image_name(yml.appname, 'release', meta_version, registry)
    meta_code = docker.tag(meta_tag, phase_meta_tag)
    release_code = docker.tag(release_tag, phase_release_tag)
    if meta_code or release_code:
        error("Error lain tag.")
    else:
        info("Done lain tag.")
Exemplo n.º 47
0
    def show(cls, phase, username=None):
        """
        show maintainers list or specical maitainer message of app in different phase

        username: sso username
        """
        
        check_phase(phase)
        yml = lain_yaml(ignore_prepare=True)
        authorize_and_check(phase, yml.appname)
        auth_header = get_auth_header(SSOAccess.get_token(phase))
        console = "console.%s" % get_domain(phase)

        maintainer_url = "http://%s/api/v1/repos/%s/maintainers/" % (
            console, yml.appname)
        if username:
            maintainer_url += '%s/' % username
        
        show_response = requests.get(maintainer_url, headers=auth_header)
        if show_response.status_code < 300:
            info("maintainer detail:")
            pprint.pprint(show_response.json())
        else:
            error("shit happened : %s" % show_response.text)
Exemplo n.º 48
0
def enter(phase, proc_name, instance_no, target=None):
    """
    Enter the container of specific proc
    """

    check_phase(phase)
    yml = lain_yaml(ignore_prepare=True)
    appname = target if target else yml.appname
    authorize_and_check(phase, appname)
    domain = get_domain(phase)
    access_token = SSOAccess.get_token(phase)

    term_type = os.environ.get("TERM", "xterm")
    endpoint = "wss://entry.%s/enter" % domain
    header_data = ["access-token: %s" % access_token,
                   "app-name: %s" % appname,
                   "proc-name: %s" % proc_name,
                   "instance-no: %s" % instance_no,
                   "term-type: %s" % term_type]
    try:
        client = EntryClient(endpoint, header=header_data)
        client.invoke_shell()
    except:
        error("Server stops the connection. Ask admin for help.")
Exemplo n.º 49
0
def validate_parameters(cpu, memory, numinstances):
    if all([cpu is None, memory is None, numinstances is None]):
        warn("please input at least one param in cpu/memory/numinstances")
        exit(1)

    if numinstances is not None:
        try:
            numinstances = int(numinstances)
        except ValueError:
            warn('invalid parameter: num_instances (%s) should be integer'%numinstances)
            exit(1)
        if numinstances <= 0:
            warn('invalid parameter: num_instances (%s) should > 0'%numinstances)
            exit(1)

    if cpu is not None:
        try:
            cpu = int(cpu)
        except ValueError:
            warn('invalid parameter: cpu (%s) should be integer'%cpu)
            exit(1)
        if cpu < 0:
            warn('invalid parameter: cpu (%s) should >= 0'%cpu)
            exit(1)

    if memory is not None:
        memory = str(memory)
        try:
            if humanfriendly.parse_size(memory) < 4194304:
                error('invalid parameter: memory (%s) should >= 4M'%memory)
                exit(1)
        except humanfriendly.InvalidSize:
            error('invalid parameter: memory (%s) humanfriendly.parse_size(memory) failed'%memory)
            exit(1)

    return cpu, memory, numinstances
Exemplo n.º 50
0
def attach(phase, proc_name, instance_no, target=None):
    """
    Attach the stdout/stderr of the container
    """

    check_phase(phase)
    yml = lain_yaml(ignore_prepare=True)
    appname = target if target else yml.appname
    authorize_and_check(phase, appname)
    domain = get_domain(phase)
    access_token = SSOAccess.get_token(phase)
    endpoint = "wss://entry.%s/attach" % domain
    header_data = ["access-token: %s" % access_token,
                   "app-name: %s" % appname,
                   "proc-name: %s" % proc_name,
                   "instance-no: %s" % instance_no]
    try:
        client = EntryClient(endpoint, header=header_data)
        info("Start to attach the stdout/stderr of the container. Press <Ctrl+c> to stop...")
        client.attach_container()
    except KeyboardInterrupt:
        pass
    except:
        error("Server stops the connection. Ask admin for help.")
Exemplo n.º 51
0
    def delete(cls, phase, procname, path):
        """
        delete secret file for different phase
        """

        check_phase(phase)
        yml = lain_yaml(ignore_prepare=True)
        authorize_and_check(phase, yml.appname)
        auth_header = get_auth_header(SSOAccess.get_token(phase))
        proc = yml.procs.get(procname, None)
        if proc is None:
            error('proc {} does not exist'.format(procname))
            exit(1)

        podgroup_name = "{}.{}.{}".format(yml.appname, proc.type.name,
                                          proc.name)
        lvault_url = "http://lvault.%s/v2/secrets?app=%s&proc=%s&path=%s" % (
            get_domain(phase), yml.appname, podgroup_name, path)

        delete_response = requests.delete(lvault_url, headers=auth_header)
        if delete_response.status_code < 300:
            info("delete successfully.")
        else:
            error("shit happened : %s" % delete_response.text)
Exemplo n.º 52
0
def deploy_app(phase, appname, console, auth_header, version, output):
    info("Begin deploy app %s to %s ..." % (appname, phase))

    app_url = "http://%s/api/v1/apps/%s/" % (console, appname)
    apps_url = "http://%s/api/v1/apps/" % console

    app_r = requests.get(app_url, headers=auth_header)
    former_version, deploy_version = None, version
    if app_r.status_code == 200:
        operation = "upgrading"
        deploy_params = None
        if not is_resource_instance(appname):
            former_version = app_r.json()["app"]["metaversion"]
            exist, valid_version = check_meta_version(phase, appname, deploy_version)
            if not exist:
                print_available_version(deploy_version, valid_version)
                exit(1)

            if deploy_version:
                deploy_params = {"meta_version": deploy_version}
            else:
                deploy_version = valid_version
        
        deploy_r = requests.put(app_url, headers=auth_header, json=deploy_params)
    elif app_r.status_code == 404:
        operation = "deploying"
        payload = {'appname': appname}
        deploy_r = requests.post(apps_url, headers=auth_header,
                                 data=json.dumps(payload), timeout=120)
    else:
        error("shit happend: %s" % app_r.content)
        exit(1)

    if deploy_r.status_code < 300:
        if output != 'pretty':
            info("%s" % deploy_r.json()['msg'])
            info("app status: ")
            render_app_status(deploy_r.json()['app'], output=output)
        else:
            result = check_deploy_result(operation, console, appname, auth_header)
            if result != 'Done':
                error("deploy latest version of %s to %s failed: %s" % (appname, phase, result))
                exit(1)
        if former_version:
            info("app {} deploy operation:".format(appname))
            info("    last version: {}".format(former_version))
            info("    this version: {}".format(deploy_version))
            info("if shit happened, rollback your app by:")
            info("    lain deploy -v {}".format(former_version))
    else:
        error("deploy latest version of %s to %s failed: %s" % (appname, phase, deploy_r.json()['msg']))
        exit(1)
Exemplo n.º 53
0
def ps(phase, output='pretty'):
    """
    Show basic deploy messages of app
    """

    check_phase(phase)
    yml = lain_yaml(ignore_prepare=True)
    authorize_and_check(phase, yml.appname)
    console = "console.%s" % get_domain(phase)

    access_token = SSOAccess.get_token(phase)
    auth_header = get_auth_header(access_token)

    repo_url = "http://%s/api/v1/repos/%s/" % (console, yml.appname)
    repo_r = requests.get(repo_url, headers=auth_header)
    if repo_r.status_code == 404:
        error('app {} has not been reposited at {}'.format(
            yml.appname, phase
        ))
        exit(1)
    elif repo_r.status_code == 200:
        pass
    else:
        error("shit happend: %s" % repo_r.content)
        exit(1)

    app_url = "http://%s/api/v1/apps/%s/" % (console, yml.appname)
    app_r = requests.get(app_url, headers=auth_header)
    if app_r.status_code == 200:
        app_status = app_r.json()["app"]
        render_app_status(app_status, output)
    elif app_r.status_code == 404:
        error('app {} has not been deployed at {}'.format(
            yml.appname, phase
        ))
        exit(1)
    else:
        error("shit happend: %s" % repo_r.content)
        exit(1)
Exemplo n.º 54
0
def _check_phase_tag(phase):
    yml = lain_yaml(ignore_prepare=True)
    meta_version = yml.repo_meta_version()
    if meta_version is None:
        error("please git commit.")
        return None
    domain = get_domain(phase)
    registry = "registry.%s" % domain
    metatag = "meta-%s"%meta_version
    releasetag = "release-%s"%meta_version
    tag_list = docker.get_tag_list_in_registry(registry, yml.appname)
    tag_ok = True
    if metatag not in tag_list:
        tag_ok = False
        error("%s/%s:%s not exist." % (registry, yml.appname, metatag))
    else:
        info("%s/%s:%s exist." % (registry, yml.appname, metatag))
    if releasetag not in tag_list:
        tag_ok = False
        error("%s/%s:%s not exist." % (registry, yml.appname, releasetag))
    else:
        info("%s/%s:%s exist." % (registry, yml.appname, releasetag))
    return tag_ok