Ejemplo n.º 1
0
def output(output):
    '''Example for all possible Echo Formats

    You see the message only, if the Output TEXT
    '''
    with OutputFormat(output):
        action('This is a ok:')
        ok()
        action('This is a ok with message:')
        ok('all is fine')
        action('This is a warning:')
        warning('please check this')
        with Action('Start with working..') as act:
            # save_the_world()
            act.progress()
            act.progress()
            act.progress()
            act.progress()
        print_table('id name'.split(), [{'id': 1, 'name': 'Test #1'}, {'id': 2, 'name': 'Test #2'}])
        info('Only FYI')
        action('This is a error:')
        error('this is wrong, please fix')
        action('This is a fatal error:')
        fatal_error('this is a fuckup')
        info('I\'am not printed, the process a dead')
Ejemplo n.º 2
0
def check_schedulers(r, schedulers):
    for s in schedulers:
        action('Check scheduler {} .....'.format(s[2:]))
        try:
            ts = r.get("zmon:metrics:{}:ts".format(s))
            if ts is None:
                error("No scheduling loop registered ( running/stuck? )")
                continue

            delta = int(time.time() - float(ts))
            action("... last loop")
            highlight("{}".format(delta))
            action("s ago ...")
            if delta > 300:
                error("Last loop more than 300s ago (stuck? restart?)".format(delta))
                continue

            if delta > 180:
                error("Last loop more than 180s ago (stuck? check logs/watch)".format(delta))
                continue

            action("...")
            ok()
        except Exception as e:
            error(e)
Ejemplo n.º 3
0
def updateAlertDef(yaml_file):
    """update a single check definition"""
    data = get_config_data()
    post = yaml.safe_load(yaml_file)
    post['last_modified_by'] = data['user']
    if 'status' not in post:
        post['status'] = 'ACTIVE'

    action('Updating alert definition..')

    if 'id' not in post:
        error('"id" missing in definition')
        return

    if 'check_definition_id' not in post:
        error('"check_definition_id" missing in definition')
        return

    alert_id = post['id']

    r = requests.put(data['url'] + '/alert-definitions/{}'.format(alert_id), json.dumps(post),
                     auth=HTTPBasicAuth(data['user'], data['password']), headers={'Content-Type': 'application/json'})
    if r.status_code == 200:
        ok(get_config_data()["url"].replace("rest/api/v1", "") + "#/alert-details/" + str(r.json()["id"]))
    else:
        print(r.text)
Ejemplo n.º 4
0
def updateAlertDef(yaml_file):
    """update a single check definition"""
    data = get_config_data()
    alert = yaml.safe_load(yaml_file)
    alert['last_modified_by'] = data.get('user', 'unknown')
    if 'status' not in alert:
        alert['status'] = 'ACTIVE'

    action('Updating alert definition..')

    if 'id' not in alert:
        error('"id" missing in definition')
        return

    if 'check_definition_id' not in alert:
        error('"check_definition_id" missing in definition')
        return

    alert_id = alert['id']

    r = put('/alert-definitions/{}'.format(alert_id), json.dumps(alert))
    if r.status_code != 200:
        error(r.text)
    r.raise_for_status()
    ok(get_base_url(get_config_data()["url"]) + "#/alert-details/" + str(r.json()["id"]))
Ejemplo n.º 5
0
def change_version_traffic(stack_ref: StackReference, percentage: float,
                           region: str):
    versions = list(get_stack_versions(stack_ref.name, region))
    arns = []
    for each_version in versions:
        arns = arns + each_version.notification_arns
    identifier_versions = collections.OrderedDict(
        (version.identifier, version.version) for version in versions)
    version = get_version(versions, stack_ref.version)

    identifier = version.identifier

    if not version.domain:
        raise click.UsageError('Stack {} version {} has '
                               'no domain'.format(version.name,
                                                  version.version))

    percentage = int(percentage * PERCENT_RESOLUTION)
    known_record_weights, partial_count, partial_sum = get_weights(version.dns_name, identifier,
                                                                   identifier_versions.keys())

    if partial_count == 0 and percentage == 0:
        # disable the last remaining version
        new_record_weights = {i: 0 for i in known_record_weights.keys()}
        message = ('DNS record "{dns_name}" will be removed from that '
                   'stack'.format(dns_name=version.dns_name))
        ok(msg=message)
    else:
        with Action('Calculating new weights..'):
            compensations = {}
            if partial_count:
                delta = int((FULL_PERCENTAGE - percentage - partial_sum) / partial_count)
            else:
                delta = 0
                if percentage > 0:
                    # will put the only last version to full traffic percentage
                    compensations[identifier] = FULL_PERCENTAGE - percentage
                    percentage = int(FULL_PERCENTAGE)
            new_record_weights, deltas = calculate_new_weights(delta,
                                                               identifier,
                                                               known_record_weights,
                                                               percentage)
            total_weight = sum(new_record_weights.values())
            calculation_error = FULL_PERCENTAGE - total_weight
            if calculation_error and calculation_error < FULL_PERCENTAGE:
                compensate(calculation_error, compensations, identifier,
                           new_record_weights, partial_count, percentage,
                           identifier_versions)
            assert sum(new_record_weights.values()) == FULL_PERCENTAGE
        message = dump_traffic_changes(stack_ref.name,
                                       identifier,
                                       identifier_versions,
                                       known_record_weights,
                                       new_record_weights,
                                       compensations,
                                       deltas)
        print_traffic_changes(message)
        inform_sns(arns, message, region)
    set_new_weights(version.dns_name, identifier, version.lb_dns_name,
                    new_record_weights, region)
Ejemplo n.º 6
0
def push_entity(ctx, entity):
    if entity[-4:] == "json" and os.path.exists(entity):
        with open(entity, 'rb') as file:
            entity = file.read()
            data = json.loads(entity.decode())
    elif entity[-4:] == 'yaml' and os.path.exists(entity):
        with open(entity, 'rb') as fd:
            data = yaml.safe_load(fd)
    else:
        data = json.loads(entity)

    if not isinstance(data, list):
        data = [data]

    for e in data:
        action("creating entity...{}".format(e['id']))
        try:
            entity = json.dumps(e)
            r = put('/entities/', entity)
            if r.status_code == 200:
                ok()
            else:
                error()
        except:
            error("failed")
Ejemplo n.º 7
0
def init(yaml_file):
    """Initialize a new alert definition YAML file"""
    name = click.prompt('Alert name', default='Example Alert')
    check_id = click.prompt('Check ID')
    team = click.prompt('(Responsible-) Team', default='Example Team')

    data = {
        'check_definition_id': check_id,
        'condition': '>100',
        'description': 'Example Alert Description',
        'entities': [],
        'entities_exclude': [],
        'id': '',
        'name': name,
        'parameters': {},
        'parent_id': '',
        'priority': 2,
        'responsible_team': team,
        'status': 'ACTIVE',
        'tags': [],
        'team': team,
        'template': False,
    }

    yaml_file.write(dump_yaml(data).encode('utf-8'))
    ok()
Ejemplo n.º 8
0
def group_remove(ctx, group_name, user_name):
    action("Removing user ....")
    r = delete("/groups/{}/member/{}/".format(group_name, user_name))
    if r.text == '1':
        ok()
    else:
        error("failed to remove")
Ejemplo n.º 9
0
def group_add(ctx, group_name, user_name):
    action("Adding user ....")
    r = put("/groups/{}/member/{}/".format(group_name, user_name))
    if r.text == '1':
        ok()
    else:
        error("failed to insert")
Ejemplo n.º 10
0
def init(yaml_file):
    """Initialize a new check definition YAML file"""
    # NOTE: sorted like FIELD_SORT_INDEX
    name = click.prompt('Check definition name', default='Example Check')
    owning_team = click.prompt(
        'Team owning this check definition (i.e. your team)',
        default='Example Team')

    data = {
        'name':
        name,
        'owning_team':
        owning_team,
        'description':
        "Example ZMON check definition which returns a HTTP status code.\n" +
        "You can write multiple lines here, including unicode ☺",
        'command':
        "# GET request on example.org and return HTTP status code\n" +
        "http('http://example.org/', timeout=5).code()",
        'interval':
        60,
        'entities': [{
            'type': 'GLOBAL'
        }],
        'status':
        'ACTIVE'
    }

    yaml_file.write(dump_yaml(data).encode('utf-8'))
    ok()
Ejemplo n.º 11
0
def add_phone(ctx, member_email, phone_nr):
    action("Adding phone ....")
    r = put("/groups/{}/phone/{}/".format(member_email, phone_nr))
    if r.text == '1':
        ok()
    else:
        error("failed to set phone")
Ejemplo n.º 12
0
def remove_phone(ctx, member_email, phone_nr):
    action("Removing phone number ....")
    r = delete("/groups/{}/phone/{}/".format(member_email, phone_nr))
    if r.text == '1':
        ok()
    else:
        error("failed to remove phone")
Ejemplo n.º 13
0
def output(output):
    '''Example for all possible Echo Formats

    You see the message only, if the Output TEXT
    '''
    with OutputFormat(output):
        action('This is a ok:')
        ok()
        action('This is a ok with message:')
        ok('all is fine')
        action('This is a warning:')
        warning('please check this')
        with Action('Start with working..') as act:
            # save_the_world()
            act.progress()
            act.progress()
            act.progress()
            act.progress()
        print_table('id name'.split(), [{
            'id': 1,
            'name': 'Test #1'
        }, {
            'id': 2,
            'name': 'Test #2'
        }])
        info('Only FYI')
        action('This is a error:')
        error('this is wrong, please fix')
        action('This is a fatal error:')
        fatal_error('this is a fuckup')
        info('I\'am not printed, the process a dead')
Ejemplo n.º 14
0
def change_version_traffic(stack_ref: StackReference, percentage: float,
                           region: str):
    versions = list(get_stack_versions(stack_ref.name, region))
    arns = []
    for each_version in versions:
        arns = arns + each_version.notification_arns
    identifier_versions = collections.OrderedDict(
        (version.identifier, version.version) for version in versions)
    version = get_version(versions, stack_ref.version)

    identifier = version.identifier

    if not version.domain:
        raise click.UsageError('Stack {} version {} has '
                               'no domain'.format(version.name,
                                                  version.version))

    percentage = int(percentage * PERCENT_RESOLUTION)
    known_record_weights, partial_count, partial_sum = get_weights(version.dns_name, identifier,
                                                                   identifier_versions.keys())

    if partial_count == 0 and percentage == 0:
        # disable the last remaining version
        new_record_weights = {i: 0 for i in known_record_weights.keys()}
        message = ('DNS record "{dns_name}" will be removed from that '
                   'stack'.format(dns_name=version.dns_name))
        ok(msg=message)
    else:
        with Action('Calculating new weights..'):
            compensations = {}
            if partial_count:
                delta = int((FULL_PERCENTAGE - percentage - partial_sum) / partial_count)
            else:
                delta = 0
                if percentage > 0:
                    # will put the only last version to full traffic percentage
                    compensations[identifier] = FULL_PERCENTAGE - percentage
                    percentage = int(FULL_PERCENTAGE)
            new_record_weights, deltas = calculate_new_weights(delta,
                                                               identifier,
                                                               known_record_weights,
                                                               percentage)
            total_weight = sum(new_record_weights.values())
            calculation_error = FULL_PERCENTAGE - total_weight
            if calculation_error and calculation_error < FULL_PERCENTAGE:
                compensate(calculation_error, compensations, identifier,
                           new_record_weights, partial_count, percentage,
                           identifier_versions)
            assert sum(new_record_weights.values()) == FULL_PERCENTAGE
        message = dump_traffic_changes(stack_ref.name,
                                       identifier,
                                       identifier_versions,
                                       known_record_weights,
                                       new_record_weights,
                                       compensations,
                                       deltas)
        print_traffic_changes(message)
        inform_sns(arns, message, region)
    set_new_weights(version.dns_name, known_record_weights,
                    new_record_weights, region)
Ejemplo n.º 15
0
def push_entity(obj, entity):
    """Push one or more entities"""
    client = get_client(obj.config)

    if (entity.endswith('.json')
            or entity.endswith('.yaml')) and os.path.exists(entity):
        with open(entity, 'rb') as fd:
            data = yaml.safe_load(fd)
    else:
        data = json.loads(entity)

    if not isinstance(data, list):
        data = [data]

    with Action('Creating new entities ...', nl=True) as act:
        for e in data:
            action('Creating entity {} ...'.format(e['id']))
            try:
                client.add_entity(e)
                ok()
            except ZmonArgumentError as e:
                act.error(str(e))
            except requests.HTTPError as e:
                log_http_exception(e, act)
            except Exception as e:
                act.error('Failed: {}'.format(str(e)))
Ejemplo n.º 16
0
def get_tv_token(obj):
    """Retrieve a new token"""
    client = get_client(obj.config)

    with Action('Retrieving new one-time token ...', nl=True):
        token = client.get_onetime_token()
        ok(client.token_login_url(token.strip('"')))
Ejemplo n.º 17
0
def invoke(op, *args, **kwargs):
    if op.http_method != 'get':
        clickclick.action('Invoking..')
    request = construct_request(op, {}, **kwargs)
    c = RequestsClient()
    future = c.request(request)
    future.result()
    clickclick.ok()
Ejemplo n.º 18
0
def switch_active(ctx, group_name, user_name):
    action("Switching active user ....")
    r = delete("/groups/{}/active/".format(group_name))
    r = put("/groups/{}/active/{}/".format(group_name, user_name))
    if r.text == '1':
        ok()
    else:
        error("failed to switch")
Ejemplo n.º 19
0
def delete_check_definition(check_id):
    '''Delete an orphan check definition'''

    action('delete check id {} ...'.format(check_id))
    r = delete('/check-definitions/{}'.format(check_id))
    if r.status_code == 200:
        ok()
    else:
        error(r.text)
Ejemplo n.º 20
0
def check_redis_host(host, port=6379):
    action("Check Redis on {}".format(host))
    action("...")
    try:
        r = StrictRedis(host, port)
        workers = r.smembers("zmon:metrics")
        ok()
        return r, workers
    except Exception as e:
        error(e)
Ejemplo n.º 21
0
def delete_entity(ctx, entity_id):
    action("delete entity... {}".format(entity_id))
    try:
        r = delete('/entities/?id={}'.format(urllib.parse.quote_plus(entity_id)))
        if r.status_code == 200 and r.text == "1":
            ok()
        else:
            error("Delete unsuccessfull")
    except Exception as ex:
        error("Exception during delete: " + str(ex))
Ejemplo n.º 22
0
def check_queues(redis):
    queues = ['zmon:queue:default', 'zmon:queue:snmp', 'zmon:queue:internal', 'zmon:queue:secure']

    for q in queues:
        action('Checking queue length ... {} ...'.format(q))
        l = redis.llen(q)
        action("...")
        highlight("{}".format(l))
        action(" ...")
        if l < 2000:
            ok()
            continue
        error("to many tasks")
Ejemplo n.º 23
0
def create_alert_definition(obj, yaml_file):
    """Create a single alert definition"""
    client = get_client(obj.config)

    alert = yaml.safe_load(yaml_file)

    alert['last_modified_by'] = obj.config.get('user', 'unknown')

    with Action('Creating alert definition ...', nl=True) as act:
        try:
            new_alert = client.create_alert_definition(alert)
            ok(client.alert_details_url(new_alert))
        except ZmonArgumentError as e:
            act.error(str(e))
Ejemplo n.º 24
0
def dashboard_update(obj, yaml_file):
    """Create/Update a single ZMON dashboard"""
    client = get_client(obj.config)
    dashboard = {}
    with open(yaml_file, 'rb') as f:
        dashboard = yaml.safe_load(f)

    msg = 'Creating new dashboard ...'
    if 'id' in dashboard:
        msg = 'Updating dashboard {} ...'.format(dashboard.get('id'))

    with Action(msg, nl=True):
        dash_id = client.update_dashboard(dashboard)
        ok(client.dashboard_url(dash_id))
Ejemplo n.º 25
0
def grafana_update(obj, yaml_file):
    """Create/Update a single ZMON dashboard"""
    dashboard = yaml.safe_load(yaml_file)

    title = dashboard.get('dashboard', {}).get('title', '')

    client = get_client(obj.config)

    with Action('Updating dashboard {} ...'.format(title), nl=True) as act:
        try:
            client.update_grafana_dashboard(dashboard)
            ok(client.grafana_dashboard_url(dashboard))
        except ZmonArgumentError as e:
            act.error(e)
Ejemplo n.º 26
0
def update(yaml_file):
    """update a single check definition"""
    data = get_config_data()
    post = yaml.safe_load(yaml_file)
    post['last_modified_by'] = data['user']
    if 'status' not in post:
        post['status'] = 'ACTIVE'
    action('Updating check definition... ')
    r = requests.post(data['url'] + '/check-definitions', json.dumps(post),
                      auth=HTTPBasicAuth(data['user'], data['password']), headers={'Content-Type': 'application/json'})
    if r.status_code == 200:
        ok(get_config_data()["url"].replace("rest/api/v1", "") + "#/check-definitions/view/" + str(r.json()["id"]))
    else:
        print(r.text)
Ejemplo n.º 27
0
def change_version_traffic(stack_ref: StackReference, percentage: float, region):

    versions = list(get_stack_versions(stack_ref.name, region))
    identifier_versions = collections.OrderedDict(
        (version.identifier, version.version) for version in versions)
    version = get_version(versions, stack_ref.version)

    identifier = version.identifier

    if not version.domain:
        raise click.UsageError('Stack {} version {} has no domain'.format(version.name, version.version))

    domain = version.domain.split('.', 1)[1]
    zone = get_zone(region, domain)
    rr = zone.get_records()
    percentage = int(percentage * PERCENT_RESOLUTION)
    known_record_weights, partial_count, partial_sum = get_weights(version.dns_name, identifier, rr,
                                                                   identifier_versions.keys())

    if partial_count == 0 and percentage == 0:
        # disable the last remaining version
        new_record_weights = {i: 0 for i in known_record_weights.keys()}
        ok(msg='DNS record "{dns_name}" will be removed from that stack'.format(dns_name=version.dns_name))
    else:
        with Action('Calculating new weights..'):
            compensations = {}
            if partial_count:
                delta = int((FULL_PERCENTAGE - percentage - partial_sum) / partial_count)
            else:
                delta = 0
                if percentage > 0:
                    # will put the only last version to full traffic percentage
                    compensations[identifier] = FULL_PERCENTAGE - percentage
                    percentage = int(FULL_PERCENTAGE)
            new_record_weights, deltas = calculate_new_weights(delta, identifier, known_record_weights, percentage)
            total_weight = sum(new_record_weights.values())
            calculation_error = FULL_PERCENTAGE - total_weight
            if calculation_error and calculation_error < FULL_PERCENTAGE:
                percentage = compensate(calculation_error, compensations, identifier,
                                        new_record_weights, partial_count, percentage, identifier_versions)
            assert sum(new_record_weights.values()) == FULL_PERCENTAGE
        dump_traffic_changes(stack_ref.name,
                             identifier,
                             identifier_versions,
                             known_record_weights,
                             new_record_weights,
                             compensations,
                             deltas)
    set_new_weights(version.dns_name, identifier, version.lb_dns_name, new_record_weights, percentage, rr)
Ejemplo n.º 28
0
def test_echo():
    action('Action..')
    ok()

    action('Action..')
    error(' some error')

    action('Action..')
    with pytest.raises(SystemExit):
        fatal_error(' some fatal error')  # noqa

    action('Action..')
    warning(' some warning')

    info('Some info')
Ejemplo n.º 29
0
def update(obj, yaml_file, skip_validation):
    """Update a single check definition"""
    check = yaml.safe_load(yaml_file)

    check['last_modified_by'] = obj.get('user', 'unknown')

    client = get_client(obj.config)

    with Action('Updating check definition ...', nl=True) as act:
        try:
            check = client.update_check_definition(
                check, skip_validation=skip_validation)
            ok(client.check_definition_url(check))
        except ZmonArgumentError as e:
            act.error(str(e))
Ejemplo n.º 30
0
def test_echo():
    action('Action..')
    ok()

    action('Action..')
    error(' some error')

    action('Action..')
    with pytest.raises(SystemExit):
        fatal_error(' some fatal error')  # noqa

    action('Action..')
    warning(' some warning')

    info('Some info')
Ejemplo n.º 31
0
def status(config):
    """check system status"""
    redis, workers = check_redis_host(config['redis_host'], 6379)

    print("")

    workers = list(map(lambda x: x.decode(), sorted(workers)))

    action("Looking for <30s interval scheduler ...")
    scheduler = list(filter(lambda x: x[:7] == 's-p3423', workers))
    if not scheduler:
        error("not found! check p3423")
    else:
        action("... running {}".format(scheduler[0][2:]))
        ok()

    action("Looking for >30s interval scheduler ...")
    scheduler = list(filter(lambda x: x[:7] == 's-p3422', workers))
    if not scheduler:
        error("not found! check p3422")
    else:
        action("... running {}".format(scheduler[0][2:]))
        ok()

    action("Looking for NG scheduler ...")
    scheduler = list(filter(lambda x: x == 's-p3421.monitor02', workers))
    if not scheduler:
        error("not found! check p3421 on monitor02")
    else:
        action("... running {}".format(scheduler[0][2:]))
        ok()

    action("Looking for self monitoring scheduler ...")
    scheduler = list(filter(lambda x: x == 's-p3421.itr-monitor01', workers))
    if not scheduler:
        error("not found! check p3411 on itr-monitor02")
    else:
        action("... running {}".format(scheduler[0][2:]))
        ok()

    print("")

    ws = []
    ss = []

    for w in workers:
        if w[:2] == "s-":
            ss.append(w)
        else:
            ws.append(w)

    check_schedulers(redis, ss)
    print("")

    check_queues(redis)
    print("")

    check_workers(redis, ws)
Ejemplo n.º 32
0
def update(yaml_file):
    """update a single check definition"""
    data = get_config_data()

    check = yaml.safe_load(yaml_file)
    check['last_modified_by'] = data.get('user', 'unknown')
    if 'status' not in check:
        check['status'] = 'ACTIVE'

    action('Updating check definition... ')

    r = post('/check-definitions', json.dumps(check))
    if r.status_code != 200:
        error(r.text)
    r.raise_for_status()
    ok(get_base_url(get_config_data()["url"]) + "#/check-definitions/view/" + str(r.json()["id"]))
Ejemplo n.º 33
0
def create_alert_definition(yaml_file):
    """Create a single alert definition"""
    data = get_config_data()
    alert = yaml.safe_load(yaml_file)
    alert['last_modified_by'] = data.get('user', 'unknown')
    if 'status' not in alert:
        alert['status'] = 'ACTIVE'

    action('Creating alert definition..')

    if 'check_definition_id' not in alert:
        error('"check_definition_id" missing in definition')
        return

    r = post('/alert-definitions', json.dumps(alert))
    ok(get_base_url(get_config_data()["url"]) + "#/alert-details/" + str(r.json()["id"]))
Ejemplo n.º 34
0
def login(config, url):
    '''Login to Pier One Docker registry (generates docker configuration in ~/.docker/config.json)'''
    url_option_was_set = url
    url = set_pierone_url(config, url)

    if not url_option_was_set:
        stups_cli.config.store_config(config, 'pierone')

    # Check if the credential helper is available
    if shutil.which("docker-credential-pierone") is None:
        fatal_error(
            "docker-credential-pierone executable is not available. "
            "If you've installed `pierone` to a virtual environment, make sure to add it to to the PATH."
        )

    docker_login_with_credhelper(url)
    ok("Authentication configured for {}, you don't need to run pierone login anymore!"
       .format(url))
Ejemplo n.º 35
0
def update(yaml_file):
    """update a single check definition"""
    data = get_config_data()

    check = yaml.safe_load(yaml_file)
    check['last_modified_by'] = data.get('user', 'unknown')
    if 'status' not in check:
        check['status'] = 'ACTIVE'

    action('Updating check definition... ')

    if not check.get('owning_team'):
        raise click.UsageError('Missing "owning_team" in check definition')

    validate_check_command(check['command'])

    r = post('/check-definitions', json.dumps(check))
    ok(get_base_url(get_config_data()["url"]) + "#/check-definitions/view/" + str(r.json()["id"]))
Ejemplo n.º 36
0
def check_workers(r, workers):
    for w in workers:
        action('Check worker {} ...'.format(w))
        try:
            ts = r.get("zmon:metrics:{}:ts".format(w))
            delta = time.time() - float(ts)
            delta = max(int(delta), 0)

            action("... last exec")
            highlight("{}".format(delta))
            action("s ago ...")
            if delta < 30:
                ok()
                continue

            error("no task execute recently")

        except Exception as e:
            error(e)
Ejemplo n.º 37
0
def dashboard_update(ctx, yaml_file):
    """Create/Update a single ZMON dashboard"""

    with open(yaml_file, 'rb') as f:
        data = yaml.safe_load(f)

    if 'id' in data:
        action('Updating dashboard {}..'.format(data.get('id')))
        post('/dashboard/{}'.format(data['id']), json.dumps(data))
        ok()
    else:
        action('Creating new dashboard..')
        r = post('/dashboard/', json.dumps(data))
        data['id'] = int(r.text)

        with open(yaml_file, 'wb') as f:
            f.write(dump_yaml(data).encode('utf-8'))

        ok("new id: {}".format(r.text))
Ejemplo n.º 38
0
def push_entity(ctx, entity):
    '''Push one or more entities'''
    if (entity.endswith('.json') or entity.endswith('.yaml')) and os.path.exists(entity):
        # JSON is a subset of YAML, so we can use the YAML parser..
        with open(entity, 'rb') as fd:
            data = yaml.safe_load(fd)
    else:
        data = json.loads(entity)

    if not isinstance(data, list):
        data = [data]

    for e in data:
        action("Creating entity {}..".format(e['id']))
        try:
            entity = json.dumps(e)
            put('/entities/', entity)
            ok()
        except:
            error("failed")
Ejemplo n.º 39
0
def update_alert_definition(obj, yaml_file):
    """Update a single alert definition"""
    alert = yaml.safe_load(yaml_file)

    alert['last_modified_by'] = obj.config.get('user', 'unknown')

    client = get_client(obj.config)

    with Action('Updating alert definition ...', nl=True) as act:
        try:
            # Workaround API inconsistency!
            if alert.get('parameters'):
                for k, v in alert['parameters'].items():
                    if type(v) is str:
                        alert['parameters'][k] = json.loads(v)

            client.update_alert_definition(alert)
            ok(client.alert_details_url(alert))
        except ZmonArgumentError as e:
            act.error(str(e))
Ejemplo n.º 40
0
def push_entity(ctx, entity):
    if entity[-4:] == "json" and os.path.exists(entity):
        action("create or update entity from json ...")
        with open(entity, 'rb') as file:
            entity = file.read()
    elif entity[-4:] == 'yaml' and os.path.exists(entity):
        action("create or update entity from yaml ...")
        with open(entity, 'rb') as fd:
            data = yaml.safe_load(fd)
            entity = json.dumps(data)
    else:
        action("create or update entity...")
    try:
        r = put('/entities/', entity)
        if r.status_code == 200:
            ok()
        else:
            error()
    except:
        error("failed")
Ejemplo n.º 41
0
def init(obj, yaml_file):
    """Initialize a new dashboard YAML file"""
    name = click.prompt('Dashboard name', default='Example dashboard')
    alert_teams = click.prompt('Alert Teams (comma separated)',
                               default='Team1, Team2')

    user = obj.config.get('user', 'unknown')

    data = {
        'id': '',
        'name': name,
        'last_modified_by': user,
        'alert_teams': [t.strip() for t in alert_teams.split(',')],
        'tags': [],
        'view_mode': 'FULL',
        'shared_teams': [],
        'widget_configuration': [],
    }

    yaml_file.write(dump_yaml(data).encode('utf-8'))
    ok()
Ejemplo n.º 42
0
def grafana_update(ctx, yaml_file):
    """Create/Update a single ZMON dashboard"""

    with open(yaml_file, 'rb') as f:
        data = yaml.safe_load(f)

    title = data.get('dashboard', {}).get('title', None)
    id = data.get('dashboard', {}).get('id', None)

    if id is None and title is None:
        error("id and title missing")

    if title is None:
        error("title is missing")

    action('Updating dashboard title "{}"...'.format(title))
    r = post('/grafana2-dashboards', json.dumps(data))
    if r.status_code == 200:
        ok()
    else:
        error(r.text)
Ejemplo n.º 43
0
def set_new_weights(dns_name, identifier, lb_dns_name: str, new_record_weights, percentage, rr):
    action('Setting weights for {dns_name}..', **vars())
    did_the_upsert = False
    for r in rr:
        if r.type == 'CNAME' and r.name == dns_name:
            w = new_record_weights[r.identifier]
            if w:
                if int(r.weight) != w:
                    r.weight = w
                    rr.add_change_record('UPSERT', r)
                if identifier == r.identifier:
                    did_the_upsert = True
            else:
                rr.add_change_record('DELETE', r)
    if new_record_weights[identifier] > 0 and not did_the_upsert:
        change = rr.add_change('CREATE', dns_name, 'CNAME', ttl=20, identifier=identifier,
                               weight=new_record_weights[identifier])
        change.add_value(lb_dns_name)
    if rr.changes:
        rr.commit()
        if sum(new_record_weights.values()) == 0:
            ok(' DISABLED')
        else:
            ok()
    else:
        ok(' not changed')
Ejemplo n.º 44
0
def set_new_weights(dns_name, identifier, lb_dns_name: str, new_record_weights,
                    percentage, rr):
    action('Setting weights for {dns_name}..', **vars())
    did_the_upsert = False
    for r in rr:
        if r.type == 'CNAME' and r.name == dns_name:
            w = new_record_weights[r.identifier]
            if w:
                if int(r.weight) != w:
                    r.weight = w
                    rr.add_change_record('UPSERT', r)
                if identifier == r.identifier:
                    did_the_upsert = True
            else:
                rr.add_change_record('DELETE', r)
    if new_record_weights[identifier] > 0 and not did_the_upsert:
        change = rr.add_change('CREATE',
                               dns_name,
                               'CNAME',
                               ttl=20,
                               identifier=identifier,
                               weight=new_record_weights[identifier])
        change.add_value(lb_dns_name)
    if rr.changes:
        rr.commit()
        if sum(new_record_weights.values()) == 0:
            ok(' DISABLED')
        else:
            ok()
    else:
        ok(' not changed')
Ejemplo n.º 45
0
def set_new_weights(dns_names: list, identifier, lb_dns_name: str, new_record_weights, percentage):
    action('Setting weights for {dns_names}..', dns_names=', '.join(dns_names))
    dns_changes = collections.defaultdict(lambda: [])
    for idx, dns_name in enumerate(dns_names):
        domain = dns_name.split('.', 1)[1]
        hosted_zone = Route53HostedZone.get_by_domain_name(domain)
        did_the_upsert = False

        convert_domain_records_to_alias(dns_name)

        for r in Route53.get_records(name=dns_name):
            if r.type in [RecordType.CNAME, RecordType.A, RecordType.AAAA]:
                w = new_record_weights[r.set_identifier]
                if w:
                    if int(r.weight) != w:
                        r.weight = w
                        dns_changes[hosted_zone.id].append({'Action': 'UPSERT',
                                                            'ResourceRecordSet': r.boto_dict})
                    if identifier == r.set_identifier:
                        did_the_upsert = True
                else:
                    if dns_changes.get(hosted_zone.id) is None:
                        dns_changes[hosted_zone.id] = []
                    dns_changes[hosted_zone.id].append({'Action': 'DELETE',
                                                        'ResourceRecordSet': r.boto_dict.copy()})
        if new_record_weights[identifier] > 0 and not did_the_upsert:
            if dns_changes.get(hosted_zone.id) is None:
                dns_changes[hosted_zone.id] = []
            elb = ELB.get_by_dns_name(lb_dns_name[idx])
            record = Route53Record(name=dns_name,
                                   type=RecordType.A,
                                   set_identifier=identifier,
                                   weight=new_record_weights[identifier],
                                   alias_target={"HostedZoneId": elb.hosted_zone.id,
                                                 "DNSName": lb_dns_name[idx],
                                                 "EvaluateTargetHealth": False})
            dns_changes[hosted_zone.id].append({'Action': 'UPSERT',
                                                'ResourceRecordSet': record.boto_dict})
    if dns_changes:
        route53 = boto3.client('route53')
        for hosted_zone_id, change in dns_changes.items():
            route53.change_resource_record_sets(HostedZoneId=hosted_zone_id,
                                                ChangeBatch={'Comment': 'Weight change of {}'.format(hosted_zone_id),
                                                             'Changes': change})
        if sum(new_record_weights.values()) == 0:
            ok(' DISABLED')
        else:
            ok()
    else:
        ok(' not changed')
Ejemplo n.º 46
0
def set_new_weights(dns_names: list, identifier, lb_dns_name: str, new_record_weights, percentage):
    action('Setting weights for {dns_names}..', dns_names=', '.join(dns_names))
    dns_changes = {}
    for idx, dns_name in enumerate(dns_names):
        domain = dns_name.split('.', 1)[1]
        zone = get_zone(domain)
        did_the_upsert = False
        for r in get_records(domain):
            if r['Type'] == 'CNAME' and r['Name'] == dns_name:
                w = new_record_weights[r['SetIdentifier']]
                if w:
                    if int(r['Weight']) != w:
                        r['Weight'] = w
                        if dns_changes.get(zone['Id']) is None:
                            dns_changes[zone['Id']] = []
                        dns_changes[zone['Id']].append({'Action': 'UPSERT',
                                                        'ResourceRecordSet': r})
                    if identifier == r['SetIdentifier']:
                        did_the_upsert = True
                else:
                    if dns_changes.get(zone['Id']) is None:
                        dns_changes[zone['Id']] = []
                    dns_changes[zone['Id']].append({'Action': 'DELETE',
                                                    'ResourceRecordSet': r.copy()})
        if new_record_weights[identifier] > 0 and not did_the_upsert:
            if dns_changes.get(zone['Id']) is None:
                dns_changes[zone['Id']] = []
            dns_changes[zone['Id']].append({'Action': 'UPSERT',
                                            'ResourceRecordSet': {'Name': dns_name,
                                                                  'Type': 'CNAME',
                                                                  'SetIdentifier': identifier,
                                                                  'Weight': new_record_weights[identifier],
                                                                  'TTL': 20,
                                                                  'ResourceRecords': [{'Value': lb_dns_name[idx]}]}})
    if dns_changes:
        route53 = boto3.client('route53')
        for hosted_zone_id, change in dns_changes.items():
            route53.change_resource_record_sets(HostedZoneId=hosted_zone_id,
                                                ChangeBatch={'Comment': 'Weight change of {}'.format(hosted_zone_id),
                                                             'Changes': change})
        if sum(new_record_weights.values()) == 0:
            ok(' DISABLED')
        else:
            ok()
    else:
        ok(' not changed')
Ejemplo n.º 47
0
 def __exit__(self, exc_type, exc_val, exc_tb):
     if exc_type is None:
         if self.output == 'text' and not self.printer and not self.errors:
             ok(self.ok_msg)
     elif not self._suppress_exception:
         error(' EXCEPTION OCCURRED: {}'.format(exc_val))
Ejemplo n.º 48
0
def set_new_weights(dns_names: list, identifier, lb_dns_name: str,
                    new_record_weights: Dict, region: str):
    action('Setting weights for {dns_names}..', dns_names=', '.join(dns_names))
    for idx, dns_name in enumerate(dns_names):
        domain = dns_name.split('.', 1)[1]
        hosted_zone = Route53HostedZone.get_by_domain_name(domain)
        convert_cname_records_to_alias(dns_name)

        changed = False
        for stack_name, percentage in new_record_weights.items():
            try:
                stack = CloudFormationStack.get_by_stack_name(stack_name,
                                                              region=region)
            except StackNotFound:
                # The Route53 record doesn't have an associated stack
                # fallback to the old logic
                record = None
                for r in Route53.get_records(name=dns_name):
                    if r.set_identifier == stack_name:
                        record = r
                        break
                if percentage:
                    record.weight = percentage
                    hosted_zone.upsert(
                        [record],
                        comment="Change weight of {} to {}".format(
                            stack_name, percentage))
                else:
                    hosted_zone.delete(
                        [record],
                        comment="Delete {} "
                        "because traffic for it is 0".format(stack_name))
                changed = True
                continue

            for key, resource in stack.template['Resources'].items():
                if (resource['Type'] == ResourceType.route53_record_set
                        and resource['Properties']['Name'] == dns_name):
                    dns_record = stack.template['Resources'][key]
                    break

            try:
                dns_record['Properties']['Weight'] = percentage
            except NameError:
                raise ELBNotFound(dns_name)

            try:
                stack.update()
            except StackNotUpdated:
                # make sure we update DNS records which were not updated via CloudFormation
                record = None
                for r in Route53.get_records(name=dns_name):
                    if r.set_identifier == stack_name:
                        record = r
                        break
                if record and record.weight != percentage:
                    record.weight = percentage
                    hosted_zone.upsert(
                        [record],
                        comment="Change weight of {} to {}".format(
                            stack_name, percentage))
                    changed = True
            else:
                changed = True

        if changed:
            ok()
        else:
            ok(' not changed')
Ejemplo n.º 49
0
def set_new_weights(dns_names: list, old_record_weights: Dict,
                    new_record_weights: Dict, region: str):
    action("Setting weights for {dns_names}..", dns_names=", ".join(dns_names))
    changed = False
    updates = {}
    for idx, dns_name in enumerate(dns_names):
        domain = dns_name.split(".", 1)[1]
        hosted_zone = Route53HostedZone.get_by_domain_name(domain)
        convert_cname_records_to_alias(dns_name)

        for stack_name, percentage in new_record_weights.items():
            if old_record_weights[stack_name] == percentage:
                # Stack weight will not change
                continue
            try:
                if stack_name not in updates.keys():
                    stack = CloudFormationStack.get_by_stack_name(
                        stack_name, region=region)
                else:
                    stack = updates[stack_name]["stack"]
            except StackNotFound:
                # The Route53 record doesn't have an associated stack
                # fallback to the old logic
                record = None
                for r in Route53.get_records(name=dns_name):
                    if r.set_identifier == stack_name:
                        record = r
                        break
                if percentage:
                    record.weight = percentage
                    hosted_zone.upsert(
                        [record],
                        comment="Change weight of {} to {}".format(
                            stack_name, percentage),
                    )
                else:
                    hosted_zone.delete(
                        [record],
                        comment="Delete {} "
                        "because traffic for it is 0".format(stack_name),
                    )
                changed = True
                continue

            for key, resource in stack.template["Resources"].items():
                if (resource["Type"] == ResourceType.route53_record_set
                        and resource["Properties"]["Name"] == dns_name):
                    dns_record = stack.template["Resources"][key]
                    break

            try:
                dns_record["Properties"]["Weight"] = percentage
            except NameError:
                raise ELBNotFound(dns_name)

            if stack_name not in updates.keys():
                update = {"stack": stack, "zones": {}}
                updates[stack_name] = update
            else:
                update = updates[stack_name]

            if domain not in update["zones"].keys():
                records = list()
                update["zones"][domain] = records
            else:
                records = update["zones"][domain]
            record = None
            for r in Route53.get_records(name=dns_name):
                if r.set_identifier == stack_name:
                    record = r
                    break
            if record and record.weight != percentage:
                record.weight = percentage
                records.append({
                    "record":
                    record,
                    "comment":
                    "Change weight of {} to {}".format(stack_name, percentage),
                })

    for key, update in updates.items():
        try:
            update["stack"].update()
        except StackNotUpdated:
            # make sure we update DNS records which were not updated via CloudFormation
            for domain, records in update["zones"].items():
                hosted_zone = Route53HostedZone.get_by_domain_name(domain)
                for zone_update in records:
                    hosted_zone.upsert([zone_update["record"]],
                                       comment=zone_update["comment"])
                    changed = True
        else:
            changed = True

    if changed:
        ok()
    else:
        ok(" not changed")