Beispiel #1
0
    def getNodeOtps(self, to_eject=[], to_failover=[], to_readd=[]):
        """ Convert known nodes into otp node id's.
            """
        listservers = ListServers()
        known_nodes_list = listservers.getNodes(listservers.getData(self.server, self.port, self.user, self.password))
        known_otps = []
        eject_otps = []
        failover_otps = []
        readd_otps = []
        hostnames = []

        for node in known_nodes_list:
            if node.get("otpNode") is None:
                raise Exception("could not access node")
            known_otps.append(node["otpNode"])
            hostnames.append(node["hostname"])
            if node["hostname"] in to_eject:
                eject_otps.append(node["otpNode"])
            if node["hostname"] in to_failover:
                if node["clusterMembership"] != "active":
                    raise Exception("node %s is not active" % node["hostname"])
                else:
                    failover_otps.append((node["otpNode"], node["status"]))
            _, host = node["otpNode"].split("@")
            hostport = "%s:%d" % util.hostport(host)
            if node["hostname"] in to_readd or hostport in to_readd:
                readd_otps.append(node["otpNode"])

        return (known_otps, eject_otps, failover_otps, readd_otps, hostnames)
Beispiel #2
0
    def get_hostlist(self, server, port, user, password, opts):
        try:
            opts.append(("-o", "return"))
            nodes = listservers.ListServers().runCmd('host-list', server, port,
                                                     user, password, False,
                                                     opts)

            for node in nodes:
                (node_server, node_port) = util.hostport(node['hostname'])
                node_stats = {
                    "host": node_server,
                    "port": node_port,
                    "status": node['status'],
                    "master": server
                }
                stats_buffer.nodes[node['hostname']] = node_stats
                if node['status'] == 'healthy':
                    node_info = info.Info().runCmd('get-server-info',
                                                   node_server, node_port,
                                                   user, password, False, opts)
                    self.retrieve_node_stats(node_info, node_stats)
                else:
                    self.log.error("Unhealthy node: %s:%s" %
                                   (node_server, node['status']))
            return nodes
        except Exception, err:
            traceback.print_exc()
            sys.exit(1)
Beispiel #3
0
    def collect_data(self, bucketname, cluster, user, password, inputfile, statsfile, scale_val, opts, output_dir):
        scale_set = []
        if scale_val == 'all':
            scale_set = ['minute', 'hour', 'day', 'week', 'month', 'year']
        else:
            scale_set = [scale_val]

        if not inputfile:
            server, port = util.hostport(cluster)

            #get node list info
            nodes = self.get_hostlist(server, port, user, password, opts)
            self.log.debug(util.pretty_print(stats_buffer.nodes))

            #get bucket list
            bucketlist = self.get_bucketlist(server, port, user, password, bucketname, opts)
            self.log.debug(util.pretty_print(stats_buffer.bucket_info))
            self.log.debug(util.pretty_print(stats_buffer.buckets_summary))

            #get stats from ep-engine
            self.get_mc_stats(server, bucketlist, nodes, bucketname)
            self.log.debug(util.pretty_print(stats_buffer.node_stats))

            collected_data = {}
            for scale in scale_set:
                #get stats from ns-server
                self.get_ns_stats(bucketlist, server, port, user, password, bucketname, scale, opts)

            self.log.debug(util.pretty_print(stats_buffer.buckets))

            collected_data["scale"] = scale_val
            collected_data["nodes"] = stats_buffer.nodes
            collected_data["bucket_info"] = stats_buffer.bucket_info
            collected_data["buckets_summary"] = stats_buffer.buckets_summary
            collected_data["node_stats"] = stats_buffer.node_stats
            collected_data["buckets"] = stats_buffer.buckets
            self.write_file(os.path.join(output_dir, statsfile), collected_data)
        else:
            json_data=open(inputfile)
            collected_data = json.load(json_data)
            json_data.close()
            stats_buffer.nodes = collected_data["nodes"]
            stats_buffer.bucket_info = collected_data["bucket_info"]
            stats_buffer.buckets_summary = collected_data["buckets_summary"]
            stats_buffer.node_stats = collected_data["node_stats"]
            self.get_mc_stats_fromfile(bucketname,
                                       collected_data["buckets"],
                                       collected_data["nodes"])
            stats_buffer.buckets = collected_data["buckets"]
            scale_val = collected_data["scale"]
        return scale_val
Beispiel #4
0
 def get_mc_stats(self, server, bucketlist, nodes):
     #print util.pretty_print(bucketlist)
     for bucket in bucketlist:
         bucket_name = bucket['name']
         stats_buffer.node_stats[bucket_name] = {}
         for node in nodes:
             (node_server, node_port) = util.hostport(node['hostname'])
             self.log.info("  node: %s %s" % (node_server, node['ports']['direct']))
             stats = {}
             mc = cb_bin_client.MemcachedClient(node_server, node['ports']['direct'])
             if bucket["name"] != "Default":
                 mc.sasl_auth_cram_md5(bucket_name.encode("utf8"), bucket["saslPassword"].encode("utf8"))
             self.get_mc_stats_per_node(mc, stats)
             stats_buffer.node_stats[bucket_name][node['hostname']] = stats
Beispiel #5
0
 def get_mc_stats_fromfile(self, bucketname, collected_buckets, collected_nodes):
     for bucket_name in collected_buckets.iterkeys():
         if bucketname == "all" or bucket_name == bucketname:
             # stats_buffer.node_stats[bucket_name] = {}
             if stats_buffer.bucket_info[bucket_name]["bucketType"] == "memcached":
                 self.log.info("Skip memcached bucket: %s" % bucket_name)
                 continue
             for node in collected_nodes.iterkeys():
                 (node_server, node_port) = util.hostport(node)
                 if collected_nodes[node]["status"] == "healthy":
                     try:
                         self.get_mc_stats_per_node(None, stats_buffer.node_stats[bucket_name][node])
                     except Exception, err:
                         traceback.print_exc()
                         sys.exit(1)
Beispiel #6
0
    def collect_data(self,cluster, user, password, opts):
        server, port = util.hostport(cluster)

        #get node list info
        nodes = self.get_hostlist(server, port, user, password, opts)
        self.log.debug(util.pretty_print(stats_buffer.nodes))

        #get bucket list
        bucketlist = self.get_bucketlist(server, port, user, password, opts)
        self.log.debug(util.pretty_print(stats_buffer.bucket_info))

        #get stats from ep-engine
        self.get_mc_stats(server, bucketlist, nodes)
        self.log.debug(util.pretty_print(stats_buffer.node_stats))

        #get stats from ns-server
        self.get_ns_stats(bucketlist, server, port, user, password, opts)
        self.log.debug(util.pretty_print(stats_buffer.buckets))
Beispiel #7
0
 def get_hostlist(self, server, port, user, password, opts):
     try:
         opts.append(("-o", "return"))
         nodes = listservers.ListServers().runCmd("host-list", server, port, user, password, False, opts)
         for node in nodes:
             (node_server, node_port) = util.hostport(node["hostname"])
             node_stats = {"host": node_server, "port": node_port, "status": node["status"], "master": server}
             stats_buffer.nodes[node["hostname"]] = node_stats
             if node["status"] == "healthy":
                 node_info = info.Info().runCmd(
                     "get-server-info", node_server, node_port, user, password, False, opts
                 )
                 self.retrieve_node_stats(node_info, node_stats)
             else:
                 self.log.error("Unhealthy node: %s:%s" % (node_server, node["status"]))
         return nodes
     except Exception, err:
         traceback.print_exc()
         sys.exit(1)
Beispiel #8
0
    def collect_data(self, bucketname, cluster, user, password, inputfile, opts):
        if not inputfile:
            server, port = util.hostport(cluster)

            #get node list info
            nodes = self.get_hostlist(server, port, user, password, opts)
            self.log.debug(util.pretty_print(stats_buffer.nodes))

            #get bucket list
            bucketlist = self.get_bucketlist(server, port, user, password, bucketname, opts)
            self.log.debug(util.pretty_print(stats_buffer.bucket_info))
            self.log.debug(util.pretty_print(stats_buffer.buckets_summary))

            #get stats from ep-engine
            self.get_mc_stats(server, bucketlist, nodes, bucketname)
            self.log.debug(util.pretty_print(stats_buffer.node_stats))
        
            #get stats from ns-server
            self.get_ns_stats(bucketlist, server, port, user, password, bucketname, opts)
            self.log.debug(util.pretty_print(stats_buffer.buckets))

            collected_data = {}
            collected_data["nodes"] = stats_buffer.nodes
            collected_data["bucket_info"] = stats_buffer.bucket_info
            collected_data["buckets_summary"] = stats_buffer.buckets_summary
            collected_data["node_stats"] = stats_buffer.node_stats
            collected_data["buckets"] = stats_buffer.buckets
            self.write_file("stats.json", collected_data)
        else:
            import json
            json_data=open(inputfile)
            collected_data = json.load(json_data)
            json_data.close()
            stats_buffer.nodes = collected_data["nodes"]
            stats_buffer.bucket_info = collected_data["bucket_info"]
            stats_buffer.buckets_summary = collected_data["buckets_summary"]
            stats_buffer.node_stats = collected_data["node_stats"]
            stats_buffer.buckets = collected_data["buckets"]
Beispiel #9
0
 def get_mc_stats(self, server, bucketlist, nodes, bucketname):
     for bucket in bucketlist:
         bucket_name = bucket['name']
         if bucketname == 'all' or bucket_name == bucketname:
             self.log.info("bucket: %s" % bucket_name)
             stats_buffer.node_stats[bucket_name] = {}
             if stats_buffer.bucket_info[bucket_name]["bucketType"] == 'memcached':
                 self.log.info("Skip memcached bucket: %s" % bucket_name)
                 continue
             for node in nodes:
                 (node_server, node_port) = util.hostport(node['hostname'])
                 self.log.info("  node: %s %s" % (node_server, node['ports']['direct']))
                 if node['status'] == 'healthy':
                     try:
                         stats = {}
                         mc = mc_bin_client.MemcachedClient(node_server, node['ports']['direct'])
                         if bucket["name"] != "Default":
                             mc.sasl_auth_plain(bucket_name.encode("utf8"), bucket["saslPassword"].encode("utf8"))
                         self.get_mc_stats_per_node(mc, stats)
                         stats_buffer.node_stats[bucket_name][node['hostname']] = stats
                     except Exception, err:
                         stats_buffer.nodes[node['hostname']]['status'] = 'down'
                         traceback.print_exc()
Beispiel #10
0
    def processOpts(self, cmd, opts):
        """ Set standard opts.
            note: use of a server key keeps optional
            args aligned with server.
            """
        servers = {'add': {}, 'remove': {}, 'failover': {}}

        # don't allow options that don't correspond to given commands

        for o, a in opts:
            usage_msg = "option '%s' is not used with command '%s'" % (o, cmd)

            if o in ("-r", "--server-remove"):
                if cmd in server_no_remove:
                    usage(usage_msg)
            elif o in ("-a", "--server-add", "--server-add-username",
                       "--server-add-password"):
                if cmd in server_no_add:
                    usage(usage_msg)

        server = None
        for o, a in opts:
            if o in ("-a", "--server-add"):
                if a == "self":
                    a = socket.gethostbyname(socket.getfqdn())
                server = "%s:%d" % util.hostport(a)
                servers['add'][server] = {'user': '', 'password': ''}
            elif o == "--server-add-username":
                if server is None:
                    usage("please specify --server-add"
                          " before --server-add-username")
                servers['add'][server]['user'] = a
            elif o == "--server-add-password":
                if server is None:
                    usage("please specify --server-add"
                          " before --server-add-password")
                servers['add'][server]['password'] = a
            elif o in ("-r", "--server-remove"):
                server = "%s:%d" % util.hostport(a)
                servers['remove'][server] = True
                server = None
            elif o in ("--server-failover"):
                server = "%s:%d" % util.hostport(a)
                servers['failover'][server] = True
                server = None
            elif o in ('-o', '--output'):
                if a == 'json':
                    self.output = a
                server = None
            elif o in ('-d', '--debug'):
                self.debug = True
                server = None
            elif o in ('--cluster-init-password', '--cluster-password'):
                self.password_new = a
            elif o in ('--cluster-init-username', '--cluster-username'):
                self.username_new = a
            elif o in ('--cluster-init-port', '--cluster-port'):
                self.port_new = a
            elif o in ('--cluster-init-ramsize', '--cluster-ramsize'):
                self.per_node_quota = a
            elif o == '--enable-auto-failover':
                self.enable_auto_failover = bool_to_str(a)
            elif o == '--enable-notification':
                self.enable_notification = bool_to_str(a)
            elif o == '--auto-failover-timeout':
                self.autofailover_timeout = a
            elif o == '--compaction-db-percentage':
                self.compaction_db_percentage = a
            elif o == '--compaction-db-size':
                self.compaction_db_size = a
            elif o == '--compaction-view-percentage':
                self.compaction_view_percentage = a
            elif o == '--compaction-view-size':
                self.compaction_view_size = a
            elif o == '--compaction-period-from':
                self.compaction_period_from = a
            elif o == '--compaction-period-to':
                self.compaction_period_to = a
            elif o == '--enable-compaction-abort':
                self.enable_compaction_abort = bool_to_str(a)
            elif o == '--enable-compaction-parallel':
                self.enable_compaction_parallel = bool_to_str(a)
            elif o == '--enable-email-alert':
                self.enable_email_alert = bool_to_str(a)
            elif o == '--node-init-data-path':
                self.data_path = a
            elif o == '--node-init-index-path':
                self.index_path = a
            elif o == '--email-recipients':
                self.email_recipient = a
            elif o == '--email-sender':
                self.email_sender = a
            elif o == '--email-user':
                self.email_user = a
            elif o == '--email-password':
                self.email_password = a
            elif o == '--email-host':
                self.email_host = a
            elif o == 'email-port':
                self.email_port = a
            elif o == '--enable-email-encrypt':
                self.email_enable_encrypt = bool_to_str(a)
            elif o == '--alert-auto-failover-node':
                self.autofailover_node = True
            elif o == '--alert-auto-failover-max-reached':
                self.autofailover_max_reached = True
            elif o == '--alert-auto-failover-node-down':
                self.autofailover_node_down = True
            elif o == '--alert-auto-failover-cluster-small':
                self.autofailover_cluster_small = True
            elif o == '--alert-ip-changed':
                self.alert_ip_changed = True
            elif o == '--alert-disk-space':
                self.alert_disk_space = True
            elif o == '--alert-meta-overhead':
                self.alert_meta_overhead = True
            elif o == '--alert-meta-oom':
                self.alert_meta_oom = True
            elif o == '--alert-write-failed':
                self.alert_write_failed = True
            elif o == '--create':
                self.cmd = 'create'
            elif o == '--list':
                self.cmd = 'list'
            elif o == '--delete':
                self.cmd = 'delete'
            elif o == '--set':
                self.cmd = 'set'
            elif o == '--ro-username':
                self.ro_username = a
            elif o == '--ro-password':
                self.ro_password = a
            elif o == '--metadata-purge-interval':
                self.purge_interval = a
            elif o == '--group-name':
                self.group_name = a
            elif o == '--add-servers':
                self.server_list = a
                self.cmd = 'add-servers'
            elif o == '--remove-servers':
                self.server_list = a
                self.cmd = 'remove-servers'
            elif o == '--move-servers':
                self.server_list = a
                self.cmd = 'move-servers'
            elif o == '--from-group':
                self.from_group = a
            elif o == '--to-group':
                self.to_group = a
            elif o == '--rename':
                self.group_rename = a
                self.cmd = 'rename'

        return servers
Beispiel #11
0
    def processOpts(self, cmd, opts):
        """ Set standard opts.
            note: use of a server key keeps optional
            args aligned with server.
            """
        servers = {
            'add': {},
            'remove': {},
            'failover': {}
        }

        # don't allow options that don't correspond to given commands

        for o, a in opts:
            usage_msg = "option '%s' is not used with command '%s'" % (o, cmd)

            if o in ( "-r", "--server-remove"):
                if cmd in server_no_remove:
                    usage(usage_msg)
            elif o in ( "-a", "--server-add",
                        "--server-add-username",
                        "--server-add-password"):
                if cmd in server_no_add:
                    usage(usage_msg)

        server = None
        for o, a in opts:
            if o in ("-a", "--server-add"):
                if a == "self":
                    a = socket.gethostbyname(socket.getfqdn())
                server = "%s:%d" % util.hostport(a)
                servers['add'][server] = { 'user':'', 'password':''}
            elif o == "--server-add-username":
                if server is None:
                    usage("please specify --server-add"
                          " before --server-add-username")
                servers['add'][server]['user'] = a
            elif o == "--server-add-password":
                if server is None:
                    usage("please specify --server-add"
                          " before --server-add-password")
                servers['add'][server]['password'] = a
            elif o in ( "-r", "--server-remove"):
                server = "%s:%d" % util.hostport(a)
                servers['remove'][server] = True
                server = None
            elif o in ( "--server-failover"):
                server = "%s:%d" % util.hostport(a)
                servers['failover'][server] = True
                server = None
            elif o in ('-o', '--output'):
                if a == 'json':
                    self.output = a
                server = None
            elif o in ('-d', '--debug'):
                self.debug = True
                server = None
            elif o in ('--cluster-init-password', '--cluster-password'):
                self.password_new = a
            elif o in ('--cluster-init-username', '--cluster-username'):
                self.username_new = a
            elif o in ('--cluster-init-port', '--cluster-port'):
                self.port_new = a
            elif o in ('--cluster-init-ramsize', '--cluster-ramsize'):
                self.per_node_quota = a
            elif o == '--enable-auto-failover':
                self.enable_auto_failover = bool_to_str(a)
            elif o == '--enable-notification':
                self.enable_notification = bool_to_str(a)
            elif o == '--auto-failover-timeout':
                self.autofailover_timeout = a
            elif o == '--compaction-db-percentage':
                self.compaction_db_percentage = a
            elif o == '--compaction-db-size':
                self.compaction_db_size = a
            elif o == '--compaction-view-percentage':
                self.compaction_view_percentage = a
            elif o == '--compaction-view-size':
                self.compaction_view_size = a
            elif o == '--compaction-period-from':
                self.compaction_period_from = a
            elif o == '--compaction-period-to':
                self.compaction_period_to = a
            elif o == '--enable-compaction-abort':
                self.enable_compaction_abort = bool_to_str(a)
            elif o == '--enable-compaction-parallel':
                self.enable_compaction_parallel = bool_to_str(a)
            elif o == '--enable-email-alert':
                self.enable_email_alert = bool_to_str(a)
            elif o == '--node-init-data-path':
                self.data_path = a
            elif o == '--node-init-index-path':
                self.index_path = a
            elif o == '--email-recipients':
                self.email_recipient = a
            elif o == '--email-sender':
                self.email_sender = a
            elif o == '--email-user':
                self.email_user = a
            elif o == '--email-password':
                self.email_password = a
            elif o == '--email-host':
                self.email_host = a
            elif o == 'email-port':
                self.email_port = a
            elif o == '--enable-email-encrypt':
                self.email_enable_encrypt = bool_to_str(a)
            elif o == '--alert-auto-failover-node':
                self.autofailover_node = True
            elif o == '--alert-auto-failover-max-reached':
                self.autofailover_max_reached = True
            elif o == '--alert-auto-failover-node-down':
                self.autofailover_node_down = True
            elif o == '--alert-auto-failover-cluster-small':
                self.autofailover_cluster_small = True
            elif o == '--alert-ip-changed':
                self.alert_ip_changed = True
            elif o == '--alert-disk-space':
                self.alert_disk_space = True
            elif o == '--alert-meta-overhead':
                self.alert_meta_overhead = True
            elif o == '--alert-meta-oom':
                self.alert_meta_oom = True
            elif o == '--alert-write-failed':
                self.alert_write_failed = True
            elif o == '--create':
                self.cmd = 'create'
            elif o == '--list':
                self.cmd = 'list'
            elif o == '--delete':
                self.cmd = 'delete'
            elif o == '--set':
                self.cmd = 'set'
            elif o == '--ro-username':
                self.ro_username = a
            elif o == '--ro-password':
                self.ro_password = a
            elif o == '--metadata-purge-interval':
                self.purge_interval = a
            elif o == '--group-name':
                self.group_name = a
            elif o == '--add-servers':
                self.server_list = a
                self.cmd = 'add-servers'
            elif o == '--remove-servers':
                self.server_list = a
                self.cmd = 'remove-servers'
            elif o == '--move-servers':
                self.server_list = a
                self.cmd = 'move-servers'
            elif o == '--from-group':
                self.from_group = a
            elif o == '--to-group':
                self.to_group = a
            elif o == '--rename':
                self.group_rename = a
                self.cmd = 'rename'

        return servers
Beispiel #12
0
 def normalize_servers(self, server_list):
     slist = []
     for server in server_list.split(Node.SEP):
         hostport = "%s:%d" % util.hostport(server)
         slist.append(hostport)
     return slist
Beispiel #13
0
    def processOpts(self, cmd, opts):
        """ Set standard opts.
            note: use of a server key keeps optional
            args aligned with server.
            """
        servers = {'add': {}, 'remove': {}, 'failover': {}}

        # don't allow options that don't correspond to given commands

        for o, a in opts:
            usage_msg = "option '%s' is not used with command '%s'" % (o, cmd)

            if o in ("-r", "--server-remove"):
                if cmd in server_no_remove:
                    usage(usage_msg)
            elif o in ("-a", "--server-add", "--server-add-username",
                       "--server-add-password"):
                if cmd in server_no_add:
                    usage(usage_msg)

        server = None

        for o, a in opts:
            if o in ("-a", "--server-add"):
                if a == "self":
                    a = socket.gethostbyname(socket.getfqdn())
                server = "%s:%d" % util.hostport(a)
                servers['add'][server] = {'user': '', 'password': ''}
            elif o == "--server-add-username":
                if server is None:
                    usage("please specify --server-add"
                          " before --server-add-username")
                servers['add'][server]['user'] = a
            elif o == "--server-add-password":
                if server is None:
                    usage("please specify --server-add"
                          " before --server-add-password")
                servers['add'][server]['password'] = a
            elif o in ("-r", "--server-remove"):
                server = "%s:%d" % util.hostport(a)
                servers['remove'][server] = True
                server = None
            elif o in ("--server-failover"):
                server = "%s:%d" % util.hostport(a)
                servers['failover'][server] = True
                server = None
            elif o in ('-o', '--output'):
                if a == 'json':
                    self.output = a
                server = None
            elif o in ('-d', '--debug'):
                self.debug = True
                server = None
            elif o == '--cluster-init-password':
                self.password_new = a
            elif o == '--cluster-init-username':
                self.username_new = a
            elif o == '--cluster-init-port':
                self.port_new = a
            elif o == '--cluster-init-ramsize':
                self.per_node_quota = a
            elif o == '--node-init-data-path':
                self.data_path = a

        return servers
Beispiel #14
0
    def processOpts(self, cmd, opts):
        """ Set standard opts.
            note: use of a server key keeps optional
            args aligned with server.
            """
        servers = {
            'add': {},
            'remove': {},
            'failover': {}
        }

        # don't allow options that don't correspond to given commands

        for o, a in opts:
            usage_msg = "option '%s' is not used with command '%s'" % (o, cmd)

            if o in ( "-r", "--server-remove"):
                if cmd in server_no_remove:
                    usage(usage_msg)
            elif o in ( "-a", "--server-add",
                        "--server-add-username",
                        "--server-add-password"):
                if cmd in server_no_add:
                    usage(usage_msg)

        server = None

        for o, a in opts:
            if o in ("-a", "--server-add"):
                if a == "self":
                    a = socket.gethostbyname(socket.getfqdn())
                server = "%s:%d" % util.hostport(a)
                servers['add'][server] = { 'user':'', 'password':''}
            elif o == "--server-add-username":
                if server is None:
                    usage("please specify --server-add"
                          " before --server-add-username")
                servers['add'][server]['user'] = a
            elif o == "--server-add-password":
                if server is None:
                    usage("please specify --server-add"
                          " before --server-add-password")
                servers['add'][server]['password'] = a
            elif o in ( "-r", "--server-remove"):
                server = "%s:%d" % util.hostport(a)
                servers['remove'][server] = True
                server = None
            elif o in ( "--server-failover"):
                server = "%s:%d" % util.hostport(a)
                servers['failover'][server] = True
                server = None
            elif o in ('-o', '--output'):
                if a == 'json':
                    self.output = a
                server = None
            elif o in ('-d', '--debug'):
                self.debug = True
                server = None
            elif o == '--cluster-init-password':
                self.password_new = a
            elif o == '--cluster-init-username':
                self.username_new = a
            elif o == '--cluster-init-port':
                self.port_new = a
            elif o == '--cluster-init-ramsize':
                self.per_node_quota = a
            elif o == '--node-init-data-path':
                self.data_path = a

        return servers
Beispiel #15
0
    def processOpts(self, cmd, opts):
        """ Set standard opts.
            note: use of a server key keeps optional
            args aligned with server.
            """
        servers = {"add": {}, "remove": {}, "failover": {}, "recovery": {}, "log": {}}

        # don't allow options that don't correspond to given commands

        for o, a in opts:
            usage_msg = "option '%s' is not used with command '%s'" % (o, cmd)

            if o in ("-r", "--server-remove"):
                if cmd in server_no_remove:
                    usage(usage_msg)
            elif o in ("-a", "--server-add", "--server-add-username", "--server-add-password"):
                if cmd in server_no_add:
                    usage(usage_msg)

        server = None
        for o, a in opts:
            if o in ("-a", "--server-add"):
                if a == "self":
                    a = socket.gethostbyname(socket.getfqdn())
                server = "%s:%d" % util.hostport(a)
                servers["add"][server] = {"user": "", "password": ""}
                self.server_list.append(server)
            elif o == "--server-add-username":
                if server:
                    servers["add"][server]["user"] = a
                self.sa_username = a
            elif o == "--server-add-password":
                if server:
                    servers["add"][server]["password"] = a
                self.sa_password = a
            elif o in ("-r", "--server-remove"):
                server = "%s:%d" % util.hostport(a)
                servers["remove"][server] = True
                server = None
            elif o in ("--server-failover"):
                server = "%s:%d" % util.hostport(a)
                servers["failover"][server] = True
                server = None
            elif o in ("--server-recovery"):
                server = "%s:%d" % util.hostport(a)
                servers["recovery"][server] = True
                server = None
            elif o == "--nodes":
                for server in self.normalize_servers(a):
                    servers["log"][server] = True
            elif o in ("-o", "--output"):
                if a == "json":
                    self.output = a
                server = None
            elif o in ("-d", "--debug"):
                self.debug = True
                server = None
            elif o in ("--cluster-init-password", "--cluster-password"):
                self.password_new = a
            elif o in ("--cluster-init-username", "--cluster-username"):
                self.username_new = a
            elif o in ("--cluster-init-port", "--cluster-port"):
                self.port_new = a
            elif o in ("--cluster-init-ramsize", "--cluster-ramsize"):
                self.per_node_quota = a
            elif o == "--enable-auto-failover":
                self.enable_auto_failover = bool_to_str(a)
            elif o == "--enable-notification":
                self.enable_notification = bool_to_str(a)
            elif o == "--auto-failover-timeout":
                self.autofailover_timeout = a
            elif o == "--compaction-db-percentage":
                self.compaction_db_percentage = a
            elif o == "--compaction-db-size":
                self.compaction_db_size = a
            elif o == "--compaction-view-percentage":
                self.compaction_view_percentage = a
            elif o == "--compaction-view-size":
                self.compaction_view_size = a
            elif o == "--compaction-period-from":
                self.compaction_period_from = a
            elif o == "--compaction-period-to":
                self.compaction_period_to = a
            elif o == "--enable-compaction-abort":
                self.enable_compaction_abort = bool_to_str(a)
            elif o == "--enable-compaction-parallel":
                self.enable_compaction_parallel = bool_to_str(a)
            elif o == "--enable-email-alert":
                self.enable_email_alert = bool_to_str(a)
            elif o == "--node-init-data-path":
                self.data_path = a
            elif o == "--node-init-index-path":
                self.index_path = a
            elif o == "--node-init-hostname":
                self.hostname = a
            elif o == "--email-recipients":
                self.email_recipient = a
            elif o == "--email-sender":
                self.email_sender = a
            elif o == "--email-user":
                self.email_user = a
            elif o == "--email-password":
                self.email_password = a
            elif o == "--email-host":
                self.email_host = a
            elif o == "--email-port":
                self.email_port = a
            elif o == "--enable-email-encrypt":
                self.email_enable_encrypt = bool_to_str(a)
            elif o == "--alert-auto-failover-node":
                self.autofailover_node = True
            elif o == "--alert-auto-failover-max-reached":
                self.autofailover_max_reached = True
            elif o == "--alert-auto-failover-node-down":
                self.autofailover_node_down = True
            elif o == "--alert-auto-failover-cluster-small":
                self.autofailover_cluster_small = True
            elif o == "--alert-ip-changed":
                self.alert_ip_changed = True
            elif o == "--alert-disk-space":
                self.alert_disk_space = True
            elif o == "--alert-meta-overhead":
                self.alert_meta_overhead = True
            elif o == "--alert-meta-oom":
                self.alert_meta_oom = True
            elif o == "--alert-write-failed":
                self.alert_write_failed = True
            elif o == "--create":
                self.cmd = "create"
            elif o == "--list":
                self.cmd = "list"
            elif o == "--delete":
                self.cmd = "delete"
            elif o == "--set":
                self.cmd = "set"
            elif o == "--ro-username":
                self.ro_username = a
            elif o == "--ro-password":
                self.ro_password = a
            elif o == "--metadata-purge-interval":
                self.purge_interval = a
            elif o == "--group-name":
                self.group_name = a
            elif o == "--add-servers":
                self.server_list = self.normalize_servers(a)
                self.cmd = "add-servers"
            elif o == "--remove-servers":
                self.server_list = self.normalize_servers(a)
                self.cmd = "remove-servers"
            elif o == "--move-servers":
                self.server_list = self.normalize_servers(a)
                self.cmd = "move-servers"
            elif o == "--from-group":
                self.from_group = a
            elif o == "--to-group":
                self.to_group = a
            elif o == "--rename":
                self.group_rename = a
                self.cmd = "rename"
            elif o == "--retrieve-cert":
                self.cmd = "retrieve"
                self.certificate_file = a
            elif o == "--regenerate-cert":
                self.cmd = "regenerate"
                self.certificate_file = a
            elif o == "--force":
                self.hard_failover = True
            elif o == "--recovery-type":
                self.recovery_type = a
            elif o == "--recovery-buckets":
                self.recovery_buckets = a
            elif o == "--nodes":
                self.nodes = a
            elif o == "--all-nodes":
                self.all_nodes = True
            elif o == "--upload":
                self.upload = True
            elif o == "--upload-host":
                self.upload_host = a
            elif o == "--customer":
                self.customer = a
            elif o == "--ticket":
                self.ticket = a

        return servers