add API for aliases/ansible

This commit is contained in:
Martin Geno 2016-05-14 13:21:10 +02:00
parent d1aa7ab4d7
commit 139c94f083
4 changed files with 80 additions and 65 deletions

View File

@ -1,43 +1,58 @@
package api package api
import ( import (
"fmt" "fmt"
"net/http" "net/http"
"github.com/julienschmidt/httprouter" "encoding/json"
"github.com/FreifunkBremen/respond-collector/models" "github.com/julienschmidt/httprouter"
"github.com/FreifunkBremen/respond-collector/models"
) )
type ApiAliases struct { type ApiAliases struct {
aliases *models.Aliases aliases *models.Aliases
config *models.Config config *models.Config
nodes *models.Nodes nodes *models.Nodes
} }
func NewAliases (config *models.Config, router *httprouter.Router,prefix string,nodes *models.Nodes) { func NewAliases (config *models.Config, router *httprouter.Router,prefix string,nodes *models.Nodes) {
api := &ApiAliases{ api := &ApiAliases{
aliases: models.NewAliases(config), aliases: models.NewAliases(config),
nodes: nodes, nodes: nodes,
config: config, config: config,
} }
router.GET(prefix, api.GetAll) router.GET(prefix, api.GetAll)
router.GET(prefix+"/ansible", api.AnsibleDiff) router.GET(prefix+"/ansible", api.AnsibleDiff)
router.GET(prefix+"/alias/:nodeid", api.GetOne) router.GET(prefix+"/alias/:nodeid", api.GetOne)
router.POST(prefix+"/alias/:nodeid", api.SaveOne) router.POST(prefix+"/alias/:nodeid", api.SaveOne)
} }
func (api *ApiAliases) GetAll(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { func (api *ApiAliases) GetAll(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
jsonOutput(w,api.aliases.List) jsonOutput(w,api.aliases.List)
} }
func (api *ApiAliases) GetOne(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { func (api *ApiAliases) GetOne(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
if alias := api.aliases.List[ps.ByName("nodeid")]; alias !=nil{ if alias := api.aliases.List[ps.ByName("nodeid")]; alias !=nil{
jsonOutput(w,alias) jsonOutput(w,alias)
} return
fmt.Fprint(w, "Not found: ", ps.ByName("nodeid"),"\n") }
fmt.Fprint(w, "Not found: ", ps.ByName("nodeid"),"\n")
} }
func (api *ApiAliases) SaveOne(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { func (api *ApiAliases) SaveOne(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
alias := &models.Alias{Hostname: ps.ByName("nodeid")} var alias models.Alias
api.aliases.Update(ps.ByName("nodeid"),alias) err := json.NewDecoder(r.Body).Decode(&alias)
api.GetOne(w,r,ps)
if err != nil{
http.Error(w, err.Error(), http.StatusInternalServerError)
fmt.Fprint(w, "Decode: ", ps.ByName("nodeid"),"\n")
return
}
api.aliases.Update(ps.ByName("nodeid"),&alias)
jsonOutput(w,alias)
} }
func (api *ApiAliases) AnsibleDiff(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { func (api *ApiAliases) AnsibleDiff(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
diff := api.aliases.List diff := api.aliases.List
//TODO diff between List and api.nodes (for run not at all) //TODO diff between List and api.nodes (for run not at all)
jsonOutput(w,models.GenerateAnsible(api.nodes,diff)) jsonOutput(w,models.GenerateAnsible(api.nodes,diff))
} }

View File

@ -1,17 +1,17 @@
package api package api
import ( import (
"net/http" "net/http"
"encoding/json" "encoding/json"
) )
func jsonOutput(w http.ResponseWriter,data interface{}){ func jsonOutput(w http.ResponseWriter,data interface{}){
js, err := json.Marshal(data) js, err := json.Marshal(data)
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return
} }
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")
w.Write(js) w.Write(js)
} }

View File

@ -40,19 +40,19 @@ func (e *Aliases) Update(nodeID string, newalias *Alias) {
} }
func (e *Aliases) load() { func (e *Aliases) load() {
path := e.config.Nodes.AliasesPath path := e.config.Nodes.AliasesPath
log.Println("loading", path) log.Println("loading", path)
if data, err := ioutil.ReadFile(path); err == nil { if data, err := ioutil.ReadFile(path); err == nil {
if err := json.Unmarshal(data, e); err == nil { if err := json.Unmarshal(data, e); err == nil {
log.Println("loaded", len(e.List), "aliases") log.Println("loaded", len(e.List), "aliases")
} else { } else {
log.Println("failed to unmarshal nodes:", err) log.Println("failed to unmarshal nodes:", err)
} }
} else { } else {
log.Println("failed loading cached nodes:", err) log.Println("failed loading cached nodes:", err)
} }
} }
// Periodically saves the cached DB to json file // Periodically saves the cached DB to json file

View File

@ -1,30 +1,30 @@
package models package models
type Ansible struct { type Ansible struct {
Nodes []string `json:"nodes"` Nodes []string `json:"nodes"`
Meta struct { Meta struct {
HostVars []*AnsibleHostVars `json:"hostvars"` HostVars []*AnsibleHostVars `json:"hostvars"`
} `json:"_meta"` } `json:"_meta"`
} }
type AnsibleHostVars struct { type AnsibleHostVars struct {
Address string `json:"ansible_ssh_host"` Address string `json:"ansible_ssh_host"`
Hostname string `json:"node_name"` Hostname string `json:"node_name"`
} }
func GenerateAnsible(nodes *Nodes,aliases map[string]*Alias) *Ansible{ func GenerateAnsible(nodes *Nodes,aliases map[string]*Alias) *Ansible{
ansible := &Ansible{Nodes:make([]string,0)} ansible := &Ansible{Nodes:make([]string,0)}
for nodeid,alias := range aliases{ for nodeid,alias := range aliases{
if node := nodes.List[nodeid]; node != nil { if node := nodes.List[nodeid]; node != nil {
ansible.Nodes = append(ansible.Nodes,nodeid) ansible.Nodes = append(ansible.Nodes,nodeid)
vars := &AnsibleHostVars{ vars := &AnsibleHostVars{
Address: node.Nodeinfo.Network.Addresses[0], Address: node.Nodeinfo.Network.Addresses[0],
Hostname: alias.Hostname, Hostname: alias.Hostname,
} }
ansible.Meta.HostVars = append(ansible.Meta.HostVars,vars) ansible.Meta.HostVars = append(ansible.Meta.HostVars,vars)
} }
} }
return ansible return ansible
} }