diff --git a/README.md b/README.md index 9ddab1f7..9deed2eb 100644 --- a/README.md +++ b/README.md @@ -8,17 +8,52 @@ ## Requirements -- [Terraform](https://www.terraform.io/downloads.html) 0.14.x -- [Go](https://golang.org/doc/install) 1.16 (to build the provider plugin) +- [Terraform](https://www.terraform.io/downloads.html) 0.2.0 +- [Go](https://golang.org/doc/install) 1.20.3 (to build the provider plugin) + +## Steps to downgrade or upgrade go version + +To downgrade or upgrade Go to a specific version, you need to follow these steps: + +Uninstall the current version of Go from your system by removing the Go installation directory. +Download the specific Go version binary for your operating system and architecture from the official website. You can find the previous releases of Go at: +```sh + https://golang.org/dl/ + ``` +Extract the downloaded archive to a location on your system. +Set the GOROOT environment variable to point to the extracted Go directory (the path where you extracted the Go binary). +Update your PATH environment variable to include the bin directory inside the extracted Go directory. + ```sh +export GOROOT=/path/to/extracted/go +export PATH=$GOROOT/bin:$PATH +``` +## Steps to downgrade or upgrade terraform version + +To upgrade Terraform manually, follow these steps: + +Visit the official HashiCorp releases page for Terraform at +```sh + https://releases.hashicorp.com/terraform/ + ``` +Find the desired version and click on it to see available downloads. +Download the appropriate archive for your operating system (e.g., ZIP for windows, tar.gz for macOS/Linux). +Extract the downloaded archive to a directory included in your system's PATH environment variable. +Verify the installation by running terraform version in the terminal. + +To downgrade to a specific version manually, follow these steps: + +Uninstall the currently installed Terraform version. +Follow the manual installation steps above, ensuring that you download and extract the desired version. +Remember to update any configuration files or scripts that rely on specific Terraform versions when upgrading or downgrading. ## Building the Provider (Internal) Clone repository: ```sh -$ git clone git@github.com:logicmonitor/terraform-provider-logicmonitor.git +$ git clone ssh://git@stash.logicmonitor.com:7999/teamintegrations/terraform-integration.git ``` Enter the provider directory and build the provider: ```sh -$ cd terraform-provider-logicmonitor/ +$ cd terraform-integration/terraform-provider-logicmonitor/ $ make ``` The make file will then generate the code, build the binary, and copy it to the Terraform plugin directory. @@ -41,3 +76,31 @@ provider "logicmonitor" { company = var.logicmonitor_company } ``` +Example usage can be found in the /terraform-integration/examples directory. + +## Initialize the Terraform project + +Run the following command to initialize the project and download necessary provider plugins: +```sh +terraform init +``` +## Plan the execution + +```sh +terraform plan +``` +This will show you a preview of the changes that Terraform will make based on your configuration. Review the plan carefully before proceeding to apply it. + +## Apply the changes + +If you are satisfied with the execution plan and ready to apply the changes, run the following command: +```sh +terraform apply +``` +Terraform will prompt you to confirm the execution plan one more time. Type yes and press Enter to proceed. +The Terraform execution will begin and create/update the necessary resources according to your configuration. + +## Internal Documentation +```sh +https://confluence.logicmonitor.com/display/ENG/Development+Guide +``` diff --git a/examples/website/datasource.tf b/examples/website/datasource.tf index 72140740..5ade0058 100644 --- a/examples/website/datasource.tf +++ b/examples/website/datasource.tf @@ -1,5 +1,5 @@ resource "logicmonitor_website" "my_website"{ - type = "pingcheck" + type = "webcheck" host = "google.com" overall_alert_level = "warn" polling_interval = 5 @@ -7,13 +7,14 @@ resource "logicmonitor_website" "my_website"{ disable_alerting = true stop_monitoring = true user_permission = "string" + group_id = 8 individual_sm_alert_enable = false steps = [ { schema = "https" resp_type = "config" timeout = 0 - match_type = "plain" + match_type = "json" description = "string" use_default_root = true http_method = "GET" @@ -24,18 +25,35 @@ resource "logicmonitor_website" "my_website"{ name = "string" req_type = "config" fullpage_load = false + require_auth = true + http_headers = "X-Version:3" + auth = [{ + password = "string" + type = "ntlm" + user_name = "string" + domain = "string" + }] + path = "$.data.resultKey" + keyword = "DEVWRT-SANRT-JOB1-9127" + http_body = "string" + resp_script = "string" + req_script = "string" + label = "string" + url = "/santaba/rest/version" + type = "string" + invert_match = true + status_code = "200" } ] transition = 1 global_sm_alert_cond = 0 is_internal = false - domain = "www.ebay.com" - name = "Ebay pingcheck" + domain = "www.example.com" + name = "Ebay webcheck test" use_default_location_setting = false use_default_alert_setting = true individual_alert_level = "warn" } - data "logicmonitor_website" "my_website" { filter = "description~\"website test\"" depends_on = [ diff --git a/examples/website/resource.tf b/examples/website/resource.tf index 8fce15c6..2f6af344 100644 --- a/examples/website/resource.tf +++ b/examples/website/resource.tf @@ -1,5 +1,5 @@ resource "logicmonitor_website" "my_website"{ - type = "pingcheck" + type = "webcheck" host = "google.com" overall_alert_level = "warn" polling_interval = 5 @@ -7,13 +7,14 @@ resource "logicmonitor_website" "my_website"{ disable_alerting = true stop_monitoring = true user_permission = "string" + group_id = 8 individual_sm_alert_enable = false steps = [ { schema = "https" resp_type = "config" timeout = 0 - match_type = "plain" + match_type = "json" description = "string" use_default_root = true http_method = "GET" @@ -24,13 +25,31 @@ resource "logicmonitor_website" "my_website"{ name = "string" req_type = "config" fullpage_load = false + require_auth = true + http_headers = "X-Version:3" + auth = [{ + password = "string" + type = "ntlm" + user_name = "string" + domain = "string" + }] + path = "$.data.resultKey" + keyword = "DEVWRT-SANRT-JOB1-9127" + http_body = "string" + resp_script = "string" + req_script = "string" + label = "string" + url = "/santaba/rest/version" + type = "string" + invert_match = true + status_code = "200" } ] transition = 1 global_sm_alert_cond = 0 is_internal = false - domain = "www.ebay.com" - name = "Ebay pingcheck" + domain = "www.example.com" + name = "Ebay webcheck test" use_default_location_setting = false use_default_alert_setting = true individual_alert_level = "warn" diff --git a/logicmonitor/schemata/authentication_schema.go b/logicmonitor/schemata/authentication_schema.go new file mode 100644 index 00000000..3fa157c8 --- /dev/null +++ b/logicmonitor/schemata/authentication_schema.go @@ -0,0 +1,70 @@ +package schemata + +import ( + "terraform-provider-logicmonitor/models" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func AuthenticationSchema() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "domain": { + Type: schema.TypeString, + Optional: true, + }, + + "password": { + Type: schema.TypeString, + Sensitive: true, + Required: true, + }, + + "type": { + Type: schema.TypeString, + Required: true, + }, + + "user_name": { + Type: schema.TypeString, + Required: true, + }, + + } +} + +func SetAuthenticationSubResourceData(m []*models.Authentication) (d []*map[string]interface{}) { + for _, authentication := range m { + if authentication != nil { + properties := make(map[string]interface{}) + properties["domain"] = authentication.Domain + properties["password"] = authentication.Password + properties["type"] = authentication.Type + properties["user_name"] = authentication.UserName + d = append(d, &properties) + } + } + return +} + +func AuthenticationModel(d map[string]interface{}) *models.Authentication { + // assume that the incoming map only contains the relevant resource data + domain := d["domain"].(string) + password := d["password"].(string) + typeVar := d["type"].(string) + userName := d["user_name"].(string) + + return &models.Authentication { + Domain: domain, + Password: &password, + Type: &typeVar, + UserName: &userName, + } +} + +func GetAuthenticationPropertyFields() (t []string) { + return []string{ + "domain", + "password", + "type", + "user_name", + } +} \ No newline at end of file diff --git a/logicmonitor/schemata/web_check_step_schema.go b/logicmonitor/schemata/web_check_step_schema.go index 86baffa1..72928bd6 100644 --- a/logicmonitor/schemata/web_check_step_schema.go +++ b/logicmonitor/schemata/web_check_step_schema.go @@ -7,6 +7,16 @@ import ( func WebCheckStepSchema() map[string]*schema.Schema { return map[string]*schema.Schema{ + "http_body": { + Type: schema.TypeString, + Optional: true, + }, + + "http_headers": { + Type: schema.TypeString, + Optional: true, + }, + "http_method": { Type: schema.TypeString, Optional: true, @@ -17,6 +27,15 @@ func WebCheckStepSchema() map[string]*schema.Schema { Optional: true, }, + "auth": { + Type: schema.TypeList, //GoType: Authentication + Elem: &schema.Resource{ + Schema: AuthenticationSchema(), + }, + ConfigMode: schema.SchemaConfigModeAttr, + Optional: true, + }, + "description": { Type: schema.TypeString, Optional: true, @@ -37,6 +56,21 @@ func WebCheckStepSchema() map[string]*schema.Schema { Optional: true, }, + "invert_match": { + Type: schema.TypeBool, + Optional: true, + }, + + "keyword": { + Type: schema.TypeString, + Optional: true, + }, + + "label": { + Type: schema.TypeString, + Optional: true, + }, + "match_type": { Type: schema.TypeString, Optional: true, @@ -47,16 +81,36 @@ func WebCheckStepSchema() map[string]*schema.Schema { Optional: true, }, + "path": { + Type: schema.TypeString, + Optional: true, + }, + "post_data_edit_type": { Type: schema.TypeString, Optional: true, }, + "req_script": { + Type: schema.TypeString, + Optional: true, + }, + "req_type": { Type: schema.TypeString, Optional: true, }, + "require_auth": { + Type: schema.TypeBool, + Optional: true, + }, + + "resp_script": { + Type: schema.TypeString, + Optional: true, + }, + "resp_type": { Type: schema.TypeString, Optional: true, @@ -67,11 +121,26 @@ func WebCheckStepSchema() map[string]*schema.Schema { Optional: true, }, + "status_code": { + Type: schema.TypeString, + Optional: true, + }, + "timeout": { Type: schema.TypeInt, Optional: true, }, + "type": { + Type: schema.TypeString, + Optional: true, + }, + + "url": { + Type: schema.TypeString, + Optional: true, + }, + "use_default_root": { Type: schema.TypeBool, Optional: true, @@ -84,19 +153,32 @@ func SetWebCheckStepSubResourceData(m []*models.WebCheckStep) (d []*map[string]i for _, webCheckStep := range m { if webCheckStep != nil { properties := make(map[string]interface{}) + properties["http_body"] = webCheckStep.HTTPBody + properties["http_headers"] = webCheckStep.HTTPHeaders properties["http_method"] = webCheckStep.HTTPMethod properties["http_version"] = webCheckStep.HTTPVersion + properties["auth"] = SetAuthenticationSubResourceData([]*models.Authentication{webCheckStep.Auth}) properties["description"] = webCheckStep.Description properties["enable"] = webCheckStep.Enable properties["follow_redirection"] = webCheckStep.FollowRedirection properties["fullpage_load"] = webCheckStep.FullpageLoad + properties["invert_match"] = webCheckStep.InvertMatch + properties["keyword"] = webCheckStep.Keyword + properties["label"] = webCheckStep.Label properties["match_type"] = webCheckStep.MatchType properties["name"] = webCheckStep.Name + properties["path"] = webCheckStep.Path properties["post_data_edit_type"] = webCheckStep.PostDataEditType + properties["req_script"] = webCheckStep.ReqScript properties["req_type"] = webCheckStep.ReqType + properties["require_auth"] = webCheckStep.RequireAuth + properties["resp_script"] = webCheckStep.RespScript properties["resp_type"] = webCheckStep.RespType properties["schema"] = webCheckStep.Schema + properties["status_code"] = webCheckStep.StatusCode properties["timeout"] = webCheckStep.Timeout + properties["type"] = webCheckStep.Type + properties["url"] = webCheckStep.URL properties["use_default_root"] = webCheckStep.UseDefaultRoot d = append(d, &properties) } @@ -106,54 +188,97 @@ func SetWebCheckStepSubResourceData(m []*models.WebCheckStep) (d []*map[string]i func WebCheckStepModel(d map[string]interface{}) *models.WebCheckStep { // assume that the incoming map only contains the relevant resource data + hTTPBody := d["http_body"].(string) + hTTPHeaders := d["http_headers"].(string) hTTPMethod := d["http_method"].(string) hTTPVersion := d["http_version"].(string) + var auth *models.Authentication = nil + authList := d["auth"].([]interface{}) + if len(authList) > 0 { // len(nil) = 0 + auth = AuthenticationModel(authList[0].(map[string]interface{})) + } description := d["description"].(string) enable := d["enable"].(bool) followRedirection := d["follow_redirection"].(bool) fullpageLoad := d["fullpage_load"].(bool) + invertMatch := d["invert_match"].(bool) + keyword := d["keyword"].(string) + label := d["label"].(string) matchType := d["match_type"].(string) name := d["name"].(string) + path := d["path"].(string) postDataEditType := d["post_data_edit_type"].(string) + reqScript := d["req_script"].(string) reqType := d["req_type"].(string) + requireAuth := d["require_auth"].(bool) + respScript := d["resp_script"].(string) respType := d["resp_type"].(string) schema := d["schema"].(string) + statusCode := d["status_code"].(string) timeout := int32(d["timeout"].(int)) + typeVar := d["type"].(string) + url := d["url"].(string) useDefaultRoot := d["use_default_root"].(bool) return &models.WebCheckStep { + HTTPBody: hTTPBody, + HTTPHeaders: hTTPHeaders, HTTPMethod: hTTPMethod, HTTPVersion: hTTPVersion, + Auth: auth, Description: description, Enable: enable, FollowRedirection: followRedirection, FullpageLoad: fullpageLoad, + InvertMatch: invertMatch, + Keyword: keyword, + Label: label, MatchType: matchType, Name: name, + Path: path, PostDataEditType: postDataEditType, + ReqScript: reqScript, ReqType: reqType, + RequireAuth: requireAuth, + RespScript: respScript, RespType: respType, Schema: schema, + StatusCode: statusCode, Timeout: timeout, + Type: typeVar, + URL: url, UseDefaultRoot: useDefaultRoot, } } func GetWebCheckStepPropertyFields() (t []string) { return []string{ + "http_body", + "http_headers", "http_method", "http_version", + "auth", "description", "enable", "follow_redirection", "fullpage_load", + "invert_match", + "keyword", + "label", "match_type", "name", + "path", "post_data_edit_type", + "req_script", "req_type", + "require_auth", + "resp_script", "resp_type", "schema", + "status_code", "timeout", + "type", + "url", "use_default_root", } } \ No newline at end of file diff --git a/logicmonitor/schemata/website_schema.go b/logicmonitor/schemata/website_schema.go index 34589f9f..81c3f218 100644 --- a/logicmonitor/schemata/website_schema.go +++ b/logicmonitor/schemata/website_schema.go @@ -31,7 +31,7 @@ func WebsiteSchema() map[string]*schema.Schema { "group_id": { Type: schema.TypeInt, - Computed: true, + Optional: true, }, "host": { @@ -345,6 +345,7 @@ func WebsiteModel(d *schema.ResourceData) *models.Website { disableAlerting := d.Get("disable_alerting").(bool) domain := d.Get("domain").(string) globalSmAlertCond := int32(d.Get("global_sm_alert_cond").(int)) + groupID := int32(d.Get("group_id").(int)) host := d.Get("host").(string) id, _ := strconv.Atoi(d.Get("id").(string)) individualAlertLevel := d.Get("individual_alert_level").(string) @@ -367,6 +368,7 @@ func WebsiteModel(d *schema.ResourceData) *models.Website { DisableAlerting: disableAlerting, Domain: domain, GlobalSmAlertCond: globalSmAlertCond, + GroupID: groupID, Host: host, ID: int32(id), IndividualAlertLevel: individualAlertLevel, @@ -391,6 +393,7 @@ func GetWebsitePropertyFields() (t []string) { "disable_alerting", "domain", "global_sm_alert_cond", + "group_id", "host", "id", "individual_alert_level", diff --git a/logicmonitor/utils/helper_functions.go b/logicmonitor/utils/helper_functions.go index 041f0a5c..f5974fda 100644 --- a/logicmonitor/utils/helper_functions.go +++ b/logicmonitor/utils/helper_functions.go @@ -347,8 +347,20 @@ func getPropFromStepsInterface(r interface{}) (t []*models.WebCheckStep) { var useDefaultRoot = m["use_default_root"].(bool) var postDataEditType = m["post_data_edit_type"].(string) var fullpageLoad = m["fullpage_load"].(bool) - - + var requireAuth = m["require_auth"].(bool) + var path = m["path"].(string) + var auth = GetAuth(m["auth"].([]interface{})) + var httpHeaders = m["http_headers"].(string) + var httpBody = m["http_body"].(string) + var keyword = m["keyword"].(string) + var respScript = m["resp_script"].(string) + var label = m["label"].(string) + var URL = m["url"].(string) + var invertMatch = m["invert_match"].(bool) + var reqScript = m["req_script"].(string) + var typee = m["type"].(string) + var statusCode = m["status_code"].(string) + model := &models.WebCheckStep{ Schema: schema, MatchType: matchType, @@ -364,9 +376,42 @@ func getPropFromStepsInterface(r interface{}) (t []*models.WebCheckStep) { UseDefaultRoot: useDefaultRoot, PostDataEditType: postDataEditType, FullpageLoad: fullpageLoad, - } + RequireAuth: requireAuth, + Path: path, + Auth: &auth, + HTTPHeaders: httpHeaders, + HTTPBody: httpBody, + Keyword: keyword, + RespScript: respScript, + Label: label, + URL: URL, + InvertMatch: invertMatch, + ReqScript: reqScript, + Type: typee, + StatusCode: statusCode, + } t = append(t, model) } } return } +func GetAuth(d []interface{}) (t models.Authentication) { + for _, i := range d { + if m, ok := i.(map[string]interface{}); ok { + var userName = m["user_name"].(string) + var password = m["password"].(string) + var typee = m["type"].(string) + var domain = m["domain"].(string) + + + model := models.Authentication{ + Password: &password, + UserName: &userName, + Type: &typee, + Domain: domain, + } + t = model + } + } + return +} diff --git a/models/authentication.go b/models/authentication.go index 7d7cd7cb..0bfdf967 100644 --- a/models/authentication.go +++ b/models/authentication.go @@ -6,146 +6,48 @@ package models // Editing this file might prove futile when you re-run the swagger generate command import ( - "bytes" "context" - "encoding/json" - "io" - "io/ioutil" "github.com/go-openapi/errors" - "github.com/go-openapi/runtime" "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" "github.com/go-openapi/validate" ) // Authentication authentication // -// swagger:discriminator Authentication type -type Authentication interface { - runtime.Validatable - runtime.ContextValidatable +// swagger:model Authentication +type Authentication struct { + + // NTLM Authentication domain + Domain string `json:"domain,omitempty"` // NTLM authentication password // Required: true - Password() *string - SetPassword(*string) + Password *string `json:"password"` // Authentication type // Example: basic // Required: true - Type() string - SetType(string) + Type *string `json:"type"` // NTLM authentication userName // Required: true - UserName() *string - SetUserName(*string) - - // AdditionalProperties in base type shoud be handled just like regular properties - // At this moment, the base type property is pushed down to the subtype -} - -type authentication struct { - passwordField *string - - typeField string - - userNameField *string -} - -// Password gets the password of this polymorphic type -func (m *authentication) Password() *string { - return m.passwordField -} - -// SetPassword sets the password of this polymorphic type -func (m *authentication) SetPassword(val *string) { - m.passwordField = val -} - -// Type gets the type of this polymorphic type -func (m *authentication) Type() string { - return "Authentication" -} - -// SetType sets the type of this polymorphic type -func (m *authentication) SetType(val string) { -} - -// UserName gets the user name of this polymorphic type -func (m *authentication) UserName() *string { - return m.userNameField -} - -// SetUserName sets the user name of this polymorphic type -func (m *authentication) SetUserName(val *string) { - m.userNameField = val -} - -// UnmarshalAuthenticationSlice unmarshals polymorphic slices of Authentication -func UnmarshalAuthenticationSlice(reader io.Reader, consumer runtime.Consumer) ([]Authentication, error) { - var elements []json.RawMessage - if err := consumer.Consume(reader, &elements); err != nil { - return nil, err - } - - var result []Authentication - for _, element := range elements { - obj, err := unmarshalAuthentication(element, consumer) - if err != nil { - return nil, err - } - result = append(result, obj) - } - return result, nil -} - -// UnmarshalAuthentication unmarshals polymorphic Authentication -func UnmarshalAuthentication(reader io.Reader, consumer runtime.Consumer) (Authentication, error) { - // we need to read this twice, so first into a buffer - data, err := ioutil.ReadAll(reader) - if err != nil { - return nil, err - } - return unmarshalAuthentication(data, consumer) -} - -func unmarshalAuthentication(data []byte, consumer runtime.Consumer) (Authentication, error) { - buf := bytes.NewBuffer(data) - buf2 := bytes.NewBuffer(data) - - // the first time this is read is to fetch the value of the type property. - var getType struct { - Type string `json:"type"` - } - if err := consumer.Consume(buf, &getType); err != nil { - return nil, err - } - - if err := validate.RequiredString("type", "body", getType.Type); err != nil { - return nil, err - } - - // The value of type is used to determine which type to create and unmarshal the data into - switch getType.Type { - case "Authentication": - var result authentication - if err := consumer.Consume(buf2, &result); err != nil { - return nil, err - } - return &result, nil - } - return nil, errors.New(422, "invalid type value: %q", getType.Type) + UserName *string `json:"userName"` } // Validate validates this authentication -func (m *authentication) Validate(formats strfmt.Registry) error { +func (m *Authentication) Validate(formats strfmt.Registry) error { var res []error if err := m.validatePassword(formats); err != nil { res = append(res, err) } + if err := m.validateType(formats); err != nil { + res = append(res, err) + } + if err := m.validateUserName(formats); err != nil { res = append(res, err) } @@ -156,18 +58,27 @@ func (m *authentication) Validate(formats strfmt.Registry) error { return nil } -func (m *authentication) validatePassword(formats strfmt.Registry) error { +func (m *Authentication) validatePassword(formats strfmt.Registry) error { + + if err := validate.Required("password", "body", m.Password); err != nil { + return err + } + + return nil +} + +func (m *Authentication) validateType(formats strfmt.Registry) error { - if err := validate.Required("password", "body", m.Password()); err != nil { + if err := validate.Required("type", "body", m.Type); err != nil { return err } return nil } -func (m *authentication) validateUserName(formats strfmt.Registry) error { +func (m *Authentication) validateUserName(formats strfmt.Registry) error { - if err := validate.Required("userName", "body", m.UserName()); err != nil { + if err := validate.Required("userName", "body", m.UserName); err != nil { return err } @@ -175,6 +86,24 @@ func (m *authentication) validateUserName(formats strfmt.Registry) error { } // ContextValidate validates this authentication based on context it is used -func (m *authentication) ContextValidate(ctx context.Context, formats strfmt.Registry) error { +func (m *Authentication) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *Authentication) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *Authentication) UnmarshalBinary(b []byte) error { + var res Authentication + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res return nil } diff --git a/models/web_check_step.go b/models/web_check_step.go index 38ba2fdb..ada0899e 100644 --- a/models/web_check_step.go +++ b/models/web_check_step.go @@ -8,6 +8,7 @@ package models import ( "context" + "github.com/go-openapi/errors" "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" ) @@ -17,6 +18,12 @@ import ( // swagger:model WebCheckStep type WebCheckStep struct { + // HTTP Body + HTTPBody string `json:"HTTPBody,omitempty"` + + // HTTP header + HTTPHeaders string `json:"HTTPHeaders,omitempty"` + // GET | HEAD | POST // Specifies the type of HTTP method // Example: GET @@ -27,6 +34,9 @@ type WebCheckStep struct { // Example: 1.1 HTTPVersion string `json:"HTTPVersion,omitempty"` + // Authorization Information + Auth *Authentication `json:"auth,omitempty"` + // The description of the Step Description string `json:"description,omitempty"` @@ -44,6 +54,17 @@ type WebCheckStep struct { // Example: false FullpageLoad bool `json:"fullpageLoad,omitempty"` + // true | false + // Checks if invert matches or not + // Example: false + InvertMatch bool `json:"invertMatch,omitempty"` + + // Keyword that matches the body + Keyword string `json:"keyword,omitempty"` + + // The Label of the Step + Label string `json:"label,omitempty"` + // Body match type // Example: plain MatchType string `json:"matchType,omitempty"` @@ -51,15 +72,29 @@ type WebCheckStep struct { // The name of the Step Name string `json:"name,omitempty"` + // Path for JSON, XPATH + Path string `json:"path,omitempty"` + // Raw | Formatted Data // Specifies POST data type // Example: raw PostDataEditType string `json:"postDataEditType,omitempty"` + // The Request Script + ReqScript string `json:"reqScript,omitempty"` + // script | config // Step Request Type ReqType string `json:"reqType,omitempty"` + // true | false + // Checks if authorization required or not + // Example: false + RequireAuth bool `json:"requireAuth,omitempty"` + + // The Step Response Script + RespScript string `json:"respScript,omitempty"` + // Plain Text/String | Glob expression | JSON | XML | Multi line key value pair // Step Response Type RespType string `json:"respType,omitempty"` @@ -67,9 +102,21 @@ type WebCheckStep struct { // HTTP schema Schema string `json:"schema,omitempty"` + // The expected status code + StatusCode string `json:"statusCode,omitempty"` + // Request timeout measured in seconds Timeout int32 `json:"timeout,omitempty"` + // script | config + // The type of service step + // Example: config + Type string `json:"type,omitempty"` + + // The URL of service step + // Example: / + URL string `json:"url,omitempty"` + // true | falseCheck if using the default root // Example: true UseDefaultRoot bool `json:"useDefaultRoot,omitempty"` @@ -77,11 +124,64 @@ type WebCheckStep struct { // Validate validates this web check step func (m *WebCheckStep) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateAuth(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *WebCheckStep) validateAuth(formats strfmt.Registry) error { + if swag.IsZero(m.Auth) { // not required + return nil + } + + if m.Auth != nil { + if err := m.Auth.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("auth") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("auth") + } + return err + } + } + return nil } -// ContextValidate validates this web check step based on context it is used +// ContextValidate validate this web check step based on the context it is used func (m *WebCheckStep) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateAuth(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *WebCheckStep) contextValidateAuth(ctx context.Context, formats strfmt.Registry) error { + + if m.Auth != nil { + if err := m.Auth.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("auth") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("auth") + } + return err + } + } + return nil } diff --git a/models/website.go b/models/website.go index 15a4aca0..c455a11f 100644 --- a/models/website.go +++ b/models/website.go @@ -44,7 +44,6 @@ type Website struct { // The id of the group the website is in // Example: 1 - // Read Only: true GroupID int32 `json:"groupId,omitempty"` // The URL to check, without the scheme or protocol (e.g http or https) @@ -202,10 +201,6 @@ func (m *Website) validateType(formats strfmt.Registry) error { func (m *Website) ContextValidate(ctx context.Context, formats strfmt.Registry) error { var res []error - if err := m.contextValidateGroupID(ctx, formats); err != nil { - res = append(res, err) - } - if err := m.contextValidateID(ctx, formats); err != nil { res = append(res, err) } @@ -232,15 +227,6 @@ func (m *Website) ContextValidate(ctx context.Context, formats strfmt.Registry) return nil } -func (m *Website) contextValidateGroupID(ctx context.Context, formats strfmt.Registry) error { - - if err := validate.ReadOnly(ctx, "groupId", "body", int32(m.GroupID)); err != nil { - return err - } - - return nil -} - func (m *Website) contextValidateID(ctx context.Context, formats strfmt.Registry) error { if err := validate.ReadOnly(ctx, "id", "body", int32(m.ID)); err != nil { diff --git a/website/docs/d/alert_rule_html.markdown b/website/docs/d/alert_rule.markdown similarity index 87% rename from website/docs/d/alert_rule_html.markdown rename to website/docs/d/alert_rule.markdown index 8b2a6eb4..b2c37cdc 100644 --- a/website/docs/d/alert_rule_html.markdown +++ b/website/docs/d/alert_rule.markdown @@ -25,7 +25,7 @@ data "logicmonitor_AlertRule" "my_AlertRule" { ## Argument Reference The following arguments are supported: +* `filter` - (Optional) Filters the response according to the operator and value specified.More Info: https://www.logicmonitor.com/support/rest-api-developers-guide/v1/alert-rules/about-the-alert-rules-resource. Please refer the filter arguments from resources tab. -* `filter` - (Optional) Filters the response according to the operator and value specified.More Info: https://www.logicmonitor.com/support/rest-api-developers-guide/v1/device-groups/. Please refer the filter arguments from resources tab. * `depends_on` - (Optional) meta-argument within data blocks defers reading of the data source until after all changes to the dependencies have been applied. diff --git a/website/docs/d/collector_html.markdown b/website/docs/d/collector.markdown similarity index 87% rename from website/docs/d/collector_html.markdown rename to website/docs/d/collector.markdown index 323e01c9..19a550d1 100644 --- a/website/docs/d/collector_html.markdown +++ b/website/docs/d/collector.markdown @@ -25,7 +25,7 @@ data "logicmonitor_Collector" "my_Collector" { ## Argument Reference The following arguments are supported: +* `filter` - (Optional) Filters the response according to the operator and value specified.More Info: https://www.logicmonitor.com/support/rest-api-developers-guide/v1/collectors/about-the-collectors-resource. Please refer the filter arguments from resources tab. -* `filter` - (Optional) Filters the response according to the operator and value specified.More Info: https://www.logicmonitor.com/support/rest-api-developers-guide/v1/device-groups/. Please refer the filter arguments from resources tab. * `depends_on` - (Optional) meta-argument within data blocks defers reading of the data source until after all changes to the dependencies have been applied. diff --git a/website/docs/d/collector_group_html.markdown b/website/docs/d/collector_group.markdown similarity index 87% rename from website/docs/d/collector_group_html.markdown rename to website/docs/d/collector_group.markdown index eb81e549..10b3a09c 100644 --- a/website/docs/d/collector_group_html.markdown +++ b/website/docs/d/collector_group.markdown @@ -25,7 +25,7 @@ data "logicmonitor_CollectorGroup" "my_CollectorGroup" { ## Argument Reference The following arguments are supported: +* `filter` - (Optional) Filters the response according to the operator and value specified.More Info: https://www.logicmonitor.com/support/rest-api-developers-guide/v1/collector-groups/about-the-collector-group-resource. Please refer the filter arguments from resources tab. -* `filter` - (Optional) Filters the response according to the operator and value specified.More Info: https://www.logicmonitor.com/support/rest-api-developers-guide/v1/device-groups/. Please refer the filter arguments from resources tab. * `depends_on` - (Optional) meta-argument within data blocks defers reading of the data source until after all changes to the dependencies have been applied. diff --git a/website/docs/d/dashboard_html.markdown b/website/docs/d/dashboard.markdown similarity index 87% rename from website/docs/d/dashboard_html.markdown rename to website/docs/d/dashboard.markdown index 2e796f52..144dfdb7 100644 --- a/website/docs/d/dashboard_html.markdown +++ b/website/docs/d/dashboard.markdown @@ -25,7 +25,7 @@ data "logicmonitor_Dashboard" "my_Dashboard" { ## Argument Reference The following arguments are supported: +* `filter` - (Optional) Filters the response according to the operator and value specified.More Info: https://www.logicmonitor.com/support/rest-api-developers-guide/v1/dashboards/about-the-dashboards-resource. Please refer the filter arguments from resources tab. -* `filter` - (Optional) Filters the response according to the operator and value specified.More Info: https://www.logicmonitor.com/support/rest-api-developers-guide/v1/device-groups/. Please refer the filter arguments from resources tab. * `depends_on` - (Optional) meta-argument within data blocks defers reading of the data source until after all changes to the dependencies have been applied. diff --git a/website/docs/d/dashboard_group_html.markdown b/website/docs/d/dashboard_group.markdown similarity index 87% rename from website/docs/d/dashboard_group_html.markdown rename to website/docs/d/dashboard_group.markdown index bb9689dc..06d55bee 100644 --- a/website/docs/d/dashboard_group_html.markdown +++ b/website/docs/d/dashboard_group.markdown @@ -25,7 +25,7 @@ data "logicmonitor_DashboardGroup" "my_DashboardGroup" { ## Argument Reference The following arguments are supported: +* `filter` - (Optional) Filters the response according to the operator and value specified.More Info: https://www.logicmonitor.com/support/rest-api-developers-guide/v1/dashboard-groups/about-the-dashboard-groups-resource. Please refer the filter arguments from resources tab. -* `filter` - (Optional) Filters the response according to the operator and value specified.More Info: https://www.logicmonitor.com/support/rest-api-developers-guide/v1/device-groups/. Please refer the filter arguments from resources tab. * `depends_on` - (Optional) meta-argument within data blocks defers reading of the data source until after all changes to the dependencies have been applied. diff --git a/website/docs/d/device_html.markdown b/website/docs/d/device.markdown similarity index 87% rename from website/docs/d/device_html.markdown rename to website/docs/d/device.markdown index a020336c..fb2956a9 100644 --- a/website/docs/d/device_html.markdown +++ b/website/docs/d/device.markdown @@ -25,7 +25,7 @@ data "logicmonitor_Device" "my_Device" { ## Argument Reference The following arguments are supported: +* `filter` - (Optional) Filters the response according to the operator and value specified.More Info: https://www.logicmonitor.com/support/rest-api-developers-guide/v1/devices/about-the-device-resource. Please refer the filter arguments from resources tab. -* `filter` - (Optional) Filters the response according to the operator and value specified.More Info: https://www.logicmonitor.com/support/rest-api-developers-guide/v1/device-groups/. Please refer the filter arguments from resources tab. * `depends_on` - (Optional) meta-argument within data blocks defers reading of the data source until after all changes to the dependencies have been applied. diff --git a/website/docs/d/device_group_html.markdown b/website/docs/d/device_group.markdown similarity index 87% rename from website/docs/d/device_group_html.markdown rename to website/docs/d/device_group.markdown index a0ce3ca7..02f5cad8 100644 --- a/website/docs/d/device_group_html.markdown +++ b/website/docs/d/device_group.markdown @@ -25,7 +25,7 @@ data "logicmonitor_DeviceGroup" "my_DeviceGroup" { ## Argument Reference The following arguments are supported: +* `filter` - (Optional) Filters the response according to the operator and value specified.More Info: https://www.logicmonitor.com/support/rest-api-developers-guide/v1/device-groups/about-the-device-group-resource. Please refer the filter arguments from resources tab. -* `filter` - (Optional) Filters the response according to the operator and value specified.More Info: https://www.logicmonitor.com/support/rest-api-developers-guide/v1/device-groups/. Please refer the filter arguments from resources tab. * `depends_on` - (Optional) meta-argument within data blocks defers reading of the data source until after all changes to the dependencies have been applied. diff --git a/website/docs/d/escalation_chain_html.markdown b/website/docs/d/escalation_chain.markdown similarity index 88% rename from website/docs/d/escalation_chain_html.markdown rename to website/docs/d/escalation_chain.markdown index 4e079089..305d928f 100644 --- a/website/docs/d/escalation_chain_html.markdown +++ b/website/docs/d/escalation_chain.markdown @@ -25,7 +25,7 @@ data "logicmonitor_EscalationChain" "my_EscalationChain" { ## Argument Reference The following arguments are supported: +* `filter` - (Optional) Filters the response according to the operator and value specified.More Info: https://www.logicmonitor.com/support/rest-api-developers-guide/v1/escalation-chains/escalation-chains-resource. Please refer the filter arguments from resources tab. -* `filter` - (Optional) Filters the response according to the operator and value specified.More Info: https://www.logicmonitor.com/support/rest-api-developers-guide/v1/device-groups/. Please refer the filter arguments from resources tab. * `depends_on` - (Optional) meta-argument within data blocks defers reading of the data source until after all changes to the dependencies have been applied. diff --git a/website/docs/d/website_html.markdown b/website/docs/d/website.markdown similarity index 87% rename from website/docs/d/website_html.markdown rename to website/docs/d/website.markdown index cdc9ab52..6ae6feb9 100644 --- a/website/docs/d/website_html.markdown +++ b/website/docs/d/website.markdown @@ -25,7 +25,7 @@ data "logicmonitor_Website" "my_Website" { ## Argument Reference The following arguments are supported: +* `filter` - (Optional) Filters the response according to the operator and value specified.More Info: https://www.logicmonitor.com/support/rest-api-developers-guide/v1/services/about-the-service-api-resource. Please refer the filter arguments from resources tab. -* `filter` - (Optional) Filters the response according to the operator and value specified.More Info: https://www.logicmonitor.com/support/rest-api-developers-guide/v1/device-groups/. Please refer the filter arguments from resources tab. * `depends_on` - (Optional) meta-argument within data blocks defers reading of the data source until after all changes to the dependencies have been applied. diff --git a/website/docs/d/website_group_html.markdown b/website/docs/d/website_group.markdown similarity index 87% rename from website/docs/d/website_group_html.markdown rename to website/docs/d/website_group.markdown index b48c7a52..bc913d35 100644 --- a/website/docs/d/website_group_html.markdown +++ b/website/docs/d/website_group.markdown @@ -25,7 +25,7 @@ data "logicmonitor_WebsiteGroup" "my_WebsiteGroup" { ## Argument Reference The following arguments are supported: +* `filter` - (Optional) Filters the response according to the operator and value specified.More Info: https://www.logicmonitor.com/support/rest-api-developers-guide/v1/service-groups/about-the-service-group-resource. Please refer the filter arguments from resources tab. -* `filter` - (Optional) Filters the response according to the operator and value specified.More Info: https://www.logicmonitor.com/support/rest-api-developers-guide/v1/device-groups/. Please refer the filter arguments from resources tab. * `depends_on` - (Optional) meta-argument within data blocks defers reading of the data source until after all changes to the dependencies have been applied. diff --git a/website/index_html.markdown b/website/docs/index.markdown similarity index 91% rename from website/index_html.markdown rename to website/docs/index.markdown index 16e1bc93..c249c1df 100644 --- a/website/index_html.markdown +++ b/website/docs/index.markdown @@ -182,6 +182,7 @@ resource "logicmonitor_website" "my_website" { disable_alerting = true stop_monitoring = true user_permission = "string" + group_id = 8 individual_sm_alert_enable = false steps = [ { @@ -194,11 +195,29 @@ resource "logicmonitor_website" "my_website" { http_method = "GET" enable = true http_version = "1.1" + http_headers = "X-Version:3" follow_redirection = true post_data_edit_type = "raw" name = "string" req_type = "config" fullpage_load = false + require_auth = false + auth = [{ + password = "string" + type = "basic" + user_name = "string" + domain = "string" + }] + path = "string" + keyword = "DEVWRT-SANRT-JOB1-9127" + http_body = "string" + resp_script = "string" + req_script = "string" + label = "string" + url = "/rest/version" + type = "string" + invert_match = false + status_code = "200" } ] transition = 1 diff --git a/website/docs/r/alert_rule_html.markdown b/website/docs/r/alert_rule.markdown similarity index 100% rename from website/docs/r/alert_rule_html.markdown rename to website/docs/r/alert_rule.markdown diff --git a/website/docs/r/collector_html.markdown b/website/docs/r/collector.markdown similarity index 100% rename from website/docs/r/collector_html.markdown rename to website/docs/r/collector.markdown diff --git a/website/docs/r/collector_group_html.markdown b/website/docs/r/collector_group.markdown similarity index 100% rename from website/docs/r/collector_group_html.markdown rename to website/docs/r/collector_group.markdown diff --git a/website/docs/r/dashboard_html.markdown b/website/docs/r/dashboard.markdown similarity index 97% rename from website/docs/r/dashboard_html.markdown rename to website/docs/r/dashboard.markdown index 65fdb738..51217640 100644 --- a/website/docs/r/dashboard_html.markdown +++ b/website/docs/r/dashboard.markdown @@ -42,7 +42,7 @@ The following arguments are **optional**: + `value` (required) + `type` (required) - Need to pass 'null' value + `inherit_list` (required) - Need to pass 'null' value -* `widgets_config` - Information about widget configuration used by the UI +* `widgets_config` - Information about widget configuration used by the UI, this field can remain empty for terraform. ## Import diff --git a/website/docs/r/dashboard_group_html.markdown b/website/docs/r/dashboard_group.markdown similarity index 100% rename from website/docs/r/dashboard_group_html.markdown rename to website/docs/r/dashboard_group.markdown diff --git a/website/docs/r/device_html.markdown b/website/docs/r/device.markdown similarity index 94% rename from website/docs/r/device_html.markdown rename to website/docs/r/device.markdown index 0961192a..72cf8840 100644 --- a/website/docs/r/device_html.markdown +++ b/website/docs/r/device.markdown @@ -60,6 +60,7 @@ The following arguments are **optional**: * `host_group_ids` - The Id(s) of the groups the device is in, where multiple group ids are comma separated * `link` - The URL link associated with the device * `netflow_collector_id` - The Id of the netflow collector associated with the device +* `preferred_collector_group_id` - The id of the Collector Group associated with the device's preferred collector, It can be 0 for auto balanced collector group . * `related_device_id` - The Id of the AWS EC2 instance related to this device, if one exists in the LogicMonitor account. This value defaults to -1, which indicates that there are no related devices ## Import diff --git a/website/docs/r/device_group.markdown b/website/docs/r/device_group.markdown new file mode 100644 index 00000000..1b92cbb8 --- /dev/null +++ b/website/docs/r/device_group.markdown @@ -0,0 +1,211 @@ +--- +layout: "logicmonitor" +page_title: "LogicMonitor: logicmonitor_device_group" +sidebar_current: "docs-logicmonitor-resource-device-group" +description: |- + Provides a LogicMonitor device group resource. This can be used to create and manage LogicMonitor device groups. +--- + +# logicmonitor_device_group + +Provides a LogicMonitor device group resource. This can be used to create and manage LogicMonitor device groups. + +## Example Usage +```hcl +# Create a LogicMonitor device group +resource "logicmonitor_device_group" "my_device_group" { + applies_to = "isLinux()" + custom_properties = [ + { + name = "addr" + value = "127.0.0.1" + }, + { + name = "host" + value = "localhost" + } + ] + default_collector_id = 1 + description = "Linux Servers" + disable_alerting = true + enable_netflow = true + group_type = "Normal" + name = "Linux Servers" + parent_id = 1 +} +``` +## Example Usage - AWS Cloud Account +```hcl +provider "aws" { + // add your AWS credentials + access_key = "" + secret_key = "" + region = "" +} + +// used for verifying LM access to your AWS account +data "logicmonitor_data_resource_aws_external_id" "my_external_id" { +} + +data "aws_iam_policy_document" "assume_role" { + statement { + actions = [ + "sts:AssumeRole" + ] + condition { + test = "StringEquals" + values = [ + data.logicmonitor_data_resource_aws_external_id.my_external_id.external_id + ] + variable = "sts:ExternalId" + } + effect = "Allow" + principals { + identifiers = [ + "282028653949" + ] + type = "AWS" + } + } +} + +resource "aws_iam_role" "lm" { + assume_role_policy = data.aws_iam_policy_document.assume_role.json + name = "TF-Integration-Role" +} + +resource "aws_iam_role_policy_attachment" "read_only_access" { + policy_arn = "arn:aws:iam::aws:policy/ReadOnlyAccess" + role = aws_iam_role.lm.name +} + +resource "aws_iam_role_policy_attachment" "aws_support_access" { + policy_arn = "arn:aws:iam::aws:policy/AWSSupportAccess" + role = aws_iam_role.lm.name +} + +// this resource acts as a timing buffer between the update of the AWS resources +// and the creation of the AWS Device Group in LM. This is required because the +// AWS API takes some time before the changes to the role is reflected. If done +// to quickly, the LM operation will fail. +resource "null_resource" "wait" { + triggers = { + always_run = timestamp() + } + provisioner "local-exec" { + command = "sleep 10s" + } + // runs after all dependent AWS operations are complete + depends_on = [ + aws_iam_role.lm, + aws_iam_role_policy_attachment.read_only_access, + aws_iam_role_policy_attachment.aws_support_access, + ] +} + +resource "logicmonitor_device_group" "my_aws_device_group" { + description = "test description" + disable_alerting = true + enable_netflow = false + extra { + account { + assumed_role_arn = aws_iam_role.lm.arn + external_id = data.logicmonitor_data_resource_aws_external_id.my_external_id.external_id + } + default { + disable_terminated_host_alerting = true + select_all = false + monitoring_region_infos = ["US_EAST_1", "US_EAST_2", "US_WEST_1", "US_WEST_2"] + dead_operation = "MANUALLY" + use_default = true + name_filter = [] + tags = [ + { + operation = "include" + name = "system.aws.tag.test" + value = "localdev" + }, + { + operation = "exclude" + name = "system.aws.tag.test1" + value = "HighPriority" + } + ] + } + services { + s_q_s { + // because use_default is true, no other fields are needed + // they settings will be determined by the above default object + use_default = true + } + } + } + group_type = "AWS/AwsRoot" + name = "Test AWS Group TF1" + parent_id = 1 + // Must guarantee that the AWS resources are updated before creating the device group + depends_on = [ + null_resource.wait, + ] +} +``` + +## Argument Reference + +The following arguments are **required**: +* `name` - The name of the device group + +The following arguments are **optional**: +* `applies_to` - The Applies to custom query for this group (only for dynamic groups) +* `custom_properties` - The properties associated with this device group + + `name` - The name of a property (required) + + `value` - The value of a property (required) +* `default_collector_id` - The Id of the default collector assigned to the device group +* `description` - The description of the device group +* `disable_alerting` - Indicates whether alerting is disabled (true) or enabled (false) for this device group +* `enable_netflow` - Indicates whether Netflow is enabled (true) or disabled (false) for the device group, the default value is true +* `extra` - The extra setting for cloud group + + `account` - cloud account information (currently only supports AWS) + + `accountId` - LogicMonitor's Account ID + + `assumedRoleArn` - ARN of the role created for LogicMonitor to use while monitoring AWS (required) + + `billingBucketName` - S3 bucket name that houses AWS billing info (deprecated) (computed) + + `billingPathPrefix` - Path to billing info in billing bucket (deprecated) (computed) + + `collectorId` - ID of the collector assigned to this group (computed) + + `externalId` - External ID provide by LM for the creation of the assumed role in AWS (required) + + `schedule` - The NetScan schedule for how frequently the cloud collector should scan/discover new resources in the cloud account. It's format is similar to Linux crontab but doesn't support some complex representations ('-', '/', ',') supported in standard linux crontabs.\nFormat: '*(minute) *(hour) *(day) *(week of month) *(weekday)'\nExamples: '50 * * * *' means scheduling at 50th minute per hour\n'50 10 20 * *' means scheduling at 10:50 of the 20th day per month\n'50 10 * 1 3' means scheduling at wednesday of the first week per month + + `type` - Type of cloud account (computed) + + `default` - default cloud service monitoring settings + + `customNSPSchedule` - The NetScan schedule for how frequently the cloud collector should scan/discover new resources in the cloud account. It's format is similar to Linux crontab but doesn't support some complex representations ('-', '/', ',') supported in standard linux crontabs.\nFormat: '*(minute) *(hour) *(day) *(week of month) *(weekday)'\nExamples: '50 * * * *' means scheduling at 50th minute per hour\n'50 10 20 * *' means scheduling at 10:50 of the 20th day per month\n'50 10 * 1 3' means scheduling at wednesday of the first week per month + + `deadOperation` - How to handle dead cloud devices (deletion from monitoring). Valid options include MANUALLY, IMMEDIATELY, KEEP_1_DAY, KEEP_3_DAYS, KEEP_7_DAYS, KEEP_14_DAYS, and KEEP_30_DAYS + + `deviceDisplayNameTemplate` - Template used to name devices found within the cloud account within the LM portal + + `disableStopTerminateHostMonitor` - If monitoring of stopped/terminated hosts is disabled + + `disableTerminatedHostAlerting` - If alerting should be disabled when a cloud device is terminated + + `monitoringRegionInfos` - The regions this group will monitor (array of strings) + + `monitoringRegions` - The regions this group will monitor (array of strings) (deprecated) (computed) + + `nameFilter` - Filter to determine which cloud devices should be monitored based on the device name (array of strings) + + `normalCollectorConfig` - Configuration of 'normal' collector installed to the cloud (ie an EC2 instance) + + `appliesTo` - AppliesTo expression to match or filter device + + `autoBalancedCollectorGroupId` - Auto balanced collector group id assigned to ec2 or azure vm (int) + + `collectorId` - Normal collector ID assigned to ec2 or azure vm (int) + + `priority` - Collector match priority, smaller value has higher priority (int) + + `usePublicIP` - Use cloud device public ip or not (boolean) + + `selectAll` - Whether or not to use all regions (can be used instead of monitoringRegions and monitoringRegionInfos) + + `tags` - Tags used to filter whether or not a cloud device is included in this group (array of CloudTagFilters) + + `name` - The name of the device property that this filter will appy to (i.e. system.aws.tag.os). Case sensitive for AWS resources + + `operation` - The operation that determines how this filter will be applied (options are 'exclude' or 'include') + + `value` - The glob expression that the filter will match on + + `useDefault` - Whether or not to use the default settings for this service. When set to true in a Service's settings, all other fields will be ignored (required) + + `devices` - Cloud devices to monitor in the group (computed) + + `deviceType` - Cloud device type (2 for AWS Device) (int) + + `requiredProps` - Required device properties (array of strings) + + `services` - Cloud account services to monitor. This is an object with keys for each AWS service that have the same arguments as `default`. See example above (all service keys alternate letters and underscores, but not numbers; SQS=s_q_s, SAGEMAKER=s_a_g_e_m_a_k_e_r, EC2=e_c2 etc.) +* `group_type` - The type of device group: normal and dynamic device groups will have groupType=Normal, and AWS groups will have a groupType value of AWS/SERVICE (e.g. AWS/AwsRoot, AWS/S3, etc.) +* `parent_id` - The id of the parent group for this device group (the root device group has an Id of 1) + +## Import + +device groups can be imported using their device group ID or full path +``` +$ terraform import logicmonitor_device_group.my_device_group 66 +$ terraform import logicmonitor_device_group.my_device_group Production/SBA/Linux +``` \ No newline at end of file diff --git a/website/docs/r/device_group_html.markdown b/website/docs/r/device_group_html.markdown deleted file mode 100644 index 99798bba..00000000 --- a/website/docs/r/device_group_html.markdown +++ /dev/null @@ -1,581 +0,0 @@ ---- -layout: "logicmonitor" -page_title: "LogicMonitor: logicmonitor_device_group" -sidebar_current: "docs-logicmonitor-resource-device-group" -description: |- - Provides a LogicMonitor device group resource. This can be used to create and manage LogicMonitor device groups. ---- - -# logicmonitor_device_group - -Provides a LogicMonitor device group resource. This can be used to create and manage LogicMonitor device groups. - -## Example Usage -```hcl -# Create a LogicMonitor device group -resource "logicmonitor_device_group" "my_device_group" { - applies_to = "isLinux()" - custom_properties = [ - { - name = "addr" - value = "127.0.0.1" - }, - { - name = "host" - value = "localhost" - } - ] - default_collector_id = 1 - description = "Linux Servers" - disable_alerting = true - enable_netflow = true - group_type = "Normal" - name = "Linux Servers" - parent_id = 1 -} -``` -## Example Usage - AWS Cloud Account -```hcl -provider "aws" { - // add your AWS credentials - access_key = "" - secret_key = "" - region = "" -} - -// used for verifying LM access to your AWS account -data "logicmonitor_data_resource_aws_external_id" "my_external_id" { -} - -data "aws_iam_policy_document" "assume_role" { - statement { - actions = [ - "sts:AssumeRole" - ] - condition { - test = "StringEquals" - values = [ - data.logicmonitor_data_resource_aws_external_id.my_external_id.external_id - ] - variable = "sts:ExternalId" - } - effect = "Allow" - principals { - identifiers = [ - "282028653949" - ] - type = "AWS" - } - } -} - -resource "aws_iam_role" "lm" { - assume_role_policy = data.aws_iam_policy_document.assume_role.json - name = "TF-Integration-Role" -} - -resource "aws_iam_role_policy_attachment" "read_only_access" { - policy_arn = "arn:aws:iam::aws:policy/ReadOnlyAccess" - role = aws_iam_role.lm.name -} - -resource "aws_iam_role_policy_attachment" "aws_support_access" { - policy_arn = "arn:aws:iam::aws:policy/AWSSupportAccess" - role = aws_iam_role.lm.name -} - -// this resource acts as a timing buffer between the update of the AWS resources -// and the creation of the AWS Device Group in LM. This is required because the -// AWS API takes some time before the changes to the role is reflected. If done -// to quickly, the LM operation will fail. -resource "null_resource" "wait" { - triggers = { - always_run = timestamp() - } - provisioner "local-exec" { - command = "sleep 10s" - } - // runs after all dependent AWS operations are complete - depends_on = [ - aws_iam_role.lm, - aws_iam_role_policy_attachment.read_only_access, - aws_iam_role_policy_attachment.aws_support_access, - ] -} - -resource "logicmonitor_device_group" "my_aws_device_group" { - description = "test description" - disable_alerting = true - enable_netflow = false - extra { - account { - assumed_role_arn = aws_iam_role.lm.arn - external_id = data.logicmonitor_data_resource_aws_external_id.my_external_id.external_id - } - default { - disable_terminated_host_alerting = true - select_all = false - monitoring_region_infos = ["US_EAST_1", "US_EAST_2", "US_WEST_1", "US_WEST_2"] - dead_operation = "MANUALLY" - use_default = true - name_filter = [] - tags = [ - { - operation = "include" - name = "system.aws.tag.test" - value = "localdev" - }, - { - operation = "exclude" - name = "system.aws.tag.test1" - value = "HighPriority" - } - ] - } - services { - s_q_s { - // because use_default is true, no other fields are needed - // they settings will be determined by the above default object - use_default = true - } - } - } - group_type = "AWS/AwsRoot" - name = "Test AWS Group TF1" - parent_id = 1 - // Must guarantee that the AWS resources are updated before creating the device group - depends_on = [ - null_resource.wait, - ] -} -``` -## Example Usage - Azure Cloud Account -```hcl -//Auth information for Azure account -variable "user_info" { - type = object({ - client_id = string - secret_key = string - tenant_id = string - }) - nullable = false - sensitive = true -} - -// Required fields: client_id, secret_key, tenant_id and subscription_ids -resource "logicmonitor_device_group" "my_azure_device_group" { - name = "Azure test" - parent_id = 1 - group_type = "Azure/AzureRoot" - description = "Azure test" - disable_alerting = false - # enable_netflow = false - custom_properties = [ - { - name = "customer" - value = "customerA" - } - ] - extra { - account { - schedule = "0 * * * *" - country = "USA" - client_id = var.user_info.client_id - secret_key = var.user_info.secret_key - subscription_ids = "" - tenant_id = var.user_info.tenant_id - collector_description = "Cloud Collector" - # collector_id = -2 - } - default { - disable_terminated_host_alerting = true - //normal_collector_config {} - custom_n_s_p_schedule = "" - select_all = true - monitoring_regions = [ - "CENTRAL_US", - "EAST_US", - "EAST_US_2" - ] - device_display_name_template = "" - disable_stop_terminate_host_monitor = true - dead_operation = "KEEP_7_DAYS" - use_default = true - name_filter = [] - tags = [] - } - services { - v_i_r_t_u_a_l_m_a_c_h_i_n_e { - disable_terminated_host_alerting = true - normal_collector_config { - collectors = [] - enabled = false - } - custom_n_s_p_schedule = "" - select_all = true - monitoring_regions = [ - "CENTRAL_US", - "EAST_US_2", - "WEST_US" - ] - device_display_name_template = "" - disable_stop_terminate_host_monitor = true - dead_operation = "KEEP_7_DAYS" - use_default = true - name_filter = [] - tags = [] - } - s_t_o_r_a_g_e_a_c_c_o_u_n_t { - disable_terminated_host_alerting = true - normal_collector_config { - collectors = [] - enabled = false - } - custom_n_s_p_schedule = "" - select_all = true - monitoring_regions = [ - "CENTRAL_US", - "EAST_US_2", - "WEST_US" - ] - device_display_name_template = "" - disable_stop_terminate_host_monitor = true - dead_operation = "KEEP_7_DAYS" - use_default = true - name_filter = [] - tags = [] - - } - e_v_e_n_t_h_u_b { - disable_terminated_host_alerting = true - normal_collector_config { - collectors = [] - enabled = false - } - custom_n_s_p_schedule = "" - select_all = true - monitoring_regions = [ - "CENTRAL_US", - "EAST_US_2", - "WEST_US" - ] - device_display_name_template = "" - disable_stop_terminate_host_monitor = true - dead_operation = "KEEP_7_DAYS" - use_default = true - name_filter = [] - tags = [] - - } - a_p_p_s_e_r_v_i_c_e { - disable_terminated_host_alerting = true - normal_collector_config { - collectors = [] - enabled = false - } - custom_n_s_p_schedule = "" - select_all = true - monitoring_regions = [ - "CENTRAL_US", - "EAST_US_2", - "WEST_US" - ] - device_display_name_template = "" - disable_stop_terminate_host_monitor = true - dead_operation = "KEEP_7_DAYS" - use_default = true - name_filter = [] - tags = [] - - } - a_p_p_s_e_r_v_i_c_e_p_l_a_n { - disable_terminated_host_alerting = true - normal_collector_config { - collectors = [] - enabled = false - } - custom_n_s_p_schedule = "" - select_all = true - monitoring_regions = [ - "CENTRAL_US", - "EAST_US_2", - "WEST_US" - ] - device_display_name_template = "" - disable_stop_terminate_host_monitor = true - dead_operation = "KEEP_7_DAYS" - use_default = true - name_filter = [] - tags = [] - } - v_i_r_t_u_a_l_m_a_c_h_i_n_e_s_c_a_l_e_s_e_t_vm { - disable_terminated_host_alerting = true - normal_collector_config { - collectors = [] - enabled = false - } - custom_n_s_p_schedule = "" - select_all = true - monitoring_regions = [ - "CENTRAL_US", - "EAST_US_2", - "WEST_US" - ] - device_display_name_template = "" - disable_stop_terminate_host_monitor = true - dead_operation = "KEEP_7_DAYS" - use_default = true - name_filter = [] - tags = [] - } - p_u_b_l_i_c_ip { - disable_terminated_host_alerting = true - normal_collector_config { - collectors = [] - enabled = false - } - custom_n_s_p_schedule = "" - select_all = true - monitoring_regions = [ - "CENTRAL_US", - "EAST_US_2", - "WEST_US" - ] - device_display_name_template = "" - disable_stop_terminate_host_monitor = true - dead_operation = "KEEP_7_DAYS" - use_default = true - name_filter = [] - tags = [] - } - sql_d_a_t_a_b_a_s_e { - disable_terminated_host_alerting = true - normal_collector_config { - collectors = [] - enabled = false - } - custom_n_s_p_schedule = "" - select_all = true - monitoring_regions = [ - "CENTRAL_US", - "EAST_US_2", - "WEST_US" - ] - device_display_name_template = "" - disable_stop_terminate_host_monitor = true - dead_operation = "KEEP_7_DAYS" - use_default = true - name_filter = [] - tags = [] - } - t_a_b_l_e_s_t_o_r_a_g_e { - disable_terminated_host_alerting = true - normal_collector_config { - collectors = [] - enabled = false - } - custom_n_s_p_schedule = "" - select_all = true - monitoring_regions = [ - "CENTRAL_US", - "EAST_US_2", - "WEST_US" - ] - device_display_name_template = "" - disable_stop_terminate_host_monitor = true - dead_operation = "KEEP_7_DAYS" - use_default = true - name_filter = [] - tags = [] - } - b_l_o_b_s_t_o_r_a_g_e { - disable_terminated_host_alerting = true - normal_collector_config { - collectors = [] - enabled = false - } - custom_n_s_p_schedule = "" - select_all = true - monitoring_regions = [ - "CENTRAL_US", - "EAST_US_2", - "WEST_US" - ] - device_display_name_template = "" - disable_stop_terminate_host_monitor = true - dead_operation = "KEEP_7_DAYS" - use_default = true - name_filter = [] - tags = [] - } - n_e_t_w_o_r_k_i_n_t_e_r_f_a_c_e { - disable_terminated_host_alerting = true - normal_collector_config { - collectors = [] - enabled = false - } - custom_n_s_p_schedule = "" - select_all = true - monitoring_regions = [ - "CENTRAL_US", - "EAST_US_2", - "WEST_US" - ] - device_display_name_template = "" - disable_stop_terminate_host_monitor = true - dead_operation = "KEEP_7_DAYS" - use_default = true - name_filter = [] - tags = [] - } - f_i_l_e_s_t_o_r_a_g_e { - disable_terminated_host_alerting = true - normal_collector_config { - collectors = [] - enabled = false - } - custom_n_s_p_schedule = "" - select_all = true - monitoring_regions = [ - "CENTRAL_US", - "EAST_US_2", - "WEST_US" - ] - device_display_name_template = "" - disable_stop_terminate_host_monitor = true - dead_operation = "KEEP_7_DAYS" - use_default = true - name_filter = [] - tags = [] - } - q_u_e_u_e_s_t_o_r_a_g_e { - disable_terminated_host_alerting = true - normal_collector_config { - collectors = [] - enabled = false - } - custom_n_s_p_schedule = "" - select_all = true - monitoring_regions = [ - "CENTRAL_US", - "EAST_US_2", - "WEST_US" - ] - device_display_name_template = "" - disable_stop_terminate_host_monitor = true - dead_operation = "KEEP_7_DAYS" - use_default = true - name_filter = [] - tags = [] - } - l_o_g_i_c_a_p_p_s { - disable_terminated_host_alerting = true - normal_collector_config { - collectors = [] - enabled = false - } - custom_n_s_p_schedule = "" - select_all = true - monitoring_regions = [ - "CENTRAL_US", - "EAST_US_2", - "WEST_US" - ] - device_display_name_template = "" - disable_stop_terminate_host_monitor = true - dead_operation = "KEEP_7_DAYS" - use_default = true - name_filter = [] - tags = [] - } - a_p_p_l_i_c_a_t_i_o_n_i_n_s_i_g_h_t_s { - disable_terminated_host_alerting = true - normal_collector_config { - collectors = [] - enabled = false - } - custom_n_s_p_schedule = "" - select_all = true - monitoring_regions = [ - "CENTRAL_US", - "EAST_US_2", - "WEST_US" - ] - device_display_name_template = "" - disable_stop_terminate_host_monitor = true - dead_operation = "KEEP_7_DAYS" - use_default = true - name_filter = [] - tags = [] - } - - } - } -} - - -``` - -## Argument Reference - -The following arguments are **required**: -* `name` - The name of the device group - -The following arguments are **optional**: -* `applies_to` - The Applies to custom query for this group (only for dynamic groups) -* `custom_properties` - The properties associated with this device group - + `name` - The name of a property (required) - + `value` - The value of a property (required) -* `default_collector_id` - The Id of the default collector assigned to the device group -* `description` - The description of the device group -* `disable_alerting` - Indicates whether alerting is disabled (true) or enabled (false) for this device group -* `enable_netflow` - Indicates whether Netflow is enabled (true) or disabled (false) for the device group, the default value is true -* `extra` - The extra setting for cloud group - + `account` - cloud account information (currently only supports AWS) - + `accountId` - LogicMonitor's Account ID - + `assumedRoleArn` - ARN of the role created for LogicMonitor to use while monitoring AWS (required) - + `billingBucketName` - S3 bucket name that houses AWS billing info (deprecated) (computed) - + `billingPathPrefix` - Path to billing info in billing bucket (deprecated) (computed) - + `collectorId` - ID of the collector assigned to this group (computed) - + `externalId` - External ID provide by LM for the creation of the assumed role in AWS (required for AWS) - + `clientId` - Client ID from Azure account (required for Azure) - + `secretKey` - Secret key from Azure Account (required for Azure) - + `subscriptionIds` - List of subcription ids(comma separated, required for Azure)) - + `tenantId` - Tenant ID from Azure account (required for Azure) - + `schedule` - The NetScan schedule for how frequently the cloud collector should scan/discover new resources in the cloud account. It's format is similar to Linux crontab but doesn't support some complex representations ('-', '/', ',') supported in standard linux crontabs.\nFormat: '*(minute) *(hour) *(day) *(week of month) *(weekday)'\nExamples: '50 * * * *' means scheduling at 50th minute per hour\n'50 10 20 * *' means scheduling at 10:50 of the 20th day per month\n'50 10 * 1 3' means scheduling at wednesday of the first week per month - + `type` - Type of cloud account (computed) - + `default` - default cloud service monitoring settings - + `customNSPSchedule` - The NetScan schedule for how frequently the cloud collector should scan/discover new resources in the cloud account. It's format is similar to Linux crontab but doesn't support some complex representations ('-', '/', ',') supported in standard linux crontabs.\nFormat: '*(minute) *(hour) *(day) *(week of month) *(weekday)'\nExamples: '50 * * * *' means scheduling at 50th minute per hour\n'50 10 20 * *' means scheduling at 10:50 of the 20th day per month\n'50 10 * 1 3' means scheduling at wednesday of the first week per month - + `deadOperation` - How to handle dead cloud devices (deletion from monitoring). Valid options include MANUALLY, IMMEDIATELY, KEEP_1_DAY, KEEP_3_DAYS, KEEP_7_DAYS, KEEP_14_DAYS, and KEEP_30_DAYS - + `deviceDisplayNameTemplate` - Template used to name devices found within the cloud account within the LM portal - + `disableStopTerminateHostMonitor` - If monitoring of stopped/terminated hosts is disabled - + `disableTerminatedHostAlerting` - If alerting should be disabled when a cloud device is terminated - + `monitoringRegionInfos` - The regions this group will monitor (array of strings) - + `monitoringRegions` - The regions this group will monitor (array of strings) (deprecated) (computed) - + `nameFilter` - Filter to determine which cloud devices should be monitored based on the device name (array of strings) - + `normalCollectorConfig` - Configuration of 'normal' collector installed to the cloud (ie an EC2 instance) - + `appliesTo` - AppliesTo expression to match or filter device - + `autoBalancedCollectorGroupId` - Auto balanced collector group id assigned to ec2 or azure vm (int) - + `collectorId` - Normal collector ID assigned to ec2 or azure vm (int) - + `priority` - Collector match priority, smaller value has higher priority (int) - + `usePublicIP` - Use cloud device public ip or not (boolean) - + `selectAll` - Whether or not to use all regions (can be used instead of monitoringRegions and monitoringRegionInfos) - + `tags` - Tags used to filter whether or not a cloud device is included in this group (array of CloudTagFilters) - + `name` - The name of the device property that this filter will appy to (i.e. system.aws.tag.os). Case sensitive for AWS resources - + `operation` - The operation that determines how this filter will be applied (options are 'exclude' or 'include') - + `value` - The glob expression that the filter will match on - + `useDefault` - Whether or not to use the default settings for this service. When set to true in a Service's settings, all other fields will be ignored (required) - + `devices` - Cloud devices to monitor in the group (computed) - + `deviceType` - Cloud device type (2 for AWS Device) (int) - + `requiredProps` - Required device properties (array of strings) - + `services` - Cloud account services to monitor. This is an object with keys for each AWS/Azure service that have the same arguments as `default`. See example above (all service keys alternate letters and underscores, but not numbers; SQS=s_q_s, SAGEMAKER=s_a_g_e_m_a_k_e_r, EC2=e_c2 etc.) -* `group_type` - The type of device group: normal and dynamic device groups will have groupType=Normal, and AWS groups will have a groupType value of AWS/SERVICE (e.g. AWS/AwsRoot, AWS/S3, Azure/AzureRoot etc.) -* `parent_id` - The id of the parent group for this device group (the root device group has an Id of 1) - -## Import - -device groups can be imported using their device group ID or full path -``` -$ terraform import logicmonitor_device_group.my_device_group 66 -$ terraform import logicmonitor_device_group.my_device_group Production/SBA/Linux -``` \ No newline at end of file diff --git a/website/docs/r/escalation_chain_html.markdown b/website/docs/r/escalation_chain.markdown similarity index 100% rename from website/docs/r/escalation_chain_html.markdown rename to website/docs/r/escalation_chain.markdown diff --git a/website/docs/r/website_html.markdown b/website/docs/r/website.markdown similarity index 79% rename from website/docs/r/website_html.markdown rename to website/docs/r/website.markdown index 7bf91358..83b5633e 100644 --- a/website/docs/r/website_html.markdown +++ b/website/docs/r/website.markdown @@ -18,6 +18,7 @@ resource "logicmonitor_website" "my_website" { disable_alerting = domain = "www.ebay.com" global_sm_alert_cond = 0 + group_id = 1 host = "" individual_alert_level = "warn" individual_sm_alert_enable = false @@ -36,11 +37,29 @@ resource "logicmonitor_website" "my_website" { http_method = "GET" enable = true http_version = "1.1" + http_headers = "X-Version:3" follow_redirection = true post_data_edit_type = "raw" name = "string" req_type = "config" fullpage_load = false + require_auth = false + path = "string" + auth = [{ + password = "string" + type = "basic" + domain = "string" + user_name = "string" + }] + keyword = "DEVWRT-SANRT-JOB1-9127" + http_body = "string" + resp_script = "string" + req_script = "string" + label = "string" + url = "/rest/version" + type = "string" + invert_match = false + status_code = "200" } ] stop_monitoring = @@ -70,6 +89,7 @@ If stopMonitoring=true, then alerting will also by default be disabled for the w 1 : half 2 : more than one 3 : any +* `group_id` - The id of the group the website is in * `host` - The URL to check, without the scheme or protocol (e.g http or https) E.g. if the URL is "http://www.google.com, then the host="www.google.com" * `individual_alert_level` - warn | error | critical @@ -83,7 +103,7 @@ The level of alert to trigger if the website fails the number of checks specifie The polling interval for the website, in units of minutes. This value indicates how often the website is checked. The minimum is 1 minute, and the maximum is 10 minutes * `steps` - Required for type=webcheck , An object comprising one or more steps, see the table below for the properties included in each step + `schema` - HTTP schema - + `matchType` - Body match type + + `matchType` - Body match type(plain | JSON | XML | Glob Expression | Multi-line key-value pairs) + `description` - The description of the Step + `httpVersion` - 1.1 | 1\nSpecifies HTTP version + `respType` - Plain Text/String | Glob expression | JSON | XML | Multi line key value pair\nStep Response Type @@ -96,6 +116,23 @@ The polling interval for the website, in units of minutes. This value indicates + `useDefaultRoot` - true | falseCheck if using the default root + `postDataEditType` - Raw | Formatted Data\nSpecifies POST data type + `fullpageLoad` - true | false\nChecks if full page should be loaded or not + + `requireAuth` - true | false\nChecks if authorization required or not + + `path` - Path for JSON, XPATH + + `auth`- Authorization Information + + `password` - NTLM authentication password + + `type` - Authentication type + + `userName` - NTLM authentication userName + + `domain` - NTLM domain (if auth type is NTLM) + + `httpHeaders` - HTTP header + + `httpBody` - HTTP Body + + `keyword` - Keyword that matches the body + + `respScript` - The Step Response Script + + `reqScript` - The Request Script + + `label` - The Label of the Step + + `url` - The URL of service step + + `invertMatch` - true | false\nChecks if invert matches or not + + `type` - script | config\nThe type of service step + + `statusCode` - The expected status code * `stop_monitoring` - true: monitoring is disabled for the website false: monitoring is enabled for the website If stopMonitoring=true, then alerting will also by default be disabled for the website diff --git a/website/docs/r/website_group_html.markdown b/website/docs/r/website_group.markdown similarity index 100% rename from website/docs/r/website_group_html.markdown rename to website/docs/r/website_group.markdown