cancel
Showing results for 
Search instead for 
Did you mean: 

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

SOLVED
Highlighted
Occasional Contributor

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 ""

5 REPLIES
Frequent Contributor

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

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> <NodeSmiley Tongueort> <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

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 ipSmiley Tongueort 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

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

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)