Filling in the Missing Parts of NetApp’s API

Late last year, NetApp released long-overdue Python and Ruby support in their SDK, officially known as the NetApp Manageability SDK. The SDK download is – oddly and unfortunately – still buried behind a paywall, and you have to submit a web form about how you plan to use it to get access to the download; otherwise it’s available to all.

But perhaps there’s good reason for hiding the download away: There are still large gaps in the API. For instance, say you want to change the security mode of a qtree? You’re out of luck. (Makes one wonder how NetApp implements this functionality in OnCommand System Manager – are they eating their own dogfood?)

That said, if you’re willing to venture off the beaten (and supported) path, you can use the undocumented system-cli API call. Here’s how I’m using it in a Python wrapper I’m working on that makes the SDK feel a little bit less like handling thinly-varnished XML:

    def invoke_cli(self, *cli_args):
        Call the unsupported/undocumented system-cli API.

        cli_args, joined with spaces, 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')
        out = self.api.invoke_elem(cli)
        if out.results_status() == 'failed':
            raise OntapApiException(out.results_errno(), out.results_reason())
        return out

On lines 11-13, I’m building up an NaElement (itself imported from the eponymous NaElement module) representation of the command line arguments; this is then added as a child to a “system-cli” NaElement. On line 17, I call “NaServer.invoke_elem()” on the “system-cli” NaElement – and from here on out, it’s just like using the ordinary (documented) API. The “cli-output” element in “out” contains the output for you to parse, and “cli-result-value” is a return code.

Here’s hoping newer versions of the API will do away with the need for this workaround.