github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/oneandone/resource_oneandone_monitoring_policy.go (about)

     1  package oneandone
     2  
     3  import (
     4  	"github.com/1and1/oneandone-cloudserver-sdk-go"
     5  	"github.com/hashicorp/terraform/helper/schema"
     6  	"strings"
     7  )
     8  
     9  func resourceOneandOneMonitoringPolicy() *schema.Resource {
    10  	return &schema.Resource{
    11  		Create: resourceOneandOneMonitoringPolicyCreate,
    12  		Read:   resourceOneandOneMonitoringPolicyRead,
    13  		Update: resourceOneandOneMonitoringPolicyUpdate,
    14  		Delete: resourceOneandOneMonitoringPolicyDelete,
    15  		Schema: map[string]*schema.Schema{
    16  			"name": {
    17  				Type:     schema.TypeString,
    18  				Required: true,
    19  			},
    20  			"description": {
    21  				Type:     schema.TypeString,
    22  				Optional: true,
    23  			},
    24  			"email": {
    25  				Type:     schema.TypeString,
    26  				Optional: true,
    27  			},
    28  			"agent": {
    29  				Type:     schema.TypeBool,
    30  				Required: true,
    31  			},
    32  			"thresholds": {
    33  				Type: schema.TypeSet,
    34  				Elem: &schema.Resource{
    35  					Schema: map[string]*schema.Schema{
    36  						"cpu": {
    37  							Type: schema.TypeSet,
    38  							Elem: &schema.Resource{
    39  								Schema: map[string]*schema.Schema{
    40  									"warning": {
    41  										Type: schema.TypeSet,
    42  										Elem: &schema.Resource{
    43  											Schema: map[string]*schema.Schema{
    44  												"value": {
    45  													Type:     schema.TypeInt,
    46  													Required: true,
    47  												},
    48  												"alert": {
    49  													Type:     schema.TypeBool,
    50  													Required: true,
    51  												},
    52  											},
    53  										},
    54  										Required: true,
    55  									},
    56  									"critical": {
    57  										Type: schema.TypeSet,
    58  										Elem: &schema.Resource{
    59  											Schema: map[string]*schema.Schema{
    60  												"value": {
    61  													Type:     schema.TypeInt,
    62  													Required: true,
    63  												},
    64  												"alert": {
    65  													Type:     schema.TypeBool,
    66  													Required: true,
    67  												},
    68  											},
    69  										},
    70  										Required: true,
    71  									},
    72  								},
    73  							},
    74  							Required: true,
    75  						},
    76  						"ram": {
    77  							Type: schema.TypeSet,
    78  							Elem: &schema.Resource{
    79  								Schema: map[string]*schema.Schema{
    80  									"warning": {
    81  										Type: schema.TypeSet,
    82  										Elem: &schema.Resource{
    83  											Schema: map[string]*schema.Schema{
    84  												"value": {
    85  													Type:     schema.TypeInt,
    86  													Required: true,
    87  												},
    88  												"alert": {
    89  													Type:     schema.TypeBool,
    90  													Required: true,
    91  												},
    92  											},
    93  										},
    94  										Required: true,
    95  									},
    96  									"critical": {
    97  										Type: schema.TypeSet,
    98  										Elem: &schema.Resource{
    99  											Schema: map[string]*schema.Schema{
   100  												"value": {
   101  													Type:     schema.TypeInt,
   102  													Required: true,
   103  												},
   104  												"alert": {
   105  													Type:     schema.TypeBool,
   106  													Required: true,
   107  												},
   108  											},
   109  										},
   110  										Required: true,
   111  									},
   112  								},
   113  							},
   114  							Required: true,
   115  						},
   116  						"disk": {
   117  							Type: schema.TypeSet,
   118  							Elem: &schema.Resource{
   119  								Schema: map[string]*schema.Schema{
   120  									"warning": {
   121  										Type: schema.TypeSet,
   122  										Elem: &schema.Resource{
   123  											Schema: map[string]*schema.Schema{
   124  												"value": {
   125  													Type:     schema.TypeInt,
   126  													Required: true,
   127  												},
   128  												"alert": {
   129  													Type:     schema.TypeBool,
   130  													Required: true,
   131  												},
   132  											},
   133  										},
   134  										Required: true,
   135  									},
   136  									"critical": {
   137  										Type: schema.TypeSet,
   138  										Elem: &schema.Resource{
   139  											Schema: map[string]*schema.Schema{
   140  												"value": {
   141  													Type:     schema.TypeInt,
   142  													Required: true,
   143  												},
   144  												"alert": {
   145  													Type:     schema.TypeBool,
   146  													Required: true,
   147  												},
   148  											},
   149  										},
   150  										Required: true,
   151  									},
   152  								},
   153  							},
   154  							Required: true,
   155  						},
   156  						"transfer": {
   157  							Type: schema.TypeSet,
   158  							Elem: &schema.Resource{
   159  								Schema: map[string]*schema.Schema{
   160  									"warning": {
   161  										Type: schema.TypeSet,
   162  										Elem: &schema.Resource{
   163  											Schema: map[string]*schema.Schema{
   164  												"value": {
   165  													Type:     schema.TypeInt,
   166  													Required: true,
   167  												},
   168  												"alert": {
   169  													Type:     schema.TypeBool,
   170  													Required: true,
   171  												},
   172  											},
   173  										},
   174  										Required: true,
   175  									},
   176  									"critical": {
   177  										Type: schema.TypeSet,
   178  										Elem: &schema.Resource{
   179  											Schema: map[string]*schema.Schema{
   180  												"value": {
   181  													Type:     schema.TypeInt,
   182  													Required: true,
   183  												},
   184  												"alert": {
   185  													Type:     schema.TypeBool,
   186  													Required: true,
   187  												},
   188  											},
   189  										},
   190  										Required: true,
   191  									},
   192  								},
   193  							},
   194  							Required: true,
   195  						},
   196  						"internal_ping": {
   197  							Type: schema.TypeSet,
   198  							Elem: &schema.Resource{
   199  								Schema: map[string]*schema.Schema{
   200  									"warning": {
   201  										Type: schema.TypeSet,
   202  										Elem: &schema.Resource{
   203  											Schema: map[string]*schema.Schema{
   204  												"value": {
   205  													Type:     schema.TypeInt,
   206  													Required: true,
   207  												},
   208  												"alert": {
   209  													Type:     schema.TypeBool,
   210  													Required: true,
   211  												},
   212  											},
   213  										},
   214  										Required: true,
   215  									},
   216  									"critical": {
   217  										Type: schema.TypeSet,
   218  										Elem: &schema.Resource{
   219  											Schema: map[string]*schema.Schema{
   220  												"value": {
   221  													Type:     schema.TypeInt,
   222  													Required: true,
   223  												},
   224  												"alert": {
   225  													Type:     schema.TypeBool,
   226  													Required: true,
   227  												},
   228  											},
   229  										},
   230  										Required: true,
   231  									},
   232  								},
   233  							},
   234  							Required: true,
   235  						},
   236  					},
   237  				},
   238  				Required: true,
   239  			},
   240  			"ports": {
   241  				Type: schema.TypeList,
   242  				Elem: &schema.Resource{
   243  					Schema: map[string]*schema.Schema{
   244  						"email_notification": {
   245  							Type:     schema.TypeBool,
   246  							Required: true,
   247  						},
   248  						"port": {
   249  							Type:     schema.TypeInt,
   250  							Required: true,
   251  						},
   252  						"protocol": {
   253  							Type:     schema.TypeString,
   254  							Optional: true,
   255  						},
   256  						"alert_if": {
   257  							Type:     schema.TypeString,
   258  							Optional: true,
   259  						},
   260  						"id": {
   261  							Type:     schema.TypeString,
   262  							Computed: true,
   263  						},
   264  					},
   265  				},
   266  				Optional: true,
   267  			},
   268  			"processes": {
   269  				Type: schema.TypeList,
   270  				Elem: &schema.Resource{
   271  					Schema: map[string]*schema.Schema{
   272  
   273  						"email_notification": {
   274  							Type:     schema.TypeBool,
   275  							Required: true,
   276  						},
   277  						"process": {
   278  							Type:     schema.TypeString,
   279  							Required: true,
   280  						},
   281  						"alert_if": {
   282  							Type:     schema.TypeString,
   283  							Optional: true,
   284  						},
   285  						"id": {
   286  							Type:     schema.TypeString,
   287  							Computed: true,
   288  						},
   289  					},
   290  				},
   291  				Optional: true,
   292  			},
   293  		},
   294  	}
   295  }
   296  
   297  func resourceOneandOneMonitoringPolicyCreate(d *schema.ResourceData, meta interface{}) error {
   298  	config := meta.(*Config)
   299  
   300  	mp_request := oneandone.MonitoringPolicy{
   301  		Name:       d.Get("name").(string),
   302  		Agent:      d.Get("agent").(bool),
   303  		Thresholds: getThresholds(d.Get("thresholds")),
   304  	}
   305  
   306  	if raw, ok := d.GetOk("ports"); ok {
   307  		mp_request.Ports = getPorts(raw)
   308  	}
   309  
   310  	if raw, ok := d.GetOk("processes"); ok {
   311  		mp_request.Processes = getProcesses(raw)
   312  	}
   313  
   314  	mp_id, mp, err := config.API.CreateMonitoringPolicy(&mp_request)
   315  	if err != nil {
   316  		return err
   317  	}
   318  
   319  	err = config.API.WaitForState(mp, "ACTIVE", 30, config.Retries)
   320  	if err != nil {
   321  		return err
   322  	}
   323  
   324  	d.SetId(mp_id)
   325  
   326  	return resourceOneandOneMonitoringPolicyRead(d, meta)
   327  }
   328  
   329  func resourceOneandOneMonitoringPolicyUpdate(d *schema.ResourceData, meta interface{}) error {
   330  	config := meta.(*Config)
   331  
   332  	req := oneandone.MonitoringPolicy{}
   333  	if d.HasChange("name") {
   334  		_, n := d.GetChange("name")
   335  		req.Name = n.(string)
   336  	}
   337  
   338  	if d.HasChange("description") {
   339  		_, n := d.GetChange("description")
   340  		req.Description = n.(string)
   341  	}
   342  
   343  	if d.HasChange("email") {
   344  		_, n := d.GetChange("email")
   345  		req.Email = n.(string)
   346  	}
   347  
   348  	if d.HasChange("agent") {
   349  		_, n := d.GetChange("agent")
   350  		req.Agent = n.(bool)
   351  	}
   352  
   353  	if d.HasChange("thresholds") {
   354  		_, n := d.GetChange("thresholds")
   355  		req.Thresholds = getThresholds(n)
   356  	}
   357  
   358  	mp, err := config.API.UpdateMonitoringPolicy(d.Id(), &req)
   359  	if err != nil {
   360  		return err
   361  	}
   362  
   363  	err = config.API.WaitForState(mp, "ACTIVE", 30, config.Retries)
   364  	if err != nil {
   365  		return err
   366  	}
   367  
   368  	if d.HasChange("ports") {
   369  		o, n := d.GetChange("ports")
   370  		oldValues := o.([]interface{})
   371  		newValues := n.([]interface{})
   372  
   373  		if len(newValues) > len(oldValues) {
   374  			ports := getPorts(newValues)
   375  
   376  			newports := []oneandone.MonitoringPort{}
   377  
   378  			for _, p := range ports {
   379  				if p.Id == "" {
   380  					newports = append(newports, p)
   381  				}
   382  			}
   383  
   384  			mp, err := config.API.AddMonitoringPolicyPorts(d.Id(), newports)
   385  			if err != nil {
   386  				return err
   387  			}
   388  
   389  			err = config.API.WaitForState(mp, "ACTIVE", 30, config.Retries)
   390  			if err != nil {
   391  				return err
   392  			}
   393  		} else if len(oldValues) > len(newValues) {
   394  			diff := difference(oldValues, newValues)
   395  			ports := getPorts(diff)
   396  
   397  			for _, port := range ports {
   398  				if port.Id == "" {
   399  					continue
   400  				}
   401  
   402  				mp, err := config.API.DeleteMonitoringPolicyPort(d.Id(), port.Id)
   403  				if err != nil {
   404  					return err
   405  				}
   406  
   407  				err = config.API.WaitForState(mp, "ACTIVE", 30, config.Retries)
   408  				if err != nil {
   409  					return err
   410  				}
   411  			}
   412  		} else if len(oldValues) == len(newValues) {
   413  			ports := getPorts(newValues)
   414  
   415  			for _, port := range ports {
   416  				mp, err := config.API.ModifyMonitoringPolicyPort(d.Id(), port.Id, &port)
   417  				if err != nil {
   418  					return err
   419  				}
   420  
   421  				err = config.API.WaitForState(mp, "ACTIVE", 30, config.Retries)
   422  				if err != nil {
   423  					return err
   424  				}
   425  			}
   426  		}
   427  	}
   428  
   429  	if d.HasChange("processes") {
   430  		o, n := d.GetChange("processes")
   431  		oldValues := o.([]interface{})
   432  		newValues := n.([]interface{})
   433  		if len(newValues) > len(oldValues) {
   434  			processes := getProcesses(newValues)
   435  
   436  			newprocesses := []oneandone.MonitoringProcess{}
   437  
   438  			for _, p := range processes {
   439  				if p.Id == "" {
   440  					newprocesses = append(newprocesses, p)
   441  				}
   442  			}
   443  
   444  			mp, err := config.API.AddMonitoringPolicyProcesses(d.Id(), newprocesses)
   445  			if err != nil {
   446  				return err
   447  			}
   448  
   449  			err = config.API.WaitForState(mp, "ACTIVE", 30, config.Retries)
   450  			if err != nil {
   451  				return err
   452  			}
   453  		} else if len(oldValues) > len(newValues) {
   454  			diff := difference(oldValues, newValues)
   455  			processes := getProcesses(diff)
   456  			for _, process := range processes {
   457  				if process.Id == "" {
   458  					continue
   459  				}
   460  
   461  				mp, err := config.API.DeleteMonitoringPolicyProcess(d.Id(), process.Id)
   462  				if err != nil {
   463  					return err
   464  				}
   465  
   466  				err = config.API.WaitForState(mp, "ACTIVE", 30, config.Retries)
   467  				if err != nil {
   468  					return err
   469  				}
   470  			}
   471  		} else if len(oldValues) == len(newValues) {
   472  			processes := getProcesses(newValues)
   473  
   474  			for _, process := range processes {
   475  				mp, err := config.API.ModifyMonitoringPolicyProcess(d.Id(), process.Id, &process)
   476  				if err != nil {
   477  					return err
   478  				}
   479  
   480  				err = config.API.WaitForState(mp, "ACTIVE", 30, config.Retries)
   481  				if err != nil {
   482  					return err
   483  				}
   484  			}
   485  		}
   486  	}
   487  
   488  	return resourceOneandOneMonitoringPolicyRead(d, meta)
   489  }
   490  
   491  func resourceOneandOneMonitoringPolicyRead(d *schema.ResourceData, meta interface{}) error {
   492  	config := meta.(*Config)
   493  
   494  	mp, err := config.API.GetMonitoringPolicy(d.Id())
   495  	if err != nil {
   496  		if strings.Contains(err.Error(), "404") {
   497  			d.SetId("")
   498  			return nil
   499  		}
   500  		return err
   501  	}
   502  
   503  	if len(mp.Servers) > 0 {
   504  	}
   505  
   506  	if len(mp.Ports) > 0 {
   507  		pports := d.Get("ports").([]interface{})
   508  		for i, raw_ports := range pports {
   509  			port := raw_ports.(map[string]interface{})
   510  			port["id"] = mp.Ports[i].Id
   511  		}
   512  		d.Set("ports", pports)
   513  	}
   514  
   515  	if len(mp.Processes) > 0 {
   516  		pprocesses := d.Get("processes").([]interface{})
   517  		for i, raw_processes := range pprocesses {
   518  			process := raw_processes.(map[string]interface{})
   519  			process["id"] = mp.Processes[i].Id
   520  		}
   521  		d.Set("processes", pprocesses)
   522  	}
   523  
   524  	return nil
   525  }
   526  
   527  func resourceOneandOneMonitoringPolicyDelete(d *schema.ResourceData, meta interface{}) error {
   528  	config := meta.(*Config)
   529  
   530  	mp, err := config.API.DeleteMonitoringPolicy(d.Id())
   531  	if err != nil {
   532  		return err
   533  	}
   534  
   535  	err = config.API.WaitUntilDeleted(mp)
   536  	if err != nil {
   537  		return err
   538  	}
   539  
   540  	return nil
   541  }
   542  
   543  func getThresholds(d interface{}) *oneandone.MonitoringThreshold {
   544  	raw_thresholds := d.(*schema.Set).List()
   545  
   546  	toReturn := &oneandone.MonitoringThreshold{}
   547  
   548  	for _, thresholds := range raw_thresholds {
   549  		th_set := thresholds.(map[string]interface{})
   550  
   551  		//CPU
   552  		cpu_raw := th_set["cpu"].(*schema.Set)
   553  		toReturn.Cpu = &oneandone.MonitoringLevel{}
   554  		for _, c := range cpu_raw.List() {
   555  			int_k := c.(map[string]interface{})
   556  			for _, w := range int_k["warning"].(*schema.Set).List() {
   557  				toReturn.Cpu.Warning = &oneandone.MonitoringValue{
   558  					Value: w.(map[string]interface{})["value"].(int),
   559  					Alert: w.(map[string]interface{})["alert"].(bool),
   560  				}
   561  			}
   562  
   563  			for _, c := range int_k["critical"].(*schema.Set).List() {
   564  				toReturn.Cpu.Critical = &oneandone.MonitoringValue{
   565  					Value: c.(map[string]interface{})["value"].(int),
   566  					Alert: c.(map[string]interface{})["alert"].(bool),
   567  				}
   568  			}
   569  		}
   570  		//RAM
   571  		ram_raw := th_set["ram"].(*schema.Set)
   572  		toReturn.Ram = &oneandone.MonitoringLevel{}
   573  		for _, c := range ram_raw.List() {
   574  			int_k := c.(map[string]interface{})
   575  			for _, w := range int_k["warning"].(*schema.Set).List() {
   576  				toReturn.Ram.Warning = &oneandone.MonitoringValue{
   577  					Value: w.(map[string]interface{})["value"].(int),
   578  					Alert: w.(map[string]interface{})["alert"].(bool),
   579  				}
   580  			}
   581  
   582  			for _, c := range int_k["critical"].(*schema.Set).List() {
   583  				toReturn.Ram.Critical = &oneandone.MonitoringValue{
   584  					Value: c.(map[string]interface{})["value"].(int),
   585  					Alert: c.(map[string]interface{})["alert"].(bool),
   586  				}
   587  			}
   588  		}
   589  
   590  		//DISK
   591  		disk_raw := th_set["disk"].(*schema.Set)
   592  		toReturn.Disk = &oneandone.MonitoringLevel{}
   593  		for _, c := range disk_raw.List() {
   594  			int_k := c.(map[string]interface{})
   595  			for _, w := range int_k["warning"].(*schema.Set).List() {
   596  				toReturn.Disk.Warning = &oneandone.MonitoringValue{
   597  					Value: w.(map[string]interface{})["value"].(int),
   598  					Alert: w.(map[string]interface{})["alert"].(bool),
   599  				}
   600  			}
   601  
   602  			for _, c := range int_k["critical"].(*schema.Set).List() {
   603  				toReturn.Disk.Critical = &oneandone.MonitoringValue{
   604  					Value: c.(map[string]interface{})["value"].(int),
   605  					Alert: c.(map[string]interface{})["alert"].(bool),
   606  				}
   607  			}
   608  		}
   609  
   610  		//TRANSFER
   611  		transfer_raw := th_set["transfer"].(*schema.Set)
   612  		toReturn.Transfer = &oneandone.MonitoringLevel{}
   613  		for _, c := range transfer_raw.List() {
   614  			int_k := c.(map[string]interface{})
   615  			for _, w := range int_k["warning"].(*schema.Set).List() {
   616  				toReturn.Transfer.Warning = &oneandone.MonitoringValue{
   617  					Value: w.(map[string]interface{})["value"].(int),
   618  					Alert: w.(map[string]interface{})["alert"].(bool),
   619  				}
   620  			}
   621  
   622  			for _, c := range int_k["critical"].(*schema.Set).List() {
   623  				toReturn.Transfer.Critical = &oneandone.MonitoringValue{
   624  					Value: c.(map[string]interface{})["value"].(int),
   625  					Alert: c.(map[string]interface{})["alert"].(bool),
   626  				}
   627  			}
   628  		}
   629  		//internal ping
   630  		ping_raw := th_set["internal_ping"].(*schema.Set)
   631  		toReturn.InternalPing = &oneandone.MonitoringLevel{}
   632  		for _, c := range ping_raw.List() {
   633  			int_k := c.(map[string]interface{})
   634  			for _, w := range int_k["warning"].(*schema.Set).List() {
   635  				toReturn.InternalPing.Warning = &oneandone.MonitoringValue{
   636  					Value: w.(map[string]interface{})["value"].(int),
   637  					Alert: w.(map[string]interface{})["alert"].(bool),
   638  				}
   639  			}
   640  
   641  			for _, c := range int_k["critical"].(*schema.Set).List() {
   642  				toReturn.InternalPing.Critical = &oneandone.MonitoringValue{
   643  					Value: c.(map[string]interface{})["value"].(int),
   644  					Alert: c.(map[string]interface{})["alert"].(bool),
   645  				}
   646  			}
   647  		}
   648  	}
   649  
   650  	return toReturn
   651  }
   652  
   653  func getProcesses(d interface{}) []oneandone.MonitoringProcess {
   654  	toReturn := []oneandone.MonitoringProcess{}
   655  
   656  	for _, raw := range d.([]interface{}) {
   657  		port := raw.(map[string]interface{})
   658  		m_port := oneandone.MonitoringProcess{
   659  			EmailNotification: port["email_notification"].(bool),
   660  		}
   661  
   662  		if port["id"] != nil {
   663  			m_port.Id = port["id"].(string)
   664  		}
   665  
   666  		if port["process"] != nil {
   667  			m_port.Process = port["process"].(string)
   668  		}
   669  
   670  		if port["alert_if"] != nil {
   671  			m_port.AlertIf = port["alert_if"].(string)
   672  		}
   673  
   674  		toReturn = append(toReturn, m_port)
   675  	}
   676  
   677  	return toReturn
   678  }
   679  
   680  func getPorts(d interface{}) []oneandone.MonitoringPort {
   681  	toReturn := []oneandone.MonitoringPort{}
   682  
   683  	for _, raw := range d.([]interface{}) {
   684  		port := raw.(map[string]interface{})
   685  		m_port := oneandone.MonitoringPort{
   686  			EmailNotification: port["email_notification"].(bool),
   687  			Port:              port["port"].(int),
   688  		}
   689  
   690  		if port["id"] != nil {
   691  			m_port.Id = port["id"].(string)
   692  		}
   693  
   694  		if port["protocol"] != nil {
   695  			m_port.Protocol = port["protocol"].(string)
   696  		}
   697  
   698  		if port["alert_if"] != nil {
   699  			m_port.AlertIf = port["alert_if"].(string)
   700  		}
   701  
   702  		toReturn = append(toReturn, m_port)
   703  	}
   704  
   705  	return toReturn
   706  }