Conqueso
Conqueso is a web server that provides an interface for centrally managing dynamic properties across your services. Simply add a client library to your service then track and manage its configuration in Conqueso. Everything's better... Conqueso.
Features
- Web interface with REST API for all your configuration property desires
- Manage typed dynamic properties for each service or globally for all services
- Track your online services and view/filter by instance metadata
What's with the name?
Naming things is hard. The "con" prefix comes from "config" or "configuration". The name is silly and fun to say; we hope you enjoy seeing the word "conqueso" in your code as much as we do.
License
The Conqueso server and the conqueso-client-java library are licensed under the Apache License, Version 2.0.
Dependencies
Conqueso runs on Node.js and is backed by MySQL.
Setup and configuration
Conqueso requires that you provide a SQL user account capable of creating a database and tables. We'll manage all the migrations and database updates for you. You can modify your server settings by modifying
server/config/settings.json
{
"http": {
"port": 8080
},
"db" : {
"type" : "MYSQL",
"config" : {
"host" : "localhost",
"port" : "3306",
"databaseName" : "conqueso",
"user" : "root",
"password" : "root",
"pool" : { "maxConnections": 15, "maxIdleTime": 5000 }
}
},
"properties" : {
"pollIntervalSecs" : 15
},
"logging" : {
"dir" : "logs",
"file" : "server.log",
"level" : "info"
}
}
Running the server
The easiest way to run Conqueso is to download a release, unzip it and run
node server/app
Supported clients
REST API
/api/roles
GET Gets all roles with instances.
[{
"name": "analytics-service",
"instances": 1
},
{
"name": "test-framework-server",
"instances": 0
}]
/api/roles/:role/properties
GET Gets plain/text properties for a role. This will overlay (with precedence) any global properties. For convenience, this will also include special Conqueso properties (conqueso.:role.ips) which is a list of online instances for all the other roles. You may find this useful if you need one service to know where to find another service.
globalprop=my_global_value
aws.metrics.enabled=false
fitness.value=88.33
list.of.items=item1,item2,item3,item4,item5
max.login.attempts=10
web.url.public=http://my-public-url.com
conqueso.analytics-service.ips=10.1.100.78
conqueso.test-framework-server.ips=
conqueso.web-interface-service.ips=
/api/roles/:role/properties?json
GET Gets JSON properties for a role. This will not include global properties or special (conqueso.:role.ips) properties.
{
"name": "global",
"properties": [
{
"id": 18,
"name": "bourbon",
"value": "blantons,four roses,weller",
"type": "STRING_SET",
"description": "Mhm",
"createdAt": "2014-10-02T18:23:33.000Z",
"updatedAt": "2014-10-02T18:23:33.000Z",
"roleId": 1
},
{
"id": 17,
"name": "coffee",
"value": "true",
"type": "BOOLEAN",
"description": "sweet sweet coffee!",
"createdAt": "2014-10-02T18:20:38.000Z",
"updatedAt": "2014-10-02T20:09:15.000Z",
"roleId": 1
},
{
"id": 30,
"name": "rye",
"value": "false",
"type": "BOOLEAN",
"description": null,
"createdAt": "2014-10-02T18:38:06.000Z",
"updatedAt": "2014-10-02T20:09:18.000Z",
"roleId": 1
}
]
}
/api/roles/:role/properties/:property
GET Get a specific property value in plain/text.
curl -X GET "http://localhost:8080/api/roles/global/properties/test"
/api/roles/:role/properties/:property?json
GET Get a specific property in JSON.
/api/roles/:role/properties/:property
PUT /api/roles/:role/properties/
PUT Update an existing property
curl -X PUT "http://localhost:8080/api/roles/global/properties/test" -d "value=new_value"
If you use the version of this API without the property in the URL, then you must specify it as a data parameter:
curl -X PUT "http://localhost:8080/api/roles/global/properties" -d "name=test&value=new_value"
/api/roles/:role/properties/test
DELETE Delete a property.
/api/roles/:role/instances
GET Get all online instances with metadata for a role.
[
{
"role" : "analytics-service",
"ip": "10.1.100.78",
"pollInterval": 60000,
"offline": false,
"createdAt": "2014-02-05T17:05:39.000Z",
"updatedAt": "2014-02-05T18:46:48.000Z",
"metadata": {
"ami-id" : "ami-133cb31d",
"availability-zone" : "us-east-1d",
...
}
},
...
]
You can also query for instances of this role with matching metadata. Example:
/api/roles/my_server_role/instances?ami-id=ami-133cb31d&availability-zone=us-east-1d
/api/roles/:role/properties
POST Send your role properties and instance metadata. Creates a role if one does not already exist. For each property that does not already exist, the property is added with the given type and default value. The description attribute optionally describes the meaning of the property, for display when viewing and editing properties in the Conqueso interface. If an instance does not already exist from the request IP, then a new instance will be created. If an instance from the request IP already exists and the metadata values have changed, other instanaces will be marked offline and a new instance will be created.
{
"instanceMetadata": {
"meta.property.1": "songs you've never heard of",
"meta.property.2": "artisanal cream cheese"
},
"properties": [
{
"name": "hipster-mode-enabled",
"value": "true",
"type": "BOOLEAN",
"description": "Are you wearing skinny jeans?"
}
]
}
/api/instances
GET Returns a list of all online instances across roles. You may filter this list by matching metadata key/values.
/api/instances?ami-id=ami-0be1ba63&availability-zone=us-east-1d
[
{
"role": "mustache-generation-server",
"ip": "111.3.3.3",
"pollInterval": 60000,
"createdAt": "2014-02-07T14:25:07.000Z",
"updatedAt": "2014-03-07T14:25:07.000Z",
"metadata": {
"conqueso.poll.interval": "50000",
"instance-type": "t1.micro",
"ami-id": "ami-0be1ba63",
"block-device-mapping": "ami",
"availability-zone": "us-east-1d"
}
}
]
Create roles and properties on startup
If you want to initialize your server with roles and/or properties, you may create a defaults.json file in the server/config directory. Example file:
[
{
"role": "old-record-player",
"properties": [
{
"name": "company",
"type": "STRING",
"value": "Victor Talking Machine Company",
"description": "What company manufactured the old-record-player"
}
]
},
{
"role": "global",
"properties": [
{
"name": "cassette",
"type": "BOOLEAN",
"value": true
},
{
"name": "books",
"type": "FLOAT",
"value": 12.2,
"description": "Books, yeah books."
}
]
}
]
The following types are supported:
"STRING", "BOOLEAN", "DOUBLE", "FLOAT", "INT", "LONG", "STRING_LIST", "STRING_MAP", "STRING_SET"
The description attribute optionally describes the meaning of the property, for display when viewing and editing properties in the Conqueso interface.
Building
Install node
sudo apt-get update
sudo apt-get install -y python-software-properties python g++ make
sudo add-apt-repository -y ppa:chris-lea/node.js
sudo apt-get update
sudo apt-get install nodejs
Install Grunt and Bower
sudo npm install -g grunt-cli bower
Install NPM dependencies
npm install
Build, pull down Bower dependencies and more
grunt
Package for Chef deployment
grunt package
This will generate a few things. First, it will generate a settings.json.erb in a templates directory at the root of the project, then that will be included in an conqueso-server-.zip file generated in the artifact directory.
To clean up the resulting artifact and templates directory, run "grunt clean".