vADC Forum

Reply
Occasional Contributor
Posts: 15
Registered: ‎11-30-2012
Accepted Solution

How to use RESTful Control API with Python? - enable, disable, or drain node

Question, how to use RESTful API in Python to enable, disable, or drain a node? plus status of single node in pool

Below is the base script, I have done the other python samples that are on the site and they work great... just stuck and looking for help

### Current BASE ###

#!/usr/bin/python

# Note:    pip install requests or easy_install requests

# Note:    API must be enabled on the STM Setting


import requests

import json

import sys

# Clustered Service for NODES

myPool = 'test_pool'

url = 'https://<stm>:9070/api/tm/1.0/config/active/pools/' + myPool;

# Setup the session

client = requests.Session()

# Set the Userid and Password.  These need to match a UserId and Password for a Stingray user

client.auth = ('admin', 'amin')

# Don't require that the Stingray's certiciate be from a certiticate authority because

# Stingray certificates are self-signed.

client.verify = 0

try:

    # Do the HTTP GET to get the lists of pools.  We are only putting this client.get within a try

    # because if there is no error connecting on this one there shouldn't be an error connnecting

    # on later client.get so that would be an unexpected exception.

    response = client.get(url)

except requests.exceptions.ConnectionError:

    print "Error: Unable to connect to " + url

    sys.exit(1)

data = json.loads(response.content)

#print data

if response.status_code == 200:

# if data.has_key('children'):

# pools = data['children']

# #response = client.get(url + "/" + mypool)

    print data

else:

  print "Error getting data..."

  print ""

Frequent Contributor
Posts: 321
Registered: ‎11-29-2012

Re: How to use RESTful Control API with Python? - enable, disable, or drain node

Hi Richard,

You're on the right track, but there are a couple of possible typos in your script so far:


client.auth = ('admin', 'amin')


Is your admin password 'amin', or is that a typo?


url = 'https://<stm>:9070/api/tm/1.0/config/active/pools/' + myPool;


response = client.get(url)


data = json.loads(response.content)


if data.has_key('children'):


When you request the URL "/api/tm/1.0/config/active/pools/", you'll get a datastructure where the key 'children' maps to a list of children (pools in this case).

You're going for the URL "/api/tm/1.0/config/active/pools/test_pool".  This will give you a datastructure corresponding to the configuration for that pool (or a 404 status if the pool does not exist).  This is the datastructure you will need to modify and PUT back to edit the configuration of the pool.

Here's a sample script that I hope illustrates how to manage the nodes in a pool:


#!/usr/bin/python


# Note:    pip install requests or easy_install requests


# Note:    API must be enabled on the STM Setting



import requests


import json


import sys



# FIXME: ensure that the pool name is correct


myPool = 'test_pool'


# FIXME: ensure that the URL is correct


url = 'https://stingray:9070/api/tm/1.0/config/active/pools/' + myPool;



# Describe the nodes in a Pool (data is the json-derived configuration object)


def describeNodes( data ):


  print "Nodes:      " + ', '.join( data['properties']['basic']['nodes'] )


  print "  draining: " + ', '.join( data['properties']['basic']['draining'] )


  print "  disabled: " + ', '.join( data['properties']['basic']['disabled'] )


  return



# Setup the session


client = requests.Session()


# FIXME: Set the Userid and Password.  These need to match a UserId and Password for a Stingray user


client.auth = ('admin', 'admin')



# Don't require that the Stingray's certiciate be from a certiticate authority because


# Stingray certificates are self-signed.


client.verify = 0



try:


    # Do the HTTP GET to get the lists of pools.  We are only putting this client.get within a try


    # because if there is no error connecting on this one there shouldn't be an error connnecting


    # on later client.get so that would be an unexpected exception.


    response = client.get(url)


except requests.exceptions.ConnectionError:


    print "Error: Unable to connect to " + url


    sys.exit(1)



if response.status_code != 200:


    print "Error: cound not find configuration for " + url + ": status " + str(response.status_code)


    sys.exit(1)



data = json.loads(response.content)


describeNodes(data)



# Modify the pool.  Set all but the first node to be draining (note the list is not sorted)


data['properties']['basic']['draining'] = data['properties']['basic']['nodes'][1:]


# None of the nodes are disabled


data['properties']['basic']['disabled'] = [];



# Put the new config


client.put( url, data = json.dumps( data ), headers = {'content-type': 'application/json'} )



# Get the config and print it (it should have changed)


response = client.get(url)


data = json.loads(response.content)


describeNodes(data)


The easiest way to understand the JSON-based datastructures that the REST API uses is to:

  1. Install an extension/plugin such as JSONView in your web browser so that you can view JSON documents clearly
  2. Go to https://stingray:9070/api/tm/1.0/config/active/pools/test_pool in your web browser to view the JSON structure

regards

Owen

Occasional Contributor
Posts: 15
Registered: ‎11-30-2012

Re: How to use RESTful Control API with Python? - enable, disable, or drain node

#! /usr/bin/env python

#

# Program: endeca_node_mgr.py

# Version: 1.0.0

# Date: 2013-04-14

# By: Richard Pardue

##

# Note: Requires requests 1.0.0 => pip install requests

# Pyton 2.7.3

#

 

import requests 

import json 

import sys 

# Testing values

#mypool = 'MouserCom_Endeca'     # Pool Name

#mynode = '192.168.2.211:15000'  # Is active - Testing

#myoption = 'active'               # Options <active>.<drain>.<status>

##

mypool = sys.argv[1]

mynode = sys.argv[2]

myoption = sys.argv[3]

if myoption == "":

    print "Usage: <Pool Name> <Node:Port> <Option: status, drain, active>"

    exit()

myun = 'admin'

mypw = 'admin'

url = 'https://<stingray:9070>/api/tm/1.0/config/active/pools/' + mypool;

jsontype = {'content-type': 'application/json'}

client = requests.Session()

client.auth = (myun, mypw)

client.verify = False 

try

    # Do the HTTP GET to get the lists of pools.  We are only putting this client.get within a try 

    # because if there is no error connecting on this one there shouldn't be an error connecting 

    # on later client.get so that would be an unexpected exception. 

    response = client.get(url) 

except requests.exceptions.ConnectionError: 

    print "Error: Unable to connect to " + url 

    sys.exit(1)

data = json.loads(response.content)

if response.status_code == 200:

    current_active_nodes = data['properties']['basic']['nodes'];

    current_draining_nodes = data['properties']['basic']['draining']

    current_disabled_nodes = data['properties']['basic']['disabled']

   

    tmp_active_nodes = []

    tmp_draining_nodes = []

    tmp_disabled_nodes = []

    current_node_status = ""

   

    for n, node in enumerate(current_active_nodes):

        tmp_active_nodes.append(node)

        if node == mynode:

            current_node_status = "active"

   

    for n, node in enumerate(current_draining_nodes):

        tmp_draining_nodes.append(node)

        if node == mynode:

            current_node_status = "draining"

           

    for n, node in enumerate(current_disabled_nodes):

        tmp_disabled_nodes.append(node)

        if node == mynode:

            current_node_status = "disabled"       

      

# Returns the current status of a node in a pool

if myoption == "status":

    print current_node_status

    exit()

# Set the node of a pool to draining if not disables    

if myoption == "drain":

    if current_node_status == "draining":

        print "Error: Node is already set to drain"

        exit()

    if current_node_status == "disabled":

        print "Error: can not drain node, it is disabled"

    else:  

        tmp_draining_nodes.append(mynode)

        update_pool = { 'properties' : {

                                        'basic' : {

                                                   'draining' : tmp_draining_nodes

                                                   }

                                        }

                       }

       

        response = client.put(url, data = json.dumps(update_pool), headers = jsontype)

       

        if response.status_code == 200:

            print "draining"

            exit()

        else:

            print "Error: Return Code = " + response.status_code

            exit()           

# Set the node of a pool to active if not disables    

if myoption == "active":

    if current_node_status == "active":

        print "Error: Node is already set to active"

        exit()

    if current_node_status == "disabled":

        print "Error: can not drain node, it is disabled"

    else:  

        tmp_draining_nodes.remove(mynode)

        update_pool = { 'properties' : {

                                        'basic' : {

                                                   'draining' : tmp_draining_nodes

                                                   }

                                        }

                       }

       

        response = client.put(url, data = json.dumps(update_pool), headers = jsontype)

       

        if response.status_code == 200:

            print "active"

            exit()

        else:

            print "Error: Return Code = " + response.status_code

            exit()

else:

    print "Error: No option set"

Occasional Contributor
Posts: 15
Registered: ‎11-30-2012

Re: How to use RESTful Control API with Python? - enable, disable, or drain node

Thanks for your help the other day... it ready helped a lot... I update the script.

plus i found a bug when using the API to disable a node... the web ui will display the ip:port grayed out 2 time, but if you click update the other fake one is gone... (Ver 9.1r1) or if you can the state back to active.

Question:

I have gone through the RestFul API can can not find the url for getting a list of all the nodes that are draining like the Web UI (https://https://<stm:9090>/apps/zxtm/index.fcgi?section=Draining)?

Frequent Contributor
Posts: 321
Registered: ‎11-29-2012

Re: How to use RESTful Control API with Python? - enable, disable, or drain node

Hi Richard,

You can get the list of nodes that are draining per-pool from /api/tm/1.0/config/active/pools/poolname; look at the properties->basic->draining value.

There's no single action to get a list of all of the nodes that are draining in all pools.  The UI reads each pool one at a time and merges the 'draining' lists from each; you will need to do the same.

I've published a code sample here: HowTo: List all of the draining nodes in Stingray using Python and REST

Best regards

Owen

Frequent Contributor
Posts: 321
Registered: ‎11-29-2012

Re: How to use RESTful Control API with Python? - enable, disable, or drain node

Here's an alternative implementation, albeit one that does not support enable/disable: HowTo: Drain a node in multiple pools (Python REST API example)

Join the Community

Get quick and easy access to valuable resource designed to help you manage your Brocade Network.

Download FREE NVMe eBook