예제 #1
0
def main(args, config_filename):
    """
    Main entry point for script.
    """
    # Set up logging to syslog.
    configure_syslog("clearwater-config-manager", args.log_level)

    # Regardless of passed arguments we want to delete outdated config to not
    # leave unused files on disk.
    delete_outdated_config_files()

    # Create an etcd client for interacting with the database.
    try:
        log.debug("Getting etcdClient with parameters %s, 4000",
                  args.management_ip)
        etcd_client = etcd.client.Client(host=args.management_ip, port=4000)
        local_store = LocalStore(args.download_dir)

        config_location = local_store.config_location(config_filename)

        selected_config = lookup_config_type(args.config_type, config_location)
        config_loader = ConfigLoader(etcd_client=etcd_client,
                                     etcd_key=args.etcd_key,
                                     site=args.site)
    except (etcd.EtcdException, EtcdConnectionFailed):
        log.error("etcd cluster uncontactable")
        sys.exit("Unable to contact the etcd cluster.")
    except EtcdNoQuorum:
        log.error("etcd cluster doesn't have quorum")
        sys.exit(CLUSTER_NOT_HEALTHY)

    if args.action == "download":
        log.info("User %s triggered download of %s", get_user_name(),
                 args.config_type)
        try:
            download_config(config_loader, local_store, selected_config,
                            args.autoconfirm)
        except (UserAbort, ConfigDownloadFailed) as exc:
            log.error("Download failed")
            sys.exit(exc)

    if args.action == "upload":
        log.info("User %s triggered upload of %s", get_user_name(),
                 args.config_type)
        try:
            upload_verified_config(config_loader, local_store, selected_config,
                                   args.force, args.autoconfirm)
        except ConfigUnchanged:
            # If there are no changes to the config, we don't execute an
            # upload. But that doesn't mean there was a failure - the config
            # on etcd is what the user wanted it to be. We print a message to
            # the user and return a zero error code.
            print NO_CHANGES_TO_CONFIG
        except (UserAbort, ConfigUploadFailed) as exc:
            log.error("Upload failed")
            sys.exit(exc)
    def testGetUserName(self, mock_subprocess):
        """Test that can retrieve get user name."""

        mock_subprocess.return_value = \
            "clearwater      pts/1        2017-10-30 18:25 (:0)"

        user_name = get_user_name()
        self.assertEqual(user_name, "clearwater")
    def testGetUserName(self, mock_subprocess):
        """Test that can retrieve get user name."""

        mock_subprocess.return_value = \
            "clearwater      pts/1        2017-10-30 18:25 (:0)"

        user_name = get_user_name()
        self.assertEqual(user_name, "clearwater")
    def testGetUserNameEnv(self, mock_subprocess, mock_getenv):
        """Test that can use env variable for username as fallback."""

        # Return an empty string from the who am i process
        mock_subprocess.return_value = ""
        mock_getenv.return_value = "myusername"

        user_name = get_user_name()
        self.assertEqual(user_name, "myusername")
    def testGetUserNameEnv(self, mock_subprocess, mock_getenv):
        """Test that can use env variable for username as fallback."""

        # Return an empty string from the who am i process
        mock_subprocess.return_value = ""
        mock_getenv.return_value = "myusername"

        user_name = get_user_name()
        self.assertEqual(user_name, "myusername")
예제 #6
0
def print_diff_and_syslog(config_type, config_1, config_2):
    """
    Print a readable diff of changes between two texts and log to syslog.
    Returns True if there are changes, that need to be uploaded, or False if
    the two are the same.
    """
    # This makes sure that both configs are strings to avoid issues with
    # combining unicode and strings together
    if isinstance(config_1, unicode):
        config_1 = config_1.encode('utf-8')
    if isinstance(config_2, unicode):
        config_2 = config_2.encode('utf-8')

    unified_diff = use_unified_diff(config_type)
    if unified_diff:
        log.debug("Generating unified diff")
        unified_diff = get_unified_diff(config_1, config_2)
        if len(unified_diff) > 0:
            diff_info = {"Changes:": [unified_diff]}
        else:
            diff_info = None
    else:
        log.debug("Generating per line diff")
        diff_info = get_per_line_diffs(config_1, config_2)

    if diff_info:
        header = "Configuration file change: user {} has modified {}.".format(
            get_user_name(),
            config_type)

        # For the syslog, we want the diff output on one line.
        # For the UI, we want to output on multiple lines, as it's
        # much clearer.
        output_str = header

        for info in diff_info:
            output_str += "\n " + info + "\n"
            output_str += "\n".join(diff_info[info])

        # Print changes to console so the user can do a sanity check
        log.info(output_str)
        print(output_str)

        # The output_str gets encoded as 'utf-8' during audit_log() and you
        # cannot encode utf-8 as utf-8.
        output_str = output_str.decode('utf-8')
        audit_log(output_str)

        return True
    else:
        print("No changes detected in {} file.").format(config_type)
        return False
예제 #7
0
def get_user_download_dir():
    """Returns the user-specific directory for downloaded config."""
    username = get_user_name()
    sub_dir = username if username is not None else ""
    return os.path.join(get_base_download_dir(), sub_dir)
예제 #8
0
def main(args, config_filename):
    """
    Main entry point for script.
    """
    # Set up logging to syslog.
    configure_syslog("clearwater-config-manager", args.log_level)

    # Regardless of passed arguments we want to delete outdated config to not
    # leave unused files on disk.
    delete_outdated_config_files()

    # Create an etcd client for interacting with the database.
    try:
        log.debug("Getting etcdClient with parameters %s, 4000",
                  args.management_ip)
        etcd_client = etcd.client.Client(host=args.management_ip,
                                         port=4000)
        local_store = LocalStore(args.download_dir)

        config_location = local_store.config_location(config_filename)

        selected_config = lookup_config_type(args.config_type, config_location)
        config_loader = ConfigLoader(etcd_client=etcd_client,
                                     etcd_key=args.etcd_key,
                                     site=args.site)
    except (etcd.EtcdException, EtcdConnectionFailed):
        log.error("etcd cluster uncontactable")
        sys.exit("Unable to contact the etcd cluster.")
    except EtcdNoQuorum:
        log.error("etcd cluster doesn't have quorum")
        sys.exit(CLUSTER_NOT_HEALTHY)

    if args.action == "download":
        log.info("User %s triggered download of %s",
                 get_user_name(),
                 args.config_type)
        try:
            download_config(config_loader,
                            local_store,
                            selected_config,
                            args.autoconfirm)
        except (UserAbort, ConfigDownloadFailed) as exc:
            log.error("Download failed")
            sys.exit(exc)

    if args.action == "upload":
        log.info("User %s triggered upload of %s",
                 get_user_name(),
                 args.config_type)
        try:
            upload_verified_config(config_loader,
                                   local_store,
                                   selected_config,
                                   args.force,
                                   args.autoconfirm)
        except ConfigUnchanged:
            # If there are no changes to the config, we don't execute an
            # upload. But that doesn't mean there was a failure - the config
            # on etcd is what the user wanted it to be. We print a message to
            # the user and return a zero error code.
            print NO_CHANGES_TO_CONFIG
        except (UserAbort, ConfigUploadFailed) as exc:
            log.error("Upload failed")
            sys.exit(exc)