Jump to: navigation, search

Difference between revisions of "Trove-Replication-And-Clustering-API-Using-Instances"

(PUT /clusters/{cluster_id}/addnode)
 
(26 intermediate revisions by one other user not shown)
Line 1: Line 1:
 +
=This Wiki Is Outdated=
 +
 +
11/2014: This proposal has been superseded and is kept around for historical purposes. To see the true Clustering specification, visit https://blueprints.launchpad.net/trove/+spec/clustering
 +
 
== Proposed addition to instance object: ==
 
== Proposed addition to instance object: ==
 
Adding an "attributes" or some other cleverly named field that allows us
 
Adding an "attributes" or some other cleverly named field that allows us
Line 21: Line 25:
 
             ]
 
             ]
 
         },  
 
         },  
         "hostame": "f7e68ccf2da64bb8a75bafe0dd3a0080.rackspaceclouddb.com",
+
         "hostname": "f7e68ccf2da64bb8a75bafe0dd3a0080.rackspaceclouddb.com",
 
         "id": "f7e68ccf-2da6-4bb8-a75b-afe0dd3a0080",  
 
         "id": "f7e68ccf-2da6-4bb8-a75b-afe0dd3a0080",  
 
         "links": [
 
         "links": [
Line 44: Line 48:
 
                 "id": "https://service/v1.0/1234/clusters/a66cab3a-041b-4c17-82e7-7ca5333a18f3",
 
                 "id": "https://service/v1.0/1234/clusters/a66cab3a-041b-4c17-82e7-7ca5333a18f3",
 
                 "type": "https://service/v1.0/1234/clustertypes/7782954c-ebec-42f0-894b-d3601016a91e",
 
                 "type": "https://service/v1.0/1234/clustertypes/7782954c-ebec-42f0-894b-d3601016a91e",
                 "role": "slave",
+
                 "role": "read-replica",
 
                 "master": "https://service/v1.0/1234/instances/fbd14327-230c-495e-b6d9-cb593ccd4cbb"
 
                 "master": "https://service/v1.0/1234/instances/fbd14327-230c-495e-b6d9-cb593ccd4cbb"
 
             }
 
             }
Line 51: Line 55:
 
}
 
}
 
</pre>
 
</pre>
 +
 
== List cluster types: ==
 
== List cluster types: ==
 
Returned json:<br/>
 
Returned json:<br/>
Line 84: Line 89:
 
{
 
{
 
     "cluster": {
 
     "cluster": {
         "nodes": 3,
+
         "instances": 3,
 
         "flavorRef": "https://service/v1.0/1234/flavors/1",  
 
         "flavorRef": "https://service/v1.0/1234/flavors/1",  
 
         "name": "replication_set_1",  
 
         "name": "replication_set_1",  
 +
        "description": "Production DB master/slave setup",
 
         "volume": {
 
         "volume": {
 
             "size": 2
 
             "size": 2
Line 96: Line 102:
 
  }
 
  }
 
</pre>
 
</pre>
 +
 +
'''Errors:'''<br>
 +
ClusterTypeNotFound: ClusterType '''{id}''' not found<br>
 +
Max_instances: instance count '''{instances}''' exceeds maximum '''{conf max}'''<br>
  
 
== Create Replication Set: (Previous db instance) ==
 
== Create Replication Set: (Previous db instance) ==
Create a replication set with primaryNode as the model for instance flavor and volume size and it will server as the "Master" node if the cluster type is master/slave or equivalent<br/>
+
Create a replication set with primaryInstance as the model for instance flavor and volume size and it will server as the "Master" instance if the cluster type is master/slave or equivalent<br/>
  
 
===== POST /clusters =====
 
===== POST /clusters =====
Line 105: Line 115:
 
{
 
{
 
     "cluster": {
 
     "cluster": {
         "nodes": 3,
+
         "instances": 3,
 
         "name": "replication_set_1",
 
         "name": "replication_set_1",
 +
        "description": "Production DB master/slave setup",
 
         "flavorRef": "https://service/v1.0/1234/flavors/1",
 
         "flavorRef": "https://service/v1.0/1234/flavors/1",
 
         "clusterConfig": {
 
         "clusterConfig": {
 
             "type": "https://service/v1.0/1234/clustertypes/7782954c-ebec-42f0-894b-d3601016a91e",
 
             "type": "https://service/v1.0/1234/clustertypes/7782954c-ebec-42f0-894b-d3601016a91e",
             "primaryNode": "https://service/v1.0/1234/instances/d3ca44b6-1ba2-4862-b16d-1b2cd115944d"
+
             "primaryInstance": "https://service/v1.0/1234/instances/d3ca44b6-1ba2-4862-b16d-1b2cd115944d"
 
         },
 
         },
 
     }
 
     }
 
}
 
}
 
</pre>
 
</pre>
 +
'''Errors:'''<br>
 +
ClusterTypeNotFound: ClusterType '''{id}''' not found<br>
 +
MaxNumInstances: Instance count '''{instances}''' exceeds maximum '''{conf max}'''<br>
 +
PrimaryInstanceNotFound: Primary instance '''{id}''' not found<br>
  
 
== List cluster or replication sets: ==
 
== List cluster or replication sets: ==
Line 127: Line 142:
 
             },
 
             },
 
             "id": "a66cab3a-041b-4c17-82e7-7ca5333a18f3",
 
             "id": "a66cab3a-041b-4c17-82e7-7ca5333a18f3",
             "nodes": [
+
             "instances": [
 
                 {"id": "https://service/v1.0/1234/instances/fbd14327-230c-495e-b6d9-cb593ccd4cbb"},
 
                 {"id": "https://service/v1.0/1234/instances/fbd14327-230c-495e-b6d9-cb593ccd4cbb"},
 
                 {"id": "https://service/v1.0/1234/instances/7a369ce2-0cfb-4bcd-b342-370a4ae55c09"},
 
                 {"id": "https://service/v1.0/1234/instances/7a369ce2-0cfb-4bcd-b342-370a4ae55c09"},
Line 146: Line 161:
 
         },
 
         },
 
         "id": "a66cab3a-041b-4c17-82e7-7ca5333a18f3",
 
         "id": "a66cab3a-041b-4c17-82e7-7ca5333a18f3",
         "nodes": [
+
         "instances": [
 
             {
 
             {
 
                 "flavor": {
 
                 "flavor": {
Line 219: Line 234:
 
                         "id": "https://service/v1.0/1234/clusters/a66cab3a-041b-4c17-82e7-7ca5333a18f3",
 
                         "id": "https://service/v1.0/1234/clusters/a66cab3a-041b-4c17-82e7-7ca5333a18f3",
 
                         "type": "https://service/v1.0/1234/clustertypes/7782954c-ebec-42f0-894b-d3601016a91e",
 
                         "type": "https://service/v1.0/1234/clustertypes/7782954c-ebec-42f0-894b-d3601016a91e",
                         "role": "slave",
+
                         "role": "read-replica",
 
                         "master": "https://service/v1.0/1234/instances/fbd14327-230c-495e-b6d9-cb593ccd4cbb"
 
                         "master": "https://service/v1.0/1234/instances/fbd14327-230c-495e-b6d9-cb593ccd4cbb"
 
                     }
 
                     }
Line 258: Line 273:
 
                         "id": "https://service/v1.0/1234/clusters/a66cab3a-041b-4c17-82e7-7ca5333a18f3",
 
                         "id": "https://service/v1.0/1234/clusters/a66cab3a-041b-4c17-82e7-7ca5333a18f3",
 
                         "type": "https://service/v1.0/1234/clustertypes/7782954c-ebec-42f0-894b-d3601016a91e",
 
                         "type": "https://service/v1.0/1234/clustertypes/7782954c-ebec-42f0-894b-d3601016a91e",
                         "role": "slave",
+
                         "role": "read-replica",
 
                         "master": "https://service/v1.0/1234/instances/fbd14327-230c-495e-b6d9-cb593ccd4cbb"
 
                         "master": "https://service/v1.0/1234/instances/fbd14327-230c-495e-b6d9-cb593ccd4cbb"
 
                     }
 
                     }
Line 268: Line 283:
 
</pre>
 
</pre>
  
== Drop node from cluster: ==
+
== Drop instance from cluster: ==
List the nodes to delete, allow for more than one node to be specified.
+
List the instances to delete, allow for more than one instance to be specified.
===== DELETE /clusters/{cluster_id}/nodes =====
+
===== PUT /clusters/{cluster_id} =====
 
<pre>
 
<pre>
 
{
 
{
 
     "cluster": {
 
     "cluster": {
 
         "id": "a66cab3a-041b-4c17-82e7-7ca5333a18f3",
 
         "id": "a66cab3a-041b-4c17-82e7-7ca5333a18f3",
         "nodes": [
+
         "instances": [
 
             /* The proposal here would be to allow multiple
 
             /* The proposal here would be to allow multiple
 
             instances to be removed if the clusterType
 
             instances to be removed if the clusterType
Line 292: Line 307:
 
     "cluster": {
 
     "cluster": {
 
         "id": "a66cab3a-041b-4c17-82e7-7ca5333a18f3",
 
         "id": "a66cab3a-041b-4c17-82e7-7ca5333a18f3",
         "node": {
+
         "instance": {
             "id": "f7e68ccf-2da6-4bb8-a75b-afe0dd3a0080"
+
             "id": "https://service/v1.0/1234/instances/f7e68ccf-2da6-4bb8-a75b-afe0dd3a0080"
 
         }
 
         }
 
     }
 
     }
 
}
 
}
 
</pre>
 
</pre>
Or just reduce the number of nodes and let the system decide?  
+
Or just reduce the number of instances and let the system decide?  
or just allow either "node" or "nodes" to give users more ways to
+
or just allow either "instance" or "instances" to give users more ways to
 
control their cluster. <br/>
 
control their cluster. <br/>
 
<pre>
 
<pre>
Line 305: Line 320:
 
     "cluster": {
 
     "cluster": {
 
         "id": "a66cab3a-041b-4c17-82e7-7ca5333a18f3",
 
         "id": "a66cab3a-041b-4c17-82e7-7ca5333a18f3",
         "nodes": 2
+
         "instances": 2
 
     }
 
     }
 
}
 
}
 
</pre>
 
</pre>
 +
'''Errors:'''<br>
 +
MinNumInstances: Instance count '''{Instances}''' below the minimum required '''{conf max}'''<br>
  
== Add node to cluster/replication: ==
+
== Add instance to cluster/replication: ==
===== PUT /clusters/{cluster_id}/nodes =====
+
===== PUT /clusters/{cluster_id}/ =====
Add nodes by just increasing the node count? <br/>
+
Add instances by just increasing the instance count? <br/>
 
<pre>
 
<pre>
 
{
 
{
     /* adding nodes to the cluster, it is assumed that
+
     /* adding instances to the cluster, it is assumed that
 
     you are bringing an uncreated instance into the
 
     you are bringing an uncreated instance into the
     the cluster of servers.  If nodes are of different
+
     the cluster of servers.  If instances are of different
     sizes then default to the size of the master/primary node */
+
     sizes then default to the size of the master/primary instance */
 
     "cluster": {
 
     "cluster": {
 
         "id": "a66cab3a-041b-4c17-82e7-7ca5333a18f3",
 
         "id": "a66cab3a-041b-4c17-82e7-7ca5333a18f3",
         "nodes": 5,
+
         "instances": 5,
 
         "clusterConfig": {
 
         "clusterConfig": {
 
             "type": "https://service/v1.0/1234/clustertypes/7782954c-ebec-42f0-894b-d3601016a91e",
 
             "type": "https://service/v1.0/1234/clustertypes/7782954c-ebec-42f0-894b-d3601016a91e",
Line 329: Line 346:
 
}
 
}
 
</pre>
 
</pre>
 +
'''Errors:'''<br>
 +
ClusterTypeNotFound: ClusterType '''{id}''' not found<br>
 +
Max_Instances: Instance count '''{instances}''' exceeds maximum '''{conf max}'''<br>
  
== Promote a slave node to master: ==
+
== Promote a slave instance to master: ==
 
===== PUT /clusters/{cluster_id}/promote =====
 
===== PUT /clusters/{cluster_id}/promote =====
 
<pre>
 
<pre>
Line 339: Line 359:
 
         },
 
         },
 
         "id": "a66cab3a-041b-4c17-82e7-7ca5333a18f3",
 
         "id": "a66cab3a-041b-4c17-82e7-7ca5333a18f3",
         "node": {
+
         "instance": {
 
             "flavor": {
 
             "flavor": {
 
                 "id": "1",
 
                 "id": "1",
Line 364: Line 384:
 
                 }
 
                 }
 
             ],
 
             ],
             "name": "master_instance",
+
             "name": "slave_instance",
            "status": "ACTIVE",
 
 
             "volume": {
 
             "volume": {
 
                 "size": 20
 
                 "size": 20
Line 381: Line 400:
 
}
 
}
 
</pre>
 
</pre>
 +
'''Errors:'''<br>
 +
ClusterTypeNotFound: ClusterType '''{id}''' not found<br>
 +
PrimaryInstanceNotFound: Primary instance '''{id}''' not found<br>
 +
InvalidRole: Role '''{role}''' is not valid<br>
  
== Restart a cluster (All nodes): ==
+
== Restart a cluster (All instances): ==
 
===== PUT /clusters/{cluster_id}/restart =====
 
===== PUT /clusters/{cluster_id}/restart =====
 
<pre>
 
<pre>
Line 394: Line 417:
 
}
 
}
 
</pre>
 
</pre>
 +
'''Errors:'''<br>
 +
ClusterTypeNotFound: ClusterType '''{id}''' not found<br>
 +
ClusterNotFound: Cluster '''{id}''' not found<br>
  
 
= COMMENTS =
 
= COMMENTS =
 
I think imsplitbit is the bee's knees.
 
I think imsplitbit is the bee's knees.

Latest revision as of 23:12, 17 November 2014

This Wiki Is Outdated

11/2014: This proposal has been superseded and is kept around for historical purposes. To see the true Clustering specification, visit https://blueprints.launchpad.net/trove/+spec/clustering

Proposed addition to instance object:

Adding an "attributes" or some other cleverly named field that allows us to store dynamic information not *just* related to replication or clustering.

GET /instances/{instance_id}
{
    "instance": {
        "created": "2013-05-08T22:43:34", 
        "flavor": {
            "id": "1", 
            "links": [
                {
                    "href": "https://service/v1.0/1234/flavors/1", 
                    "rel": "self"
                }, 
                {
                    "href": "https://service/flavors/1", 
                    "rel": "bookmark"
                }
            ]
        }, 
        "hostname": "f7e68ccf2da64bb8a75bafe0dd3a0080.rackspaceclouddb.com",
        "id": "f7e68ccf-2da6-4bb8-a75b-afe0dd3a0080", 
        "links": [
            {
                "href": "https://service/v1.0/1234/instances/f7e68ccf-2da6-4bb8-a75b-afe0dd3a0080", 
                "rel": "self"
            }, 
            {
                "href": "https://service/instances/f7e68ccf-2da6-4bb8-a75b-afe0dd3a0080", 
                "rel": "bookmark"
            }
        ], 
        "name": "slave_instance", 
        "status": "ACTIVE", 
        "updated": "2013-05-08T22:43:34", 
        "volume": {
            "size": 20, 
            "used": 0.16368598397821188
        },
        "attributes": {
            "cluster": {
                "id": "https://service/v1.0/1234/clusters/a66cab3a-041b-4c17-82e7-7ca5333a18f3",
                "type": "https://service/v1.0/1234/clustertypes/7782954c-ebec-42f0-894b-d3601016a91e",
                "role": "read-replica",
                "master": "https://service/v1.0/1234/instances/fbd14327-230c-495e-b6d9-cb593ccd4cbb"
            }
        }
    }
}

List cluster types:

Returned json:

GET /clustertypes
{
    "clusterTypes": [
        {
            "id": "7782954c-ebec-42f0-894b-d3601016a91e",
            "links": [
                {
                    "href": "https://service/v1.0/1234/clustertypes/7782954c-ebec-42f0-894b-d3601016a91e",
                    "rel": "self"
                },
                {
                    "href": "https://service/clustertypes/7782954c-ebec-42f0-894b-d3601016a91e",
                    "rel": "self"
                }
            ],
            "name": "Master/Slave Replication",
            "type": "master-slave"
        }
    ]
}

Create Replication Set: (No previous db instance, fresh)

This will create 1 master with 2 replicas.

POST /clusters
{
    "cluster": {
        "instances": 3,
        "flavorRef": "https://service/v1.0/1234/flavors/1", 
        "name": "replication_set_1", 
        "description": "Production DB master/slave setup",
        "volume": {
            "size": 2
        },
        "clusterConfig": {
            "type": "https://service/v1.0/1234/clustertypes/7782954c-ebec-42f0-894b-d3601016a91e"
        }
    }
 }

Errors:
ClusterTypeNotFound: ClusterType {id} not found
Max_instances: instance count {instances} exceeds maximum {conf max}

Create Replication Set: (Previous db instance)

Create a replication set with primaryInstance as the model for instance flavor and volume size and it will server as the "Master" instance if the cluster type is master/slave or equivalent

POST /clusters

Optional attributes: flavorRef

{
    "cluster": {
        "instances": 3,
        "name": "replication_set_1",
        "description": "Production DB master/slave setup",
        "flavorRef": "https://service/v1.0/1234/flavors/1",
        "clusterConfig": {
            "type": "https://service/v1.0/1234/clustertypes/7782954c-ebec-42f0-894b-d3601016a91e",
            "primaryInstance": "https://service/v1.0/1234/instances/d3ca44b6-1ba2-4862-b16d-1b2cd115944d"
        },
    }
}

Errors:
ClusterTypeNotFound: ClusterType {id} not found
MaxNumInstances: Instance count {instances} exceeds maximum {conf max}
PrimaryInstanceNotFound: Primary instance {id} not found

List cluster or replication sets:

GET /clusters

Returned JSON object

{
    "clusters": [
        {
            "clusterConfig": {
                "type": "https://service/v1.0/1234/clustertypes/7782954c-ebec-42f0-894b-d3601016a91e",
            },
            "id": "a66cab3a-041b-4c17-82e7-7ca5333a18f3",
            "instances": [
                {"id": "https://service/v1.0/1234/instances/fbd14327-230c-495e-b6d9-cb593ccd4cbb"},
                {"id": "https://service/v1.0/1234/instances/7a369ce2-0cfb-4bcd-b342-370a4ae55c09"},
                {"id": "https://service/v1.0/1234/instances/f7e68ccf-2da6-4bb8-a75b-afe0dd3a0080"}
            ]
        }
    ]
}

List cluster or replication set details:

GET /clusters/{cluster_id}
{
    "cluster": {
        "clusterConfig": {
            "type": "https://service/v1.0/1234/clustertypes/7782954c-ebec-42f0-894b-d3601016a91e",
        },
        "id": "a66cab3a-041b-4c17-82e7-7ca5333a18f3",
        "instances": [
            {
                "flavor": {
                    "id": "1",
                    "links": [
                        {
                            "href": "https://service/v1.0/1234/flavors/1",
                            "rel": "self"
                        },
                        {
                            "href": "https://service/flavors/1",
                            "rel": "bookmark"
                        }
                    ]
                },
                "id": "fbd14327-230c-495e-b6d9-cb593ccd4cbb",
                "links": [
                    {
                        "href": "https://service/v1.0/1234/instances/fbd14327-230c-495e-b6d9-cb593ccd4cbb",
                        "rel": "self"
                    },
                    {
                        "href": "https://service/instances/fbd14327-230c-495e-b6d9-cb593ccd4cbb",
                        "rel": "bookmark"
                    }
                ],
                "name": "master_instance",
                "status": "ACTIVE",
                "volume": {
                    "size": 20
                },
                "attributes": {
                    "cluster": {
                        "id": "https://service/v1.0/1234/clusters/a66cab3a-041b-4c17-82e7-7ca5333a18f3",
                        "type": "https://service/v1.0/1234/clustertypes/7782954c-ebec-42f0-894b-d3601016a91e",
                        "role": "master"
                    }
                }
            },
            {
                "flavor": {
                    "id": "1",
                    "links": [
                        {
                            "href": "https://service/v1.0/1234/flavors/1",
                            "rel": "self"
                        },
                        {
                            "href": "https://service/flavors/1",
                            "rel": "bookmark"
                        }
                    ]
                },
                "id": "7a369ce2-0cfb-4bcd-b342-370a4ae55c09",
                "links": [
                    {
                        "href": "https://service/v1.0/1234/instances/7a369ce2-0cfb-4bcd-b342-370a4ae55c09",
                        "rel": "self"
                    },
                    {
                        "href": "https://service/instances/7a369ce2-0cfb-4bcd-b342-370a4ae55c09",
                        "rel": "bookmark"
                    }
                ],
                "name": "master_instance",
                "status": "ACTIVE",
                "volume": {
                    "size": 20
                },
                "attributes": {
                    "cluster": {
                        "id": "https://service/v1.0/1234/clusters/a66cab3a-041b-4c17-82e7-7ca5333a18f3",
                        "type": "https://service/v1.0/1234/clustertypes/7782954c-ebec-42f0-894b-d3601016a91e",
                        "role": "read-replica",
                        "master": "https://service/v1.0/1234/instances/fbd14327-230c-495e-b6d9-cb593ccd4cbb"
                    }
                }
            },
            {
                "flavor": {
                    "id": "1",
                    "links": [
                        {
                            "href": "https://service/v1.0/1234/flavors/1",
                            "rel": "self"
                        },
                        {
                            "href": "https://service/flavors/1",
                            "rel": "bookmark"
                        }
                    ]
                },
                "id": "f7e68ccf-2da6-4bb8-a75b-afe0dd3a0080",
                "links": [
                    {
                        "href": "https://service/v1.0/1234/instances/f7e68ccf-2da6-4bb8-a75b-afe0dd3a0080",
                        "rel": "self"
                    },
                    {
                        "href": "https://service/instances/f7e68ccf-2da6-4bb8-a75b-afe0dd3a0080",
                        "rel": "bookmark"
                    }
                ],
                "name": "master_instance",
                "status": "ACTIVE",
                "volume": {
                    "size": 20
                },
                "attributes": {
                    "cluster": {
                        "id": "https://service/v1.0/1234/clusters/a66cab3a-041b-4c17-82e7-7ca5333a18f3",
                        "type": "https://service/v1.0/1234/clustertypes/7782954c-ebec-42f0-894b-d3601016a91e",
                        "role": "read-replica",
                        "master": "https://service/v1.0/1234/instances/fbd14327-230c-495e-b6d9-cb593ccd4cbb"
                    }
                }
            },
        ]
    }
}

Drop instance from cluster:

List the instances to delete, allow for more than one instance to be specified.

PUT /clusters/{cluster_id}
{
    "cluster": {
        "id": "a66cab3a-041b-4c17-82e7-7ca5333a18f3",
        "instances": [
            /* The proposal here would be to allow multiple
            instances to be removed if the clusterType
            supports it. Think "I have a master and 2 slaves
            for christmas traffic but no longer need the
            slaves." */
            {"id": "https://service/v1.0/1234/instances/7a369ce2-0cfb-4bcd-b342-370a4ae55c09"},
            {"id": "https://service/v1.0/1234/instances/f7e68ccf-2da6-4bb8-a75b-afe0dd3a0080"}
        ]
    }
}

Or, only one at a time? Or both?

{
    "cluster": {
        "id": "a66cab3a-041b-4c17-82e7-7ca5333a18f3",
        "instance": {
            "id": "https://service/v1.0/1234/instances/f7e68ccf-2da6-4bb8-a75b-afe0dd3a0080"
        }
    }
}

Or just reduce the number of instances and let the system decide? or just allow either "instance" or "instances" to give users more ways to control their cluster.

{
    "cluster": {
        "id": "a66cab3a-041b-4c17-82e7-7ca5333a18f3",
        "instances": 2
    }
}

Errors:
MinNumInstances: Instance count {Instances} below the minimum required {conf max}

Add instance to cluster/replication:

PUT /clusters/{cluster_id}/

Add instances by just increasing the instance count?

{
    /* adding instances to the cluster, it is assumed that
    you are bringing an uncreated instance into the
    the cluster of servers.  If instances are of different
    sizes then default to the size of the master/primary instance */
    "cluster": {
        "id": "a66cab3a-041b-4c17-82e7-7ca5333a18f3",
        "instances": 5,
        "clusterConfig": {
            "type": "https://service/v1.0/1234/clustertypes/7782954c-ebec-42f0-894b-d3601016a91e",
        }

    }
}

Errors:
ClusterTypeNotFound: ClusterType {id} not found
Max_Instances: Instance count {instances} exceeds maximum {conf max}

Promote a slave instance to master:

PUT /clusters/{cluster_id}/promote
{
    "cluster": {
        "clusterConfig": {
            "type": "https://service/v1.0/1234/clustertypes/7782954c-ebec-42f0-894b-d3601016a91e",
        },
        "id": "a66cab3a-041b-4c17-82e7-7ca5333a18f3",
        "instance": {
            "flavor": {
                "id": "1",
                "links": [
                    {
                        "href": "https://service/v1.0/1234/flavors/1",
                        "rel": "self"
                    },
                    {
                        "href": "https://service/flavors/1",
                        "rel": "bookmark"
                    }
                ]
            },
            "id": "f7e68ccf-2da6-4bb8-a75b-afe0dd3a0080",
            "links": [
                {
                    "href": "https://service/v1.0/1234/instances/f7e68ccf-2da6-4bb8-a75b-afe0dd3a0080",
                    "rel": "self"
                },
                {
                    "href": "https://service/instances/f7e68ccf-2da6-4bb8-a75b-afe0dd3a0080",
                    "rel": "bookmark"
                }
            ],
            "name": "slave_instance",
            "volume": {
                "size": 20
            },
            "attributes": {
                "cluster": {
                    "id": "https://service/v1.0/1234/clusters/a66cab3a-041b-4c17-82e7-7ca5333a18f3",
                    "type": "https://service/v1.0/1234/clustertypes/7782954c-ebec-42f0-894b-d3601016a91e",
                    "role": "master",
                    "master": "https://service/v1.0/1234/instances/fbd14327-230c-495e-b6d9-cb593ccd4cbb"
                }
            }
        }
    }
}

Errors:
ClusterTypeNotFound: ClusterType {id} not found
PrimaryInstanceNotFound: Primary instance {id} not found
InvalidRole: Role {role} is not valid

Restart a cluster (All instances):

PUT /clusters/{cluster_id}/restart
{
    "cluster": {
        "clusterConfig": {
            "type": "https://service/v1.0/1234/clustertypes/7782954c-ebec-42f0-894b-d3601016a91e",
        },
        "id": "a66cab3a-041b-4c17-82e7-7ca5333a18f3",
    }
}

Errors:
ClusterTypeNotFound: ClusterType {id} not found
ClusterNotFound: Cluster {id} not found

COMMENTS

I think imsplitbit is the bee's knees.