예제 #1
0
파일: images.py 프로젝트: opsbay/hokusai
def images():
    images = ECR().get_images()
    print('')
    print_green('Image Pushed At           | Image Tags')
    print_green('----------------------------------------------------------')
    for image in sorted(images, key=itemgetter('imagePushedAt'), reverse=True):
        if 'imageTags' not in image.keys():
            continue
        print("%s | %s" %
              (image['imagePushedAt'], ', '.join(image['imageTags'])))
예제 #2
0
def k8s_delete(context, namespace=None, yaml_file_name=None):
    if yaml_file_name is None: yaml_file_name = context
    kubernetes_yml = os.path.join(os.getcwd(),
                                  "hokusai/%s.yml" % yaml_file_name)
    if not os.path.isfile(kubernetes_yml):
        raise HokusaiError("Yaml file %s does not exist." % kubernetes_yml)

    kctl = Kubectl(context, namespace=namespace)
    shout(kctl.command("delete -f %s" % kubernetes_yml), print_output=True)
    print_green("Deleted Kubernetes environment %s" % kubernetes_yml)
예제 #3
0
def gitcompare(org_name, git_compare_link):
  ecr = ECR()

  staging_tag = ecr.find_git_sha1_image_tag('staging')
  if staging_tag is None:
    raise HokusaiError("Could not find a tag for staging.  Aborting.")

  production_tag = ecr.find_git_sha1_image_tag('production')
  if production_tag is None:
    raise HokusaiError("Could not find a git SHA1 tag for production.  Aborting.")

  print_green(git_compare_link % (org_name, config.project_name, production_tag, staging_tag))
예제 #4
0
def push(tag, build, force, overwrite, skip_latest=False):
    if force is None and shout('git status --porcelain'):
        raise HokusaiError("Working directory is not clean.  Aborting.")

    if force is None and shout('git status --porcelain --ignored'):
        raise HokusaiError(
            "Working directory contains ignored files and/or directories.  Aborting."
        )

    ecr = ECR()
    if not ecr.project_repo_exists():
        raise HokusaiError(
            "ECR repo %s does not exist... did you run `hokusai setup` for this project?"
            % config.project_name)

    shout(ecr.get_login())
    if tag is None:
        tag = shout('git rev-parse HEAD').strip()

    if overwrite is None and ecr.tag_exists(tag):
        raise HokusaiError("Tag %s already exists in registry.  Aborting." %
                           tag)

    if build:
        docker_compose_yml = os.path.join(os.getcwd(), 'hokusai/build.yml')
        legacy_docker_compose_yml = os.path.join(os.getcwd(),
                                                 'hokusai/common.yml')
        if not os.path.isfile(docker_compose_yml) and not os.path.isfile(
                legacy_docker_compose_yml):
            raise HokusaiError("Yaml files %s / %s do not exist." %
                               (docker_compose_yml, legacy_docker_compose_yml))
        if os.path.isfile(docker_compose_yml):
            shout("docker-compose -f %s -p hokusai build" % docker_compose_yml,
                  print_output=True)
        if os.path.isfile(legacy_docker_compose_yml):
            shout("docker-compose -f %s -p hokusai build" %
                  legacy_docker_compose_yml,
                  print_output=True)

    build_tag = "hokusai_%s:latest" % config.project_name

    shout("docker tag %s %s:%s" % (build_tag, ecr.project_repo, tag))
    shout("docker push %s:%s" % (ecr.project_repo, tag), print_output=True)
    print_green("Pushed %s to %s:%s" % (build_tag, ecr.project_repo, tag))

    if skip_latest: return

    shout("docker tag %s %s:%s" % (build_tag, ecr.project_repo, 'latest'))
    shout("docker push %s:%s" % (ecr.project_repo, 'latest'),
          print_output=True)
    print_green("Pushed %s to %s:%s" % (build_tag, ecr.project_repo, 'latest'))
예제 #5
0
파일: retag.py 프로젝트: artsy/hokusai
def retag(tag_to_change, tag_to_match):
    ecr = ECR()

    if not ecr.project_repo_exists():
        raise HokusaiError("Project repo does not exist. Aborting.")

    try:
        ecr.retag(tag_to_match, tag_to_change)
        print_green(
            "Updated ECR '%s' tag to point to the image that '%s' tag points to."
            % (tag_to_change, tag_to_match),
            newline_after=True)
    except (ValueError, ClientError) as e:
        raise HokusaiError("Updating ECR tag failed due to the error: '%s'" %
                           str(e))
예제 #6
0
def gitdiff():
    ecr = ECR()

    staging_tag = ecr.find_git_sha1_image_tag('staging')
    if staging_tag is None:
        raise HokusaiError("Could not find a tag for staging.  Aborting.")

    production_tag = ecr.find_git_sha1_image_tag('production')
    if production_tag is None:
        raise HokusaiError(
            "Could not find a git SHA1 tag for production.  Aborting.")

    print_green("Comparing %s to %s" % (production_tag, staging_tag))
    for remote in shout('git remote').splitlines():
        shout("git fetch %s" % remote)
    shout("git diff %s %s" % (production_tag, staging_tag), print_output=True)
예제 #7
0
파일: kubernetes.py 프로젝트: artsy/hokusai
def k8s_delete(context, namespace=None, filename=None):
  if filename is None:
    yaml_template = TemplateSelector().get(os.path.join(CWD, HOKUSAI_CONFIG_DIR, context))
  else:
    yaml_template = TemplateSelector().get(filename)

  if filename is None:
    configmap = ConfigMap(context, namespace=namespace)
    configmap.destroy()
    print_green("Deleted configmap %s-environment" % config.project_name)

  kctl = Kubectl(context, namespace=namespace)
  yaml_spec = YamlSpec(yaml_template).to_file()

  shout(kctl.command("delete -f %s" % yaml_spec), print_output=True)
  print_green("Deleted Kubernetes environment %s" % yaml_template)
예제 #8
0
def configure(kubectl_version, bucket_name, key_name, platform, install_to,
              install_config_to):
    print_green("Downloading and installing kubectl...")
    urllib.urlretrieve(
        "https://storage.googleapis.com/kubernetes-release/release/v%s/bin/%s/amd64/kubectl"
        % (kubectl_version, platform), os.path.join('/tmp', 'kubectl'))
    os.chmod(os.path.join('/tmp', 'kubectl'), 0755)
    shutil.move(os.path.join('/tmp', 'kubectl'),
                os.path.join(install_to, 'kubectl'))

    print_green("Configuring kubectl...")
    if not os.path.isdir(install_config_to):
        mkpath(install_config_to)

    bucket = boto3.resource('s3').Bucket(bucket_name)
    bucket.download_file(key_name, os.path.join(install_config_to, 'config'))
예제 #9
0
파일: kubernetes.py 프로젝트: rm3l/hokusai
def k8s_update(context,
               namespace=None,
               filename=None,
               check_branch="master",
               check_remote=None,
               skip_checks=False,
               dry_run=False):
    if filename is None:
        kubernetes_yml = os.path.join(CWD, HOKUSAI_CONFIG_DIR,
                                      "%s.yml" % context)
    else:
        kubernetes_yml = filename

    if not os.path.isfile(kubernetes_yml):
        raise HokusaiError("Yaml file %s does not exist." % kubernetes_yml)

    if not skip_checks:
        current_branch = None
        for branchname in shout('git branch').splitlines():
            if '* ' in branchname:
                current_branch = branchname.replace('* ', '')
                break

        if 'detached' in current_branch:
            raise HokusaiError("Not on any branch!  Aborting.")
        if current_branch != check_branch:
            raise HokusaiError("Not on %s branch!  Aborting." % check_branch)

        remotes = [check_remote
                   ] if check_remote else shout('git remote').splitlines()
        for remote in remotes:
            shout("git fetch %s" % remote)
            if returncode("git diff --quiet %s/%s" % (remote, current_branch)):
                raise HokusaiError(
                    "Local branch %s is divergent from %s/%s.  Aborting." %
                    (current_branch, remote, current_branch))

    kctl = Kubectl(context, namespace=namespace)

    if dry_run:
        shout(kctl.command("apply -f %s --dry-run" % kubernetes_yml),
              print_output=True)
        print_green("Updated Kubernetes environment %s (dry run)" %
                    kubernetes_yml)
    else:
        shout(kctl.command("apply -f %s" % kubernetes_yml), print_output=True)
        print_green("Updated Kubernetes environment %s" % kubernetes_yml)
예제 #10
0
파일: test.py 프로젝트: jo-rs/hokusai
def test(build, cleanup, filename, service_name):
    if filename is None:
        yaml_template = TemplateSelector().get(
            os.path.join(CWD, HOKUSAI_CONFIG_DIR, TEST_YML_FILE))
    else:
        yaml_template = TemplateSelector().get(filename)

    docker_compose_yml = YamlSpec(yaml_template).to_file()
    follow_extends(docker_compose_yml)

    def on_cleanup(*args):
        shout("docker-compose -f %s -p hokusai stop" % docker_compose_yml)
        shout("docker-compose -f %s -p hokusai rm --force" %
              docker_compose_yml)

    if cleanup:
        for sig in EXIT_SIGNALS:
            signal.signal(sig, on_cleanup)

    opts = ' --abort-on-container-exit'
    if build:
        Docker().build()

    if service_name is None:
        service_name = config.project_name

    print_green("Starting test environment... Press Ctrl+C to stop.",
                newline_after=True)
    try:
        shout("docker-compose -f %s -p hokusai up%s" %
              (docker_compose_yml, opts),
              print_output=True)
        return_code = int(shout("docker wait hokusai_%s_1" % service_name))
    except CalledProcessError:
        if cleanup: on_cleanup()
        raise HokusaiError('Tests Failed')

    if return_code:
        raise HokusaiError('Tests Failed - Exit Code: %s\n' % return_code,
                           return_code=return_code)
    else:
        print_green("Tests Passed")

    if cleanup: on_cleanup()

    return return_code
예제 #11
0
파일: kubernetes.py 프로젝트: rm3l/hokusai
def k8s_delete(context, namespace=None, filename=None):
    if filename is None:
        kubernetes_yml = os.path.join(CWD, HOKUSAI_CONFIG_DIR,
                                      "%s.yml" % context)
    else:
        kubernetes_yml = filename

    if not os.path.isfile(kubernetes_yml):
        raise HokusaiError("Yaml file %s does not exist." % kubernetes_yml)

    if filename is None:
        configmap = ConfigMap(context, namespace=namespace)
        configmap.destroy()
        print_green("Deleted configmap %s-environment" % config.project_name)

    kctl = Kubectl(context, namespace=namespace)
    shout(kctl.command("delete -f %s" % kubernetes_yml), print_output=True)
    print_green("Deleted Kubernetes environment %s" % kubernetes_yml)
예제 #12
0
def configure(kubectl_version, bucket_name, key_name, config_file, platform, install_to, install_config_to):
  if not ((bucket_name and key_name) or config_file):
    raise HokusaiError("Must define bucket_name and key_name or config_file")

  print_green("Downloading and installing kubectl...")
  urllib.urlretrieve("https://storage.googleapis.com/kubernetes-release/release/v%s/bin/%s/amd64/kubectl" % (kubectl_version, platform), os.path.join('/tmp', 'kubectl'))
  os.chmod(os.path.join('/tmp', 'kubectl'), 0755)
  shutil.move(os.path.join('/tmp', 'kubectl'), os.path.join(install_to, 'kubectl'))

  print_green("Configuring kubectl...")
  if not os.path.isdir(install_config_to):
    mkpath(install_config_to)

  if bucket_name and key_name:
    client = boto3.client('s3', region_name=get_region_name())
    client.download_file(bucket_name, key_name, os.path.join(install_config_to, 'config'))
  else:
    shutil.copy(config_file, os.path.join(install_config_to, 'config'))
예제 #13
0
파일: deployment.py 프로젝트: artsy/hokusai
    def refresh(self):
        for deployment in self.cache:
            print_green("Refreshing %s..." % deployment['metadata']['name'],
                        newline_after=True)
            shout(
                self.kctl.command("rollout restart deployment/%s" %
                                  deployment['metadata']['name']))

        print_green("Waiting for refresh to complete...")

        rollout_commands = [
            self.kctl.command("rollout status deployment/%s" %
                              deployment['metadata']['name'])
            for deployment in self.cache
        ]
        return_codes = shout_concurrent(rollout_commands, print_output=True)
        if any(return_codes):
            raise HokusaiError("Refresh failed!")
예제 #14
0
def configure(kubectl_version, bucket_name, key_name, config_file, install_to,
              install_config_to):
    if global_config.is_present(
    ) and global_config.kubectl_version is not None:
        kubectl_version = global_config.kubectl_version

    if not kubectl_version:
        raise HokusaiError("You must supply a kubectl_version")

    if global_config.is_present(
    ) and global_config.kubectl_config_file is not None:
        uri = urlparse(global_config.kubectl_config_file)
        if uri.scheme == 's3':
            bucket_name = uri.netloc
            key_name = uri.path
        if uri.scheme == 'file':
            key_name = uri.path

    if not ((bucket_name and key_name) or config_file):
        raise HokusaiError("You must define valid config_file")

    print_green("Downloading and installing kubectl...",
                newline_before=True,
                newline_after=True)
    tmpdir = tempfile.mkdtemp()
    urlretrieve(
        "https://storage.googleapis.com/kubernetes-release/release/v%s/bin/%s/amd64/kubectl"
        % (kubectl_version, platform.system().lower()),
        os.path.join(tmpdir, 'kubectl'))
    os.chmod(os.path.join(tmpdir, 'kubectl'), 0o755)
    shutil.move(os.path.join(tmpdir, 'kubectl'),
                os.path.join(install_to, 'kubectl'))
    shutil.rmtree(tmpdir)

    print_green("Configuring kubectl...", newline_after=True)
    if not os.path.isdir(install_config_to):
        mkpath(install_config_to)

    if bucket_name and key_name:
        client = boto3.client('s3', region_name=get_region_name())
        client.download_file(bucket_name, key_name.lstrip('/'),
                             os.path.join(install_config_to, 'config'))
    else:
        shutil.copy(config_file, os.path.join(install_config_to, 'config'))
예제 #15
0
def images(reverse_sort, limit, filter_tags, digests):
    images = ECR().images
    sorted_images = sorted(images,
                           key=itemgetter('imagePushedAt'),
                           reverse=not reverse_sort)
    filtered_images = filter(lambda image: 'imageTags' in image.keys(),
                             sorted_images)
    if filter_tags:
        filtered_images = filter(
            lambda image: filter_tags in ', '.join(image['imageTags']),
            filtered_images)

    if digests:
        print_green(
            'Image Pushed At           | Image Digest                                                            | Image Tags',
            newline_before=True)
        print_green(
            '--------------------------------------------------------------------------------------------------------------------------------------'
        )
    else:
        print_green('Image Pushed At           | Image Tags',
                    newline_before=True)
        print_green(
            '----------------------------------------------------------')

    for image in filtered_images[:limit]:
        image_tags = ', '.join(image['imageTags'])
        if digests:
            line = "%s | %s | %s" % (image['imagePushedAt'],
                                     image['imageDigest'], image_tags)
        else:
            line = "%s | %s" % (image['imagePushedAt'], image_tags)
        if 'production' in image['imageTags']:
            print_green(line)
        elif 'staging' in image['imageTags']:
            print_yellow(line)
        else:
            print_smart(line)

    print_yellow("%d more images available" %
                 (len(filtered_images) - len(filtered_images[:limit])),
                 newline_before=True,
                 newline_after=True)
예제 #16
0
파일: pull.py 프로젝트: artsy/hokusai
def pull(tag, local_tag):
    ecr = ECR()
    if not ecr.project_repo_exists():
        raise HokusaiError(
            "ECR repo %s does not exist... did you run `hokusai setup` for this project?"
            % config.project_name)

    shout(ecr.get_login(),
          mask=(r'^(docker login -u) .+ (-p) .+ (.+)$',
                r'\1 ****** \2 ***** \3'))

    shout("docker pull %s:%s" % (ecr.project_repo, tag))

    shout("docker tag %s:%s hokusai_%s:%s" %
          (ecr.project_repo, tag, config.project_name, local_tag))

    print_green("Pulled %s:%s to hokusai_%s:%s" %
                (ecr.project_repo, tag, config.project_name, local_tag),
                newline_after=True)
예제 #17
0
파일: push.py 프로젝트: rm3l/hokusai
def push(tag, local_tag, build, filename, force, overwrite, skip_latest=False):
    if force is None and shout('git status --porcelain'):
        raise HokusaiError("Working directory is not clean.  Aborting.")

    if force is None and shout('git status --porcelain --ignored'):
        raise HokusaiError(
            "Working directory contains ignored files and/or directories.  Aborting."
        )

    ecr = ECR()
    if not ecr.project_repo_exists():
        raise HokusaiError(
            "ECR repo %s does not exist... did you run `hokusai setup` for this project?"
            % config.project_name)

    shout(ecr.get_login(),
          mask=(r'^(docker login -u) .+ (-p) .+ (.+)$',
                r'\1 ****** \2 ***** \3'))
    if tag is None:
        tag = shout('git rev-parse HEAD').strip()

    if overwrite is None and ecr.tag_exists(tag):
        raise HokusaiError("Tag %s already exists in registry.  Aborting." %
                           tag)

    if build:
        Docker().build(filename)

    build_tag = "hokusai_%s:%s" % (config.project_name, local_tag)

    shout("docker tag %s %s:%s" % (build_tag, ecr.project_repo, tag))
    shout("docker push %s:%s" % (ecr.project_repo, tag), print_output=True)
    print_green("Pushed %s to %s:%s" % (build_tag, ecr.project_repo, tag),
                newline_after=True)

    if skip_latest: return

    shout("docker tag %s %s:%s" % (build_tag, ecr.project_repo, 'latest'))
    shout("docker push %s:%s" % (ecr.project_repo, 'latest'),
          print_output=True)
    print_green("Pushed %s to %s:%s" % (build_tag, ecr.project_repo, 'latest'),
                newline_after=True)
예제 #18
0
def k8s_create(context, tag='latest', namespace=None, yaml_file_name=None):
  if yaml_file_name is None: yaml_file_name = context
  kubernetes_yml = os.path.join(CWD, "%s/%s.yml" % (HOKUSAI_CONFIG_DIR, yaml_file_name))
  if not os.path.isfile(kubernetes_yml):
    raise HokusaiError("Yaml file %s does not exist." % kubernetes_yml)

  ecr = ECR()
  if not ecr.project_repo_exists():
    raise HokusaiError("ECR repository %s does not exist... did you run `hokusai setup` for this project?" % config.project_name)

  if not ecr.tag_exists(tag):
    raise HokusaiError("Image tag %s does not exist... did you run `hokusai registry push`?" % tag)

  if tag is 'latest' and not ecr.tag_exists(context):
    ecr.retag(tag, context)
    print_green("Updated tag 'latest' -> %s" % context)

  kctl = Kubectl(context, namespace=namespace)
  shout(kctl.command("create --save-config -f %s" % kubernetes_yml), print_output=True)
  print_green("Created Kubernetes environment %s" % kubernetes_yml)
예제 #19
0
def gitlog():
  ecr = ECR()

  staging_deployment = Deployment('staging')
  staging_tag = staging_deployment.current_tag
  if staging_tag is None:
    raise HokusaiError("Could not find a tag for staging.  Aborting.")
  staging_tag = ecr.find_git_sha1_image_tag(staging_tag)
  if staging_tag is None:
    raise HokusaiError("Could not find a git SHA1 tag for tag %s.  Aborting." % staging_tag)

  production_deployment = Deployment('production')
  production_tag = production_deployment.current_tag
  if production_tag is None:
    raise HokusaiError("Could not find a tag for production.  Aborting.")
  production_tag = ecr.find_git_sha1_image_tag(production_tag)
  if production_tag is None:
    raise HokusaiError("Could not find a git SHA1 for tag %s.  Aborting." % production_tag)

  print_green("Comparing %s to %s" % (production_tag, staging_tag))
  shout("git log --right-only %s..%s" % (production_tag, staging_tag), print_output=True)
예제 #20
0
파일: kubernetes.py 프로젝트: artsy/hokusai
def k8s_create(context, tag='latest', namespace=None, filename=None, environment=()):
  if filename is None:
    yaml_template = TemplateSelector().get(os.path.join(CWD, HOKUSAI_CONFIG_DIR, context))
  else:
    yaml_template = TemplateSelector().get(filename)

  ecr = ECR()
  if not ecr.project_repo_exists():
    raise HokusaiError("ECR repository %s does not exist... did you run `hokusai setup` for this project?" % config.project_name)

  if not ecr.tag_exists(tag):
    raise HokusaiError("Image tag %s does not exist... did you run `hokusai registry push`?" % tag)

  if tag == 'latest' and not ecr.tag_exists(context):
    ecr.retag(tag, context)
    print_green("Updated tag 'latest' -> %s" % context)

  if filename is None:
    configmap = ConfigMap(context, namespace=namespace)
    for s in environment:
      if '=' not in s:
        raise HokusaiError("Error: environment variables must be of the form 'KEY=VALUE'")
      split = s.split('=', 1)
      configmap.update(split[0], split[1])
    configmap.create()
    print_green("Created configmap %s-environment" % config.project_name)

  kctl = Kubectl(context, namespace=namespace)
  yaml_spec = YamlSpec(yaml_template).to_file()

  shout(kctl.command("create --save-config -f %s" % yaml_spec), print_output=True)
  print_green("Created Kubernetes environment %s" % yaml_template)
예제 #21
0
파일: namespace.py 프로젝트: opsbay/hokusai
def create_new_app_yaml(source_file, app_name):
    with open(source_file, 'r') as stream:
        try:
            yaml_content = list(yaml.load_all(stream))
        except yaml.YAMLError as exc:
            raise HokusaiError("Cannot read source yaml file %s." %
                               source_file)

    for c in yaml_content:
        update_namespace(c, clean_string(app_name))

    new_namespace = OrderedDict([('apiVersion', 'v1'), ('kind', 'Namespace'),
                                 ('metadata', {
                                     'name': clean_string(app_name)
                                 })])
    yaml_content = [new_namespace] + yaml_content

    with open("hokusai/%s.yml" % app_name, 'w') as output:
        output.write(YAML_HEADER)
        yaml.safe_dump_all(yaml_content, output, default_flow_style=False)

    print_green("Created hokusai/%s.yml" % app_name)
예제 #22
0
def test(build, cleanup):
    docker_compose_yml = os.path.join(os.getcwd(), 'hokusai/test.yml')
    if not os.path.isfile(docker_compose_yml):
        raise HokusaiError("Yaml file %s does not exist." % docker_compose_yml)

    def on_cleanup(*args):
        shout("docker-compose -f %s -p hokusai stop" % docker_compose_yml)
        shout("docker-compose -f %s -p hokusai rm --force" %
              docker_compose_yml)

    if cleanup:
        for sig in EXIT_SIGNALS:
            signal.signal(sig, on_cleanup)

    opts = ' --abort-on-container-exit'
    if build:
        opts += ' --build'

    print_green("Starting test environment... Press Ctrl+C to stop.")
    try:
        shout("docker-compose -f %s -p hokusai up%s" %
              (docker_compose_yml, opts),
              print_output=True)
        return_code = int(
            shout("docker wait hokusai_%s_1" % config.project_name))
    except CalledProcessError:
        if cleanup: on_cleanup()
        raise HokusaiError('Tests Failed')

    if return_code:
        raise HokusaiError('Tests Failed - Exit Code: %s\n' % return_code,
                           return_code=return_code)
    else:
        print_green("Tests Passed")

    if cleanup: on_cleanup()

    return return_code
예제 #23
0
파일: namespace.py 프로젝트: artsy/hokusai
def create_new_app_yaml(source_file, app_name):
    yaml_spec = YamlSpec(source_file).to_file()
    with open(yaml_spec, 'r') as stream:
        try:
            yaml_content = list(yaml.load_all(stream, Loader=yaml.FullLoader))
        except yaml.YAMLError as exc:
            raise HokusaiError("Cannot read source yaml file %s." %
                               source_file)

    for c in yaml_content:
        update_namespace(c, clean_string(app_name))

    new_namespace = OrderedDict([('apiVersion', 'v1'), ('kind', 'Namespace'),
                                 ('metadata', {
                                     'name': clean_string(app_name)
                                 })])
    yaml_content = [new_namespace] + yaml_content

    with open(os.path.join(CWD, HOKUSAI_CONFIG_DIR, "%s.yml" % app_name),
              'w') as output:
        output.write(YAML_HEADER)
        yaml.safe_dump_all(yaml_content, output, default_flow_style=False)

    print_green("Created %s/%s.yml" % (HOKUSAI_CONFIG_DIR, app_name))
예제 #24
0
def update(context,
           tag,
           migration,
           constraint,
           git_remote,
           timeout,
           namespace=None,
           resolve_tag_sha1=True):
    if migration is not None:
        print_green("Running migration '%s' on %s..." % (migration, context),
                    newline_after=True)
        return_code = CommandRunner(context, namespace=namespace).run(
            tag, migration, constraint=constraint, tty=False)
        if return_code:
            raise HokusaiError("Migration failed with return code %s" %
                               return_code,
                               return_code=return_code)
    Deployment(context,
               namespace=namespace).update(tag,
                                           constraint,
                                           git_remote,
                                           timeout,
                                           resolve_tag_sha1=resolve_tag_sha1)
    print_green("Deployment updated to %s" % tag)
예제 #25
0
def environment_create(context):
    kubernetes_yml = os.path.join(os.getcwd(), "hokusai/%s.yml" % context)
    if not os.path.isfile(kubernetes_yml):
        raise HokusaiError("Yaml file %s does not exist for given context." %
                           kubernetes_yml)

    ecr = ECR()
    if not ecr.project_repository_exists():
        raise HokusaiError(
            "ECR repository %s does not exist... did you run `hokusai setup` for this project?"
            % config.project_name)

    if not ecr.tag_exists('latest'):
        raise HokusaiError(
            "Image tag 'latest' does not exist... did you run `hokusai push`?")

    if not ecr.tag_exists(context):
        ecr.retag('latest', context)
        print_green("Updated tag 'latest' -> %s" % context)

    kctl = Kubectl(context)
    shout(kctl.command("create --save-config -f %s" % kubernetes_yml),
          print_output=True)
    print_green("Created remote environment %s" % context)
예제 #26
0
def gitcompare(org_name, git_compare_link):
    ecr = ECR()

    staging_deployment = Deployment('staging')
    staging_tag = staging_deployment.current_tag
    if staging_tag is None:
        raise HokusaiError("Could not find a tag for staging.  Aborting.")
    staging_tag = ecr.find_git_sha1_image_tag(staging_tag)
    if staging_tag is None:
        raise HokusaiError(
            "Could not find a git SHA1 tag for tag %s.  Aborting." %
            staging_tag)

    production_deployment = Deployment('production')
    production_tag = production_deployment.current_tag
    if production_tag is None:
        raise HokusaiError("Could not find a tag for production.  Aborting.")
    production_tag = ecr.find_git_sha1_image_tag(production_tag)
    if production_tag is None:
        raise HokusaiError("Could not find a git SHA1 for tag %s.  Aborting." %
                           production_tag)

    print_green(git_compare_link %
                (org_name, config.project_name, production_tag, staging_tag))
예제 #27
0
def promote(migration, constraint, git_remote):
  ecr = ECR()

  deploy_from = Deployment('staging')
  tag = deploy_from.current_tag
  if tag is None:
    raise HokusaiError("Could not find a tag for staging.  Aborting.")
  tag = ecr.find_git_sha1_image_tag(tag)
  if tag is None:
    print_red("Could not find a git SHA1 for tag %s.  Aborting." % tag)
    return -1

  print_green("Deploying tag %s to production..." % tag)
  if migration is not None:
    print_green("Running migration '%s' on production..." % migration)
    return_code = CommandRunner('production').run(tag, migration, constraint=constraint)
    if return_code:
      raise HokusaiError("Migration failed with return code %s" % return_code, return_code=return_code)
  deploy_to = Deployment('production').update(tag, constraint, git_remote)
  print_green("Promoted staging to production at %s" % tag)
예제 #28
0
    def update(self, tag, constraint):
        print_green("Deploying %s to %s..." % (tag, self.context))

        if self.context != tag:
            ecr = ECR()

            ecr.retag(tag, self.context)
            print_green("Updated tag %s -> %s" % (tag, self.context))

            deployment_tag = "%s--%s" % (
                self.context,
                datetime.datetime.utcnow().strftime("%Y-%m-%d--%H-%M-%S"))
            ecr.retag(tag, deployment_tag)
            print_green("Updated tag %s -> %s" % (tag, deployment_tag))

        if config.pre_deploy is not None:
            print_green("Running pre-deploy hook '%s' on %s..." %
                        (config.pre_deploy, self.context))
            return_code = CommandRunner(self.context).run(
                tag, config.pre_deploy, constraint=constraint)
            if return_code:
                raise HokusaiError(
                    "Pre-deploy hook failed with return code %s" % return_code,
                    return_code=return_code)

        deployment_timestamp = datetime.datetime.utcnow().strftime("%s%f")
        for deployment in self.cache:
            containers = deployment['spec']['template']['spec']['containers']
            container_names = [container['name'] for container in containers]
            deployment_targets = [{
                "name":
                name,
                "image":
                "%s:%s" % (config.aws_ecr_registry, tag)
            } for name in container_names]
            patch = {
                "spec": {
                    "template": {
                        "metadata": {
                            "labels": {
                                "deploymentTimestamp": deployment_timestamp
                            }
                        },
                        "spec": {
                            "containers": deployment_targets
                        }
                    }
                }
            }
            print_green("Patching deployment %s..." %
                        deployment['metadata']['name'])
            shout(
                self.kctl.command(
                    "patch deployment %s -p '%s'" %
                    (deployment['metadata']['name'], json.dumps(patch))))

        print_green("Waiting for rollout to complete...")

        rollout_commands = [
            self.kctl.command("rollout status deployment/%s" %
                              deployment['metadata']['name'])
            for deployment in self.cache
        ]
        return_code = shout_concurrent(rollout_commands)
        if return_code:
            raise HokusaiError("Deployment failed!", return_code=return_code)

        if config.post_deploy is not None:
            print_green("Running post-deploy hook '%s' on %s..." %
                        (config.post_deploy, self.context))
            return_code = CommandRunner(self.context).run(
                tag, config.post_deploy, constraint=constraint)
            if return_code:
                raise HokusaiError(
                    "Post-deploy hook failed with return code %s" %
                    return_code,
                    return_code=return_code)
예제 #29
0
 def check_ok(check_item):
   print_green('\u2714 ' + check_item + ' found')
예제 #30
0
def k8s_status(context,
               resources,
               pods,
               describe,
               top,
               namespace=None,
               filename=None):
    if filename is None:
        yaml_template = TemplateSelector().get(
            os.path.join(CWD, HOKUSAI_CONFIG_DIR, context))
    else:
        yaml_template = TemplateSelector().get(filename)

    kctl = Kubectl(context, namespace=namespace)
    yaml_spec = YamlSpec(yaml_template).to_file()

    if describe:
        kctl_cmd = "describe"
        output = ""
    else:
        kctl_cmd = "get"
        output = " -o wide"
    if resources:
        print_green("Resources", newline_before=True)
        print_green("===========")
        shout(kctl.command("%s -f %s%s" % (kctl_cmd, yaml_spec, output)),
              print_output=True)
    if pods:
        print_green("Pods", newline_before=True)
        print_green("===========")
        shout(kctl.command("%s pods --selector app=%s,layer=application%s" %
                           (kctl_cmd, config.project_name, output)),
              print_output=True)
    if top:
        print_green("Top Pods", newline_before=True)
        print_green("===========")
        shout(kctl.command("top pods --selector app=%s,layer=application" %
                           config.project_name),
              print_output=True)