707 lines
17 KiB
Go
707 lines
17 KiB
Go
package oneandone
|
|
|
|
import (
|
|
"github.com/1and1/oneandone-cloudserver-sdk-go"
|
|
"github.com/hashicorp/terraform/helper/schema"
|
|
"strings"
|
|
)
|
|
|
|
func resourceOneandOneMonitoringPolicy() *schema.Resource {
|
|
return &schema.Resource{
|
|
Create: resourceOneandOneMonitoringPolicyCreate,
|
|
Read: resourceOneandOneMonitoringPolicyRead,
|
|
Update: resourceOneandOneMonitoringPolicyUpdate,
|
|
Delete: resourceOneandOneMonitoringPolicyDelete,
|
|
Schema: map[string]*schema.Schema{
|
|
"name": {
|
|
Type: schema.TypeString,
|
|
Required: true,
|
|
},
|
|
"description": {
|
|
Type: schema.TypeString,
|
|
Optional: true,
|
|
},
|
|
"email": {
|
|
Type: schema.TypeString,
|
|
Optional: true,
|
|
},
|
|
"agent": {
|
|
Type: schema.TypeBool,
|
|
Required: true,
|
|
},
|
|
"thresholds": {
|
|
Type: schema.TypeSet,
|
|
Elem: &schema.Resource{
|
|
Schema: map[string]*schema.Schema{
|
|
"cpu": {
|
|
Type: schema.TypeSet,
|
|
Elem: &schema.Resource{
|
|
Schema: map[string]*schema.Schema{
|
|
"warning": {
|
|
Type: schema.TypeSet,
|
|
Elem: &schema.Resource{
|
|
Schema: map[string]*schema.Schema{
|
|
"value": {
|
|
Type: schema.TypeInt,
|
|
Required: true,
|
|
},
|
|
"alert": {
|
|
Type: schema.TypeBool,
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
Required: true,
|
|
},
|
|
"critical": {
|
|
Type: schema.TypeSet,
|
|
Elem: &schema.Resource{
|
|
Schema: map[string]*schema.Schema{
|
|
"value": {
|
|
Type: schema.TypeInt,
|
|
Required: true,
|
|
},
|
|
"alert": {
|
|
Type: schema.TypeBool,
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
Required: true,
|
|
},
|
|
"ram": {
|
|
Type: schema.TypeSet,
|
|
Elem: &schema.Resource{
|
|
Schema: map[string]*schema.Schema{
|
|
"warning": {
|
|
Type: schema.TypeSet,
|
|
Elem: &schema.Resource{
|
|
Schema: map[string]*schema.Schema{
|
|
"value": {
|
|
Type: schema.TypeInt,
|
|
Required: true,
|
|
},
|
|
"alert": {
|
|
Type: schema.TypeBool,
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
Required: true,
|
|
},
|
|
"critical": {
|
|
Type: schema.TypeSet,
|
|
Elem: &schema.Resource{
|
|
Schema: map[string]*schema.Schema{
|
|
"value": {
|
|
Type: schema.TypeInt,
|
|
Required: true,
|
|
},
|
|
"alert": {
|
|
Type: schema.TypeBool,
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
Required: true,
|
|
},
|
|
"disk": {
|
|
Type: schema.TypeSet,
|
|
Elem: &schema.Resource{
|
|
Schema: map[string]*schema.Schema{
|
|
"warning": {
|
|
Type: schema.TypeSet,
|
|
Elem: &schema.Resource{
|
|
Schema: map[string]*schema.Schema{
|
|
"value": {
|
|
Type: schema.TypeInt,
|
|
Required: true,
|
|
},
|
|
"alert": {
|
|
Type: schema.TypeBool,
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
Required: true,
|
|
},
|
|
"critical": {
|
|
Type: schema.TypeSet,
|
|
Elem: &schema.Resource{
|
|
Schema: map[string]*schema.Schema{
|
|
"value": {
|
|
Type: schema.TypeInt,
|
|
Required: true,
|
|
},
|
|
"alert": {
|
|
Type: schema.TypeBool,
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
Required: true,
|
|
},
|
|
"transfer": {
|
|
Type: schema.TypeSet,
|
|
Elem: &schema.Resource{
|
|
Schema: map[string]*schema.Schema{
|
|
"warning": {
|
|
Type: schema.TypeSet,
|
|
Elem: &schema.Resource{
|
|
Schema: map[string]*schema.Schema{
|
|
"value": {
|
|
Type: schema.TypeInt,
|
|
Required: true,
|
|
},
|
|
"alert": {
|
|
Type: schema.TypeBool,
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
Required: true,
|
|
},
|
|
"critical": {
|
|
Type: schema.TypeSet,
|
|
Elem: &schema.Resource{
|
|
Schema: map[string]*schema.Schema{
|
|
"value": {
|
|
Type: schema.TypeInt,
|
|
Required: true,
|
|
},
|
|
"alert": {
|
|
Type: schema.TypeBool,
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
Required: true,
|
|
},
|
|
"internal_ping": {
|
|
Type: schema.TypeSet,
|
|
Elem: &schema.Resource{
|
|
Schema: map[string]*schema.Schema{
|
|
"warning": {
|
|
Type: schema.TypeSet,
|
|
Elem: &schema.Resource{
|
|
Schema: map[string]*schema.Schema{
|
|
"value": {
|
|
Type: schema.TypeInt,
|
|
Required: true,
|
|
},
|
|
"alert": {
|
|
Type: schema.TypeBool,
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
Required: true,
|
|
},
|
|
"critical": {
|
|
Type: schema.TypeSet,
|
|
Elem: &schema.Resource{
|
|
Schema: map[string]*schema.Schema{
|
|
"value": {
|
|
Type: schema.TypeInt,
|
|
Required: true,
|
|
},
|
|
"alert": {
|
|
Type: schema.TypeBool,
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
Required: true,
|
|
},
|
|
},
|
|
},
|
|
Required: true,
|
|
},
|
|
"ports": {
|
|
Type: schema.TypeList,
|
|
Elem: &schema.Resource{
|
|
Schema: map[string]*schema.Schema{
|
|
"email_notification": {
|
|
Type: schema.TypeBool,
|
|
Required: true,
|
|
},
|
|
"port": {
|
|
Type: schema.TypeInt,
|
|
Required: true,
|
|
},
|
|
"protocol": {
|
|
Type: schema.TypeString,
|
|
Optional: true,
|
|
},
|
|
"alert_if": {
|
|
Type: schema.TypeString,
|
|
Optional: true,
|
|
},
|
|
"id": {
|
|
Type: schema.TypeString,
|
|
Computed: true,
|
|
},
|
|
},
|
|
},
|
|
Optional: true,
|
|
},
|
|
"processes": {
|
|
Type: schema.TypeList,
|
|
Elem: &schema.Resource{
|
|
Schema: map[string]*schema.Schema{
|
|
|
|
"email_notification": {
|
|
Type: schema.TypeBool,
|
|
Required: true,
|
|
},
|
|
"process": {
|
|
Type: schema.TypeString,
|
|
Required: true,
|
|
},
|
|
"alert_if": {
|
|
Type: schema.TypeString,
|
|
Optional: true,
|
|
},
|
|
"id": {
|
|
Type: schema.TypeString,
|
|
Computed: true,
|
|
},
|
|
},
|
|
},
|
|
Optional: true,
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func resourceOneandOneMonitoringPolicyCreate(d *schema.ResourceData, meta interface{}) error {
|
|
config := meta.(*Config)
|
|
|
|
mp_request := oneandone.MonitoringPolicy{
|
|
Name: d.Get("name").(string),
|
|
Agent: d.Get("agent").(bool),
|
|
Thresholds: getThresholds(d.Get("thresholds")),
|
|
}
|
|
|
|
if raw, ok := d.GetOk("ports"); ok {
|
|
mp_request.Ports = getPorts(raw)
|
|
}
|
|
|
|
if raw, ok := d.GetOk("processes"); ok {
|
|
mp_request.Processes = getProcesses(raw)
|
|
}
|
|
|
|
mp_id, mp, err := config.API.CreateMonitoringPolicy(&mp_request)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = config.API.WaitForState(mp, "ACTIVE", 30, config.Retries)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
d.SetId(mp_id)
|
|
|
|
return resourceOneandOneMonitoringPolicyRead(d, meta)
|
|
}
|
|
|
|
func resourceOneandOneMonitoringPolicyUpdate(d *schema.ResourceData, meta interface{}) error {
|
|
config := meta.(*Config)
|
|
|
|
req := oneandone.MonitoringPolicy{}
|
|
if d.HasChange("name") {
|
|
_, n := d.GetChange("name")
|
|
req.Name = n.(string)
|
|
}
|
|
|
|
if d.HasChange("description") {
|
|
_, n := d.GetChange("description")
|
|
req.Description = n.(string)
|
|
}
|
|
|
|
if d.HasChange("email") {
|
|
_, n := d.GetChange("email")
|
|
req.Email = n.(string)
|
|
}
|
|
|
|
if d.HasChange("agent") {
|
|
_, n := d.GetChange("agent")
|
|
req.Agent = n.(bool)
|
|
}
|
|
|
|
if d.HasChange("thresholds") {
|
|
_, n := d.GetChange("thresholds")
|
|
req.Thresholds = getThresholds(n)
|
|
}
|
|
|
|
mp, err := config.API.UpdateMonitoringPolicy(d.Id(), &req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = config.API.WaitForState(mp, "ACTIVE", 30, config.Retries)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if d.HasChange("ports") {
|
|
o, n := d.GetChange("ports")
|
|
oldValues := o.([]interface{})
|
|
newValues := n.([]interface{})
|
|
|
|
if len(newValues) > len(oldValues) {
|
|
ports := getPorts(newValues)
|
|
|
|
newports := []oneandone.MonitoringPort{}
|
|
|
|
for _, p := range ports {
|
|
if p.Id == "" {
|
|
newports = append(newports, p)
|
|
}
|
|
}
|
|
|
|
mp, err := config.API.AddMonitoringPolicyPorts(d.Id(), newports)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = config.API.WaitForState(mp, "ACTIVE", 30, config.Retries)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
} else if len(oldValues) > len(newValues) {
|
|
diff := difference(oldValues, newValues)
|
|
ports := getPorts(diff)
|
|
|
|
for _, port := range ports {
|
|
if port.Id == "" {
|
|
continue
|
|
}
|
|
|
|
mp, err := config.API.DeleteMonitoringPolicyPort(d.Id(), port.Id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = config.API.WaitForState(mp, "ACTIVE", 30, config.Retries)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
} else if len(oldValues) == len(newValues) {
|
|
ports := getPorts(newValues)
|
|
|
|
for _, port := range ports {
|
|
mp, err := config.API.ModifyMonitoringPolicyPort(d.Id(), port.Id, &port)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = config.API.WaitForState(mp, "ACTIVE", 30, config.Retries)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if d.HasChange("processes") {
|
|
o, n := d.GetChange("processes")
|
|
oldValues := o.([]interface{})
|
|
newValues := n.([]interface{})
|
|
if len(newValues) > len(oldValues) {
|
|
processes := getProcesses(newValues)
|
|
|
|
newprocesses := []oneandone.MonitoringProcess{}
|
|
|
|
for _, p := range processes {
|
|
if p.Id == "" {
|
|
newprocesses = append(newprocesses, p)
|
|
}
|
|
}
|
|
|
|
mp, err := config.API.AddMonitoringPolicyProcesses(d.Id(), newprocesses)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = config.API.WaitForState(mp, "ACTIVE", 30, config.Retries)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
} else if len(oldValues) > len(newValues) {
|
|
diff := difference(oldValues, newValues)
|
|
processes := getProcesses(diff)
|
|
for _, process := range processes {
|
|
if process.Id == "" {
|
|
continue
|
|
}
|
|
|
|
mp, err := config.API.DeleteMonitoringPolicyProcess(d.Id(), process.Id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = config.API.WaitForState(mp, "ACTIVE", 30, config.Retries)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
} else if len(oldValues) == len(newValues) {
|
|
processes := getProcesses(newValues)
|
|
|
|
for _, process := range processes {
|
|
mp, err := config.API.ModifyMonitoringPolicyProcess(d.Id(), process.Id, &process)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = config.API.WaitForState(mp, "ACTIVE", 30, config.Retries)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return resourceOneandOneMonitoringPolicyRead(d, meta)
|
|
}
|
|
|
|
func resourceOneandOneMonitoringPolicyRead(d *schema.ResourceData, meta interface{}) error {
|
|
config := meta.(*Config)
|
|
|
|
mp, err := config.API.GetMonitoringPolicy(d.Id())
|
|
if err != nil {
|
|
if strings.Contains(err.Error(), "404") {
|
|
d.SetId("")
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
|
|
if len(mp.Servers) > 0 {
|
|
}
|
|
|
|
if len(mp.Ports) > 0 {
|
|
pports := d.Get("ports").([]interface{})
|
|
for i, raw_ports := range pports {
|
|
port := raw_ports.(map[string]interface{})
|
|
port["id"] = mp.Ports[i].Id
|
|
}
|
|
d.Set("ports", pports)
|
|
}
|
|
|
|
if len(mp.Processes) > 0 {
|
|
pprocesses := d.Get("processes").([]interface{})
|
|
for i, raw_processes := range pprocesses {
|
|
process := raw_processes.(map[string]interface{})
|
|
process["id"] = mp.Processes[i].Id
|
|
}
|
|
d.Set("processes", pprocesses)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func resourceOneandOneMonitoringPolicyDelete(d *schema.ResourceData, meta interface{}) error {
|
|
config := meta.(*Config)
|
|
|
|
mp, err := config.API.DeleteMonitoringPolicy(d.Id())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = config.API.WaitUntilDeleted(mp)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func getThresholds(d interface{}) *oneandone.MonitoringThreshold {
|
|
raw_thresholds := d.(*schema.Set).List()
|
|
|
|
toReturn := &oneandone.MonitoringThreshold{}
|
|
|
|
for _, thresholds := range raw_thresholds {
|
|
th_set := thresholds.(map[string]interface{})
|
|
|
|
//CPU
|
|
cpu_raw := th_set["cpu"].(*schema.Set)
|
|
toReturn.Cpu = &oneandone.MonitoringLevel{}
|
|
for _, c := range cpu_raw.List() {
|
|
int_k := c.(map[string]interface{})
|
|
for _, w := range int_k["warning"].(*schema.Set).List() {
|
|
toReturn.Cpu.Warning = &oneandone.MonitoringValue{
|
|
Value: w.(map[string]interface{})["value"].(int),
|
|
Alert: w.(map[string]interface{})["alert"].(bool),
|
|
}
|
|
}
|
|
|
|
for _, c := range int_k["critical"].(*schema.Set).List() {
|
|
toReturn.Cpu.Critical = &oneandone.MonitoringValue{
|
|
Value: c.(map[string]interface{})["value"].(int),
|
|
Alert: c.(map[string]interface{})["alert"].(bool),
|
|
}
|
|
}
|
|
}
|
|
//RAM
|
|
ram_raw := th_set["ram"].(*schema.Set)
|
|
toReturn.Ram = &oneandone.MonitoringLevel{}
|
|
for _, c := range ram_raw.List() {
|
|
int_k := c.(map[string]interface{})
|
|
for _, w := range int_k["warning"].(*schema.Set).List() {
|
|
toReturn.Ram.Warning = &oneandone.MonitoringValue{
|
|
Value: w.(map[string]interface{})["value"].(int),
|
|
Alert: w.(map[string]interface{})["alert"].(bool),
|
|
}
|
|
}
|
|
|
|
for _, c := range int_k["critical"].(*schema.Set).List() {
|
|
toReturn.Ram.Critical = &oneandone.MonitoringValue{
|
|
Value: c.(map[string]interface{})["value"].(int),
|
|
Alert: c.(map[string]interface{})["alert"].(bool),
|
|
}
|
|
}
|
|
}
|
|
|
|
//DISK
|
|
disk_raw := th_set["disk"].(*schema.Set)
|
|
toReturn.Disk = &oneandone.MonitoringLevel{}
|
|
for _, c := range disk_raw.List() {
|
|
int_k := c.(map[string]interface{})
|
|
for _, w := range int_k["warning"].(*schema.Set).List() {
|
|
toReturn.Disk.Warning = &oneandone.MonitoringValue{
|
|
Value: w.(map[string]interface{})["value"].(int),
|
|
Alert: w.(map[string]interface{})["alert"].(bool),
|
|
}
|
|
}
|
|
|
|
for _, c := range int_k["critical"].(*schema.Set).List() {
|
|
toReturn.Disk.Critical = &oneandone.MonitoringValue{
|
|
Value: c.(map[string]interface{})["value"].(int),
|
|
Alert: c.(map[string]interface{})["alert"].(bool),
|
|
}
|
|
}
|
|
}
|
|
|
|
//TRANSFER
|
|
transfer_raw := th_set["transfer"].(*schema.Set)
|
|
toReturn.Transfer = &oneandone.MonitoringLevel{}
|
|
for _, c := range transfer_raw.List() {
|
|
int_k := c.(map[string]interface{})
|
|
for _, w := range int_k["warning"].(*schema.Set).List() {
|
|
toReturn.Transfer.Warning = &oneandone.MonitoringValue{
|
|
Value: w.(map[string]interface{})["value"].(int),
|
|
Alert: w.(map[string]interface{})["alert"].(bool),
|
|
}
|
|
}
|
|
|
|
for _, c := range int_k["critical"].(*schema.Set).List() {
|
|
toReturn.Transfer.Critical = &oneandone.MonitoringValue{
|
|
Value: c.(map[string]interface{})["value"].(int),
|
|
Alert: c.(map[string]interface{})["alert"].(bool),
|
|
}
|
|
}
|
|
}
|
|
//internal ping
|
|
ping_raw := th_set["internal_ping"].(*schema.Set)
|
|
toReturn.InternalPing = &oneandone.MonitoringLevel{}
|
|
for _, c := range ping_raw.List() {
|
|
int_k := c.(map[string]interface{})
|
|
for _, w := range int_k["warning"].(*schema.Set).List() {
|
|
toReturn.InternalPing.Warning = &oneandone.MonitoringValue{
|
|
Value: w.(map[string]interface{})["value"].(int),
|
|
Alert: w.(map[string]interface{})["alert"].(bool),
|
|
}
|
|
}
|
|
|
|
for _, c := range int_k["critical"].(*schema.Set).List() {
|
|
toReturn.InternalPing.Critical = &oneandone.MonitoringValue{
|
|
Value: c.(map[string]interface{})["value"].(int),
|
|
Alert: c.(map[string]interface{})["alert"].(bool),
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return toReturn
|
|
}
|
|
|
|
func getProcesses(d interface{}) []oneandone.MonitoringProcess {
|
|
toReturn := []oneandone.MonitoringProcess{}
|
|
|
|
for _, raw := range d.([]interface{}) {
|
|
port := raw.(map[string]interface{})
|
|
m_port := oneandone.MonitoringProcess{
|
|
EmailNotification: port["email_notification"].(bool),
|
|
}
|
|
|
|
if port["id"] != nil {
|
|
m_port.Id = port["id"].(string)
|
|
}
|
|
|
|
if port["process"] != nil {
|
|
m_port.Process = port["process"].(string)
|
|
}
|
|
|
|
if port["alert_if"] != nil {
|
|
m_port.AlertIf = port["alert_if"].(string)
|
|
}
|
|
|
|
toReturn = append(toReturn, m_port)
|
|
}
|
|
|
|
return toReturn
|
|
}
|
|
|
|
func getPorts(d interface{}) []oneandone.MonitoringPort {
|
|
toReturn := []oneandone.MonitoringPort{}
|
|
|
|
for _, raw := range d.([]interface{}) {
|
|
port := raw.(map[string]interface{})
|
|
m_port := oneandone.MonitoringPort{
|
|
EmailNotification: port["email_notification"].(bool),
|
|
Port: port["port"].(int),
|
|
}
|
|
|
|
if port["id"] != nil {
|
|
m_port.Id = port["id"].(string)
|
|
}
|
|
|
|
if port["protocol"] != nil {
|
|
m_port.Protocol = port["protocol"].(string)
|
|
}
|
|
|
|
if port["alert_if"] != nil {
|
|
m_port.AlertIf = port["alert_if"].(string)
|
|
}
|
|
|
|
toReturn = append(toReturn, m_port)
|
|
}
|
|
|
|
return toReturn
|
|
}
|