Skip to content

Commit

Permalink
[gui] add disable checks functionality. (#1311)
Browse files Browse the repository at this point in the history
* [gui] add disable checks functionality.

[gui] set restart warning message

* [releasenotes][skip ci] adding release note for PR
  • Loading branch information
truthbk authored Feb 21, 2018
1 parent c2261ae commit a754988
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 68 deletions.
4 changes: 3 additions & 1 deletion cmd/agent/gui/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"net/http"
"strconv"
"strings"
"time"

"github.com/DataDog/datadog-agent/cmd/agent/common"
"github.com/DataDog/datadog-agent/pkg/config"
Expand Down Expand Up @@ -33,7 +34,8 @@ func agentHandler(r *mux.Router) {

// Sends a simple reply (for checking connection to server)
func ping(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Pong"))
elapsed := time.Now().Unix() - startTimestamp
w.Write([]byte(strconv.FormatInt(elapsed, 10)))
}

// Sends the current agent status
Expand Down
89 changes: 58 additions & 31 deletions cmd/agent/gui/checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"sort"
"strings"
Expand Down Expand Up @@ -42,6 +43,8 @@ func checkHandler(r *mux.Router) {
r.HandleFunc("/getConfig/{checkFolder}/{fileName}", http.HandlerFunc(getCheckConfigFile)).Methods("POST")
r.HandleFunc("/setConfig/{fileName}", http.HandlerFunc(setCheckConfigFile)).Methods("POST")
r.HandleFunc("/setConfig/{checkFolder}/{fileName}", http.HandlerFunc(setCheckConfigFile)).Methods("POST")
r.HandleFunc("/setConfig/{fileName}", http.HandlerFunc(setCheckConfigFile)).Methods("DELETE")
r.HandleFunc("/setConfig/{checkFolder}/{fileName}", http.HandlerFunc(setCheckConfigFile)).Methods("DELETE")
r.HandleFunc("/listChecks", http.HandlerFunc(listChecks)).Methods("POST")
r.HandleFunc("/listConfigs", http.HandlerFunc(listConfigs)).Methods("POST")
}
Expand Down Expand Up @@ -188,42 +191,63 @@ func setCheckConfigFile(w http.ResponseWriter, r *http.Request) {
fileName = filepath.Join(checkFolder, fileName)
}

payload, e := parseBody(r)
if e != nil {
w.Write([]byte(e.Error()))
}
data := []byte(payload.Config)

// Check that the data is actually a valid yaml file
cf := configFormat{}
e = yaml.Unmarshal(data, &cf)
if e != nil {
w.Write([]byte("Error: " + e.Error()))
return
}
if len(cf.Instances) < 1 && cf.MetricConfig == nil {
w.Write([]byte("Configuration file contains no valid instances"))
return
}
if r.Method == "POST" {
payload, e := parseBody(r)
if e != nil {
w.Write([]byte(e.Error()))
}
data := []byte(payload.Config)

// Attempt to write new configs to custom checks directory
path := filepath.Join(config.Datadog.GetString("confd_path"), fileName)
e = ioutil.WriteFile(path, data, 0600)
// Check that the data is actually a valid yaml file
cf := configFormat{}
e = yaml.Unmarshal(data, &cf)
if e != nil {
w.Write([]byte("Error: " + e.Error()))
return
}
if len(cf.Instances) < 1 && cf.MetricConfig == nil {
w.Write([]byte("Configuration file contains no valid instances"))
return
}

// If the write didn't work, try writing to the default checks directory
if e != nil && strings.Contains(e.Error(), "no such file or directory") {
path = filepath.Join(common.GetDistPath(), "conf.d", fileName)
// Attempt to write new configs to custom checks directory
path := filepath.Join(config.Datadog.GetString("confd_path"), fileName)
e = ioutil.WriteFile(path, data, 0600)
}

if e != nil {
w.Write([]byte("Error saving config file: " + e.Error()))
log.Debug("Error saving config file: " + e.Error())
return
}
// If the write didn't work, try writing to the default checks directory
if e != nil && strings.Contains(e.Error(), "no such file or directory") {
path = filepath.Join(common.GetDistPath(), "conf.d", fileName)
e = ioutil.WriteFile(path, data, 0600)
}

if e != nil {
w.Write([]byte("Error saving config file: " + e.Error()))
log.Debug("Error saving config file: " + e.Error())
return
}

log.Infof("Successfully wrote new " + fileName + " config file.")
w.Write([]byte("Success"))
} else if r.Method == "DELETE" {
// Attempt to write new configs to custom checks directory
path := filepath.Join(config.Datadog.GetString("confd_path"), fileName)
e := os.Rename(path, path+".disabled")

log.Infof("Successfully wrote new " + fileName + " config file.")
w.Write([]byte("Success"))
// If the move didn't work, try writing to the dev checks directory
if e != nil {
path = filepath.Join(common.GetDistPath(), "conf.d", fileName)
e = os.Rename(path, path+".disabled")
}

if e != nil {
w.Write([]byte("Error disabling config file: " + e.Error()))
log.Errorf("Error disabling config file (%v): %v ", path, e)
return
}

log.Infof("Successfully disabled integration " + fileName + " config file.")
w.Write([]byte("Success"))
}
}

// Sends a list containing the names of all the checks
Expand Down Expand Up @@ -341,11 +365,14 @@ func hasRightEnding(filename string) bool {
// Only accept files of the format
// {name}.yaml, {name}.yml
// {name}.yaml.default, {name}.yml.default
// {name}.yaml.disabled, {name}.yml.disabled
// {name}.yaml.example, {name}.yml.example

ext := filepath.Ext(filename)
if ext == ".default" {
ext = filepath.Ext(strings.TrimSuffix(filename, ".default"))
} else if ext == ".disabled" {
ext = filepath.Ext(strings.TrimSuffix(filename, ".disabled"))
} else if ext == ".example" {
ext = filepath.Ext(strings.TrimSuffix(filename, ".example"))
}
Expand Down
7 changes: 7 additions & 0 deletions cmd/agent/gui/gui.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"net/http"
"path/filepath"
"strings"
"time"

"github.com/DataDog/datadog-agent/cmd/agent/common"
"github.com/DataDog/datadog-agent/pkg/api/security"
Expand All @@ -25,6 +26,9 @@ var (

// CsrfToken is a session-specific token passed to the GUI's authentication endpoint by app.launchGui
CsrfToken string

// To compute uptime
startTimestamp int64
)

// Payload struct is for the JSON messages received from a client POST request
Expand All @@ -43,6 +47,9 @@ func StopGUIServer() {

// StartGUIServer creates the router, starts the HTTP server & generates the authentication token for access
func StartGUIServer(port string) error {
// Set start time...
startTimestamp = time.Now().Unix()

// Instantiate the gorilla/mux router
router := mux.NewRouter()

Expand Down
11 changes: 8 additions & 3 deletions cmd/agent/gui/views/private/css/stylesheet.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 11 additions & 4 deletions cmd/agent/gui/views/private/css/stylesheet.scss
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,9 @@ a {
text-decoration:none;
text-align: center;
}

#restart_status {
color: #ff0000;
}
#agent_info {
position: absolute;
right: 0px;
Expand Down Expand Up @@ -248,7 +250,7 @@ a {
font-size: $font_size;
padding: 1px;

#submit_settings, #save_check, #add_check, #reload_check {
#submit_settings, #save_check, #disable_check, #add_check, #reload_check {
box-shadow:inset 0px 1px 0px 0px #3dc21b;
background:linear-gradient(to bottom, #44c767 5%, #5cbf2a 100%);
background-color:#44c767;
Expand Down Expand Up @@ -308,6 +310,11 @@ a {
top: 10px;
}

#disable_check {
right: 170px;
top: 10px;
}

#reload_check {
width: 50px;
right: 10px;
Expand All @@ -320,12 +327,12 @@ a {
top: 10px;
}

#submit_settings:hover, #save_check:hover, #reload_check:hover {
#submit_settings:hover, #save_check:hover, , #disable_check:hover, #reload_check:hover {
background:linear-gradient(to bottom, #5cbf2a 5%, #44c767 100%);
background-color:#5cbf2a;
}

#submit_settings:active, #save_check:active, #reload_check:active, #add_check:active {
#submit_settings:active, #save_check:active, #disable_check:active, #reload_check:active, #add_check:active {
margin-top: 1px;
}

Expand Down
Loading

0 comments on commit a754988

Please sign in to comment.