Afternoon all
I've recently started looking at streamlining some of the code used in my Puppet NetApp network device module.
The majority of my code using NaServer.invoke, which is nice and straight-forward to understand and use.
However some have been forced to use NaServer.invoke_elem due to the additional complexity in the API.
A good example of this is the nfs-exportfs-append-rules-2 api, which has a lot of additional NaElement constructs below it...
However I started to wonder why I couldn't just use the invoke call, whilst also passing the NaElement fields where required.
This lead me to check out the invoke def in the ruby sdk, which initially looks like this:
#A convenience routine which wraps invoke_elem().
#It constructs an NaElement with name $api, and for
#each argument name/value pair, adds a child element
#to it. It's an error to have an even number of
#arguments to this function.
#Example: myserver->invoke('snapshot-create',
# 'snapshot', 'mysnapshot',
# 'volume', 'vol0');
#
def invoke(api, *args)
num_parms = args.length
if ((num_parms & 1) != 0)
return self.fail_response(13001, "in Zapi::invoke, invalid number of parameters")
end
xi = NaElement.new(api)
i = 0
while(i < num_parms)
key = args[i]
i = i + 1
value = args[i]
i = i + 1
xi.child_add(NaElement.new(key, value))
end
return invoke_elem(xi)
end
So if I try and feed in a NaElement field to invoke, I was getting an error caused by the NaElement construct going into the @contents value rather than the @children value, as shown below:
xi Request looks like:
#<NaElement:0x7f9039184b08
@attrkeys=[],
@attrvals=[],
@children=
[#<NaElement:0x7f9039184978
@attrkeys=[],
@attrvals=[],
@children=[],
@content="true",
@name="persistent">,
#<NaElement:0x7f90391847e8
@attrkeys=[],
@attrvals=[],
@children=[],
@content=
#<NaElement:0x7f9039195638
@attrkeys=[],
@attrvals=[],
@children=
[#<NaElement:0x7f9039195520
@attrkeys=[],
@attrvals=[],
@children=[],
@content="/vol/v_puppet_test1007131448.",
@name="pathname">],
@content="",
@name="pathname-info">,
@name="pathnames">],
@content="",
@name="nfs-exportfs-delete-rules">
INPUT
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE netapp SYSTEM 'file:/etc/netapp_filer.dtd'>
<netapp version='1.13' xmlns='http://www.netapp.com/filer/admin'><nfs-exportfs-delete-rules><persistent>true</persistent><pathnames>#<NaElement:0x7f9039195638></pathnames></nfs-exportfs-delete-rules></netapp>Invalid number of pathnames
So looking closer at 'invoke', I can see that it's treating the arguments passed to it as key/value pairs, and is constructing a new NaElement for every key/value pair. Hence the issue I'm seeing above with pathnames containing a NaElement value.
After a few tweaks, I came up with the following:
def invoke(api, *args)
num_parms = args.length
if ((num_parms & 1) != 0)
return self.fail_response(13001, "in Zapi::invoke, invalid number of parameters")
end
xi = NaElement.new(api)
i = 0
while(i < num_parms)
key = args[i]
i = i + 1
value = args[i]
i = i + 1
if value.class == NaElement
x = NaElement.new(key)
x.child_add(value)
xi.child_add(x)
else
xi.child_add(NaElement.new(key, value))
end
end
return invoke_elem(xi)
end
So, what do people think of the above change? Is this something that could be fed back into the core API SDK?
Cheers
Gavin