def set_cifs_homedirs(self, homedirs): """Set the list of CIFS home directory paths for the filer.""" homedir_paths = NaElement('homedir-paths') for d in homedirs: homedir_paths.child_add(NaElement('homedir-path-info', d)) chps = NaElement('cifs-homedir-paths-set') chps.child_add(homedir_paths) self.invoke_elem(chps)
def invoke_cli(s, cli_args): """ Call the unsupported/undocumented system-cli API. cli_args, a list of commands, would represent the command line if executing in the CLI. Return the NaElement result of executing the command. """ args = NaElement('args') for arg in cli_args: args.child_add(NaElement('arg', arg)) cli = NaElement('system-cli') cli.child_add(args) out = s.invoke_elem(cli) if out.results_status() != 'passed': raise Exception(out.results_reason()) return out
def invoke_cli(self, *cli_args): """ Call the unsupported/undocumented system-cli API. args is a tuple of arguments that, joined with spaces, would represent the command line if executing in the CLI. """ args = NaElement('args') for arg in cli_args: args.child_add(NaElement('arg', arg)) cli = NaElement('system-cli') cli.child_add(args) out = self.api.invoke_elem(cli) if out.results_status() == 'failed': raise OntapApiException(out.results_errno(), out.results_reason()) return out
def invoke_cli(self, command): """Undocumented API that runs supplied arguments as a command. API documentation and python code found here: https://communities.netapp.com/message/74370 :command: @todo :returns: Object containing cli-output (string) and cli-result-value (integer) """ args = NaElement('args') for arg in command.split(): args.child_add(NaElement('arg', arg)) cli = NaElement('system-cli') cli.child_add(args) out = self.invoke_elem(cli) check_zapi_error(out) return out
def delete_rule(self): """Remove the exportfs rule for a share.""" # # Construct NaElement tree: # pathname_info = NaElement('pathname-info') pathname_info.child_add(NaElement('name', self.path)) pathnames = NaElement('pathnames') pathnames.child_add(pathname_info) elem = NaElement('nfs-exportfs-delete-rules') elem.child_add(NaElement('persistent', 'true')) elem.child_add(pathnames) # Execute it: self.filer.invoke_elem(elem)
def set_sv_sec_snap_sched(self, sched, auto_update, retention_ct, dow = 'mon-sun', hod = '0'): """ Set the SnapVault snapshot schedule on a SnapVault secondary. sched - SnapVault schedule's name retention_ct - Number of snapshots to be retained dow - Days of week on which the schedule will run hod - Hours of day on whcih the schedule will run """ nae = NaElement('snapvault-secondary-set-snapshot-schedule') snap_sched = NaElement('snapshot-schedule') ssssi = NaElement('snapvault-secondary-snapshot-schedule-info') if auto_update: ssssi.child_add(NaElement('is-auto-update', 'true')) else: ssssi.child_add(NaElement('is-auto-update', 'false')) ssssi.child_add(NaElement('retention-count', int(retention_ct))) ssssi.child_add(NaElement('schedule-name', sched)) ssssi.child_add(NaElement('volume-name', self.name)) sched_info = NaElement('snapvault-schedule-info') sched_info.child_add(NaElement('days-of-week', dow)) sched_info.child_add(NaElement('hours-of_day', str(hod))) sched = NaElement('schedule') sched.child_add(sched_info) ssssi.child_add(sched) snap_sched.child_add(ssssi) nae.child_add(snap_sched) self.filer.invoke_elem(nae)
def get_info(self): """@todo: Docstring for get_info. :returns: @todo """ volume_info = {'volume-autosize-attributes': { 'maximum-size': 'integer', 'increment-size': 'integer', 'is-enabled': 'boolean' }, 'volume-id-attributes': { 'containing-aggregate-name': 'string', 'type': 'string', 'owning-vserver-name': 'string' }, 'volume-inode-attributes': { 'files-total': 'integer', 'files-used': 'integer', 'block-type': 'string' }, 'volume-state-attributes': { 'state': 'string' }, 'volume-space-attributes': { 'percentage-size-used': 'integer', 'size-total': 'integer', 'size-available': 'integer', 'size-used': 'integer', 'size-used-by-snapshots': 'integer', 'space-guarantee': 'string', 'size': 'integer', 'percentage-snapshot-reserve': 'integer', 'percentage-fractional-reserve': 'integer', }, 'volume-sis-attributes': { 'is-sis-volume': 'boolean', 'deduplication-space-saved': 'integer', 'compression-space-saved': 'integer', 'total-space-saved': 'integer' } } vol_get_iter = NaElement('volume-get-iter') query = NaElement('query') vol_query_attrs = NaElement('volume-attributes') vol_id_attrs = NaElement('volume-id-attributes') vol_get_iter.child_add(query) query.child_add(vol_query_attrs) vol_query_attrs.child_add(vol_id_attrs) vol_id_attrs.child_add_string('name', self.name) out = self.invoke_elem(vol_get_iter) attributes_list = out.child_get('attributes-list').children_get()[0] #print attributes_list.sprintf() vol_info_dict = {} for vol_attribute_type, attributes in volume_info.iteritems(): attribute_group = attributes_list.child_get(vol_attribute_type) for attr_name, data_type in attributes.iteritems(): #print vol_attribute_type #print attribute_group #print attr_name #print data_type if data_type == 'string': data = attribute_group.child_get_string(attr_name) vol_info_dict[attr_name] = data elif data_type == 'integer': data = attribute_group.child_get_int(attr_name) vol_info_dict[attr_name] = data elif data_type == 'boolean': data = (attribute_group.child_get_string(attr_name) == 'true') vol_info_dict[attr_name] = data return vol_info_dict
def listVolumes(): isDebug = getConfigOption("Debug") # Build command to list volumes cmd = NaElement("volume-get-iter") xi = NaElement("desired-attributes") xi1 = NaElement("volume-attributes") xi1.child_add(NaElement("volume-id-attributes")) xi1.child_add(NaElement("volume-snapshot-attributes")) xi1.child_add(NaElement("volume-space-attributes")) xi2 = NaElement("volume-clone-attributes") xi2.child_add(NaElement("volume-clone-parent-attributes")) xi1.child_add(xi2) xi.child_add(xi1) cmd.child_add(xi) cmd.child_add_string("max-records", "500") ret = executeCmd(cmd) # Remove volumes from list that contain filterStrings filterString = getConfigOption("VolFilters") filterList = filterString.replace(" ", "").split(",") filteredVolumes = NaElement("attributes-list") for vol in ret.child_get("attributes-list").children_get(): volattrs = vol.child_get("volume-id-attributes") if any(x in volattrs.child_get_string("name") for x in filterList): if isDebug == "True": print "Skipping filtered vol : %s" % volattrs.child_get_string("name") continue if isDebug == "True": print "Volume Name : %s" % volattrs.child_get_string("name") filteredVolumes.child_add(vol) filteredRet = NaElement("results") filteredRet.attr_set("status", "passed") filteredRet.child_add(filteredVolumes) if isDebug == "True": print "Number of volumes (after filtering): " + str(ret.child_get("attributes-list").children_get().__len__()) return filteredRet
], }, } server = ZenOntap('8.8.8.8', 'un', 'pw', 'HTTPS') request = NaElement('perf-object-get-instances') for perf, instances in perfGet.iteritems(): request.child_add_string('objectname', perf) reqinst = NaElement('instances') for instance, counters in instances.iteritems(): reqinst.child_add_string('instance', instance) reqcnts = NaElement('counters') for counter in counters: reqcnts.child_add_string('counter', counter) request.child_add(reqcnts) request.child_add(reqinst) response = server.invoke_elem_async(request) deferreds = [response] naElements = defer.DeferredList(deferreds, consumeErrors=True).addCallback(callback) reactor.run() nodes = [] for result in naElements.__dict__['result']: if result.child_get('instances') is not None: print result.child_get_string('timestamp') nodes.extend(result \ .child_get('instances') \ .child_get('instance-data') \
def modify_rule(self, nosuid=True, root_hosts=[], ro_hosts=[], rw_hosts=[], sec_flavor='sys'): """ Change the exportfs rule for an NFS share. This method follows the semantics of the NetApp API for default values, namely: 'By default, if no 'read-only' or 'read-write' hosts are given, then 'read-write' [access is granted to all hosts].' The exportfs rule must already exist before calling this method, or an exception will be thrown. """ # Parse arguments: if nosuid: nosuid_val = 'true' else: nosuid_val = 'false' # # Construct NaElement tree: # rule_info = NaElement('exports-rule-info') rule_info.child_add(NaElement('nosuid', nosuid_val)) rule_info.child_add(NaElement('pathname', self.path)) host_lists = { 'root': root_hosts, 'read-only': ro_hosts, 'read-write': rw_hosts } for elem in host_lists: if len(host_lists[elem]) > 0: nae = NaElement(elem) for host in host_lists[elem]: ehi = NaElement('exports-hostname-info') ehi.child_add(NaElement('name', host)) nae.child_add(ehi) rule_info.child_add(nae) nfs_export = NaElement('nfs-exportfs-modify-rule') nfs_export.child_add(NaElement('persistent', 'true')) rule = NaElement('rule') rule.child_add(rule_info) nfs_export.child_add(rule) # Execute rule change: self.filer.invoke_elem(nfs_export)
def get_perf_object(self, objectname, read=[], instances=[]): """ Return objectname's performance data in a dict tree. read - optional array of counters whose values are to be read. If not set, all counters are reported. instances - optional array of instances whose values are to be read. If not set, all instances are reported. """ info = self.get_perf_object_info(objectname) get_perf_obj = NaElement('perf-object-get-instances-iter-start') get_perf_obj.child_add(NaElement('objectname', objectname)) if read: read_counters = NaElement('counters') for c in read: read_counters.child_add(NaElement('counter', c)) get_perf_obj.child_add(read_counters) if instances: insts = NaElement('instances') for inst in instances: insts.child_add(NaElement('instance', inst)) get_perf_obj.child_add(insts) out = self.invoke_elem(get_perf_obj) iter_tag = out.child_get_int('tag') iter_recs = out.child_get_int('records') perf_insts = {} i = 0 while i < iter_recs: out = self.invoke('perf-object-get-instances-iter-next', 'maximum', 1, 'tag', iter_tag) inst = out.child_get('instances').child_get('instance-data') inst_name = inst.child_get_string('name') perf_insts[inst_name] = {} counters = inst.child_get('counters').children_get() for c in counters: name = c.child_get_string('name') if info[name]['type'] == 'array': vals = c.child_get_string('value').split(',') data = {} j = 0 while j < len(vals): data[info[name]['labels'][j]] = int(vals[j]) j = j + 1 perf_insts[inst_name][name] = data else: try: perf_insts[inst_name][name] = c.child_get_int('value') except ValueError: # Must be a string... perf_insts[inst_name][name] = c.child_get_string( 'value') i = i + 1 self.invoke('perf-object-get-instances-iter-end', 'tag', iter_tag) return perf_insts
def set_sv_sec_snap_sched(self, sched, auto_update, retention_ct, dow='mon-sun', hod='0'): """ Set the SnapVault snapshot schedule on a SnapVault secondary. sched - SnapVault schedule's name retention_ct - Number of snapshots to be retained dow - Days of week on which the schedule will run hod - Hours of day on whcih the schedule will run """ nae = NaElement('snapvault-secondary-set-snapshot-schedule') snap_sched = NaElement('snapshot-schedule') ssssi = NaElement('snapvault-secondary-snapshot-schedule-info') if auto_update: ssssi.child_add(NaElement('is-auto-update', 'true')) else: ssssi.child_add(NaElement('is-auto-update', 'false')) ssssi.child_add(NaElement('retention-count', int(retention_ct))) ssssi.child_add(NaElement('schedule-name', sched)) ssssi.child_add(NaElement('volume-name', self.name)) sched_info = NaElement('snapvault-schedule-info') sched_info.child_add(NaElement('days-of-week', dow)) sched_info.child_add(NaElement('hours-of_day', str(hod))) sched = NaElement('schedule') sched.child_add(sched_info) ssssi.child_add(sched) snap_sched.child_add(ssssi) nae.child_add(snap_sched) self.filer.invoke_elem(nae)
def modify_rule(self, nosuid=True, root_hosts = [], ro_hosts = [], rw_hosts = [], sec_flavor = 'sys'): """ Change the exportfs rule for an NFS share. This method follows the semantics of the NetApp API for default values, namely: 'By default, if no 'read-only' or 'read-write' hosts are given, then 'read-write' [access is granted to all hosts].' The exportfs rule must already exist before calling this method, or an exception will be thrown. """ # Parse arguments: if nosuid: nosuid_val = 'true' else: nosuid_val = 'false' # # Construct NaElement tree: # rule_info = NaElement('exports-rule-info') rule_info.child_add(NaElement('nosuid', nosuid_val)) rule_info.child_add(NaElement('pathname', self.path)) host_lists = { 'root': root_hosts, 'read-only': ro_hosts, 'read-write': rw_hosts } for elem in host_lists: if len(host_lists[elem]) > 0: nae = NaElement(elem) for host in host_lists[elem]: ehi = NaElement('exports-hostname-info') ehi.child_add(NaElement('name', host)) nae.child_add(ehi) rule_info.child_add(nae) nfs_export = NaElement('nfs-exportfs-modify-rule') nfs_export.child_add(NaElement('persistent', 'true')) rule = NaElement('rule') rule.child_add(rule_info) nfs_export.child_add(rule) # Execute rule change: self.filer.invoke_elem(nfs_export)