-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add discovery rules resource (#2)
feat: add discovery rules resource
- Loading branch information
Showing
13 changed files
with
1,064 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
|
||
# foreman_discovery_rules | ||
|
||
Discovery rules in Foreman are used to automatically provision hosts based on predefined criteria. | ||
These rules help streamline the process of adding new hosts to your infrastructure by automating the provisioning process based on specific conditions. | ||
|
||
## Example Usage | ||
|
||
```terraform | ||
resource "foreman_discovery_rule" "example_rule_01" { | ||
name = "Example Rule HPE servers" | ||
search = "facts.bios_vendor = HPE" | ||
hostgroup_ids = 3 | ||
hostname = "<%= @host.facts['nmprimary_dhcp4_option_host_name'] %>" | ||
max_count = 0 | ||
priority = 100 | ||
enabled = true | ||
location_ids = [2] | ||
organization_ids = [1] | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
- `name` - (Required) The name of the discovery rule. | ||
- `search` - (Required) The search criteria used to match hosts. | ||
- `priority` - (Required) The priority of the rule. | ||
- `hostgroup_id` - (Optional) The ID of the host group to which the discovered host will be assigned. | ||
- `enabled` - (Optional) A boolean value indicating whether the discovery rule is enabled. When set to `true`, the rule is active and will be evaluated. | ||
- `order` - (Optional) An integer specifying the order in which the rule is evaluated. Lower numbers are evaluated first. | ||
- `parameters` - (Optional) A map of key-value pairs that will be saved as discovery rule parameters. These parameters can be used to pass additional information to the rule. | ||
- `max_count` - (Optional) The maximum number of hosts that can be discovered by this rule. A value of `0` means unlimited. | ||
- `hostname` - (Optional) The hostname pattern to be used for the discovered hosts. | ||
- `location_ids` - (Optional) A list of location IDs where the discovered hosts will be assigned. | ||
- `organization_ids` - (Optional) A list of organization IDs where the discovered hosts will be assigned. | ||
|
||
## Attributes Reference | ||
|
||
The following attributes are exported: | ||
|
||
- `name` - The name of the discovery rule. | ||
- `search` - The search criteria used to match hosts. | ||
- `priority` - The priority of the rule. | ||
- `hostgroup_id` - The ID of the host group to which the discovered host will be assigned. | ||
- `enabled` - Whether the discovery rule is enabled. | ||
- `order` - The order in which the rule is evaluated. | ||
- `parameters` - A map of parameters that will be saved as discovery rule parameters. | ||
- `max_count` - (Optional) The maximum number of hosts that can be discovered by this rule. A value of `0` means unlimited. | ||
- `hostname` - (Optional) The hostname pattern to be used for the discovered hosts. | ||
- `location_ids` - (Optional) A list of location IDs where the discovered hosts will be assigned. | ||
- `organization_ids` - (Optional) A list of organization IDs where the discovered hosts will be assigned. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
provider "foreman" { | ||
server_hostname = "192.168.1.118" | ||
server_protocol = "https" | ||
|
||
client_tls_insecure = true | ||
|
||
client_username = "${var.client_username}" | ||
client_password = "${var.client_password}" | ||
} | ||
|
||
resource "foreman_discovery_rule" "example_rule_01" { | ||
name = "example-rule-01" | ||
search = "facts.bios_vendor = HPE" | ||
hostgroup_ids = 5 | ||
hostname = "<%= @host.facts['nmprimary_dhcp4_option_host_name'] %>" | ||
max_count = 0 | ||
priority = 100 | ||
enabled = true | ||
location_ids = [1] | ||
organization_ids = [1] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,214 @@ | ||
package api | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
"net/http" | ||
"path" | ||
"strconv" | ||
|
||
"github.com/HanseMerkur/terraform-provider-utils/log" | ||
) | ||
|
||
const ( | ||
DiscoveryRuleEndpointPrefix = "/v2/discovery_rules/" | ||
) | ||
|
||
type ForemanDiscoveryRule struct { | ||
ForemanObject | ||
Name string `json:"name"` | ||
Search string `json:"search,omitempty"` | ||
HostGroupId int `json:"hostgroup_id,omitempty"` | ||
Hostname string `json:"hostname,omitempty"` | ||
HostsLimitMaxCount int `json:"max_count,omitempty"` | ||
Priority int `json:"priority"` | ||
Enabled bool `json:"enabled"` | ||
LocationIds []int `json:"location_ids,omitempty"` | ||
OrganizationIds []int `json:"organization_ids,omitempty"` | ||
DefaultLocationId int `json:"location_id,omitempty"` | ||
DefaultOrganizationId int `json:"organization_id,omitempty"` | ||
} | ||
|
||
type ForemanDiscoveryRuleResponse struct { | ||
ForemanObject | ||
Name string `json:"name"` | ||
Search string `json:"search,omitempty"` | ||
HostGroupId int `json:"hostgroup_id,omitempty"` | ||
Hostname string `json:"hostname,omitempty"` | ||
Priority int `json:"priority"` | ||
Enabled bool `json:"enabled"` | ||
HostsLimitMaxCount int `json:"hosts_limit,omitempty"` | ||
Locations []EntityResponse `json:"locations,omitempty"` | ||
Organizations []EntityResponse `json:"organizations,omitempty"` | ||
} | ||
|
||
type EntityResponse struct { | ||
ID int `json:"id"` | ||
Name string `json:"name"` | ||
Title string `json:"title"` | ||
Description any `json:"description"` | ||
} | ||
|
||
// CreateDiscoveryRule creates a new ForemanDiscoveryRule | ||
func (c *Client) CreateDiscoveryRule(ctx context.Context, d *ForemanDiscoveryRule) (*ForemanDiscoveryRule, error) { | ||
log.Tracef("foreman/api/discovery_rule.go#Create") | ||
|
||
if d.DefaultLocationId == 0 { | ||
d.DefaultLocationId = c.clientConfig.LocationID | ||
} | ||
|
||
if d.DefaultOrganizationId == 0 { | ||
d.DefaultOrganizationId = c.clientConfig.OrganizationID | ||
} | ||
|
||
dJSONBytes, err := c.WrapJSON("discovery_rule", d) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
log.Debugf("discoveryruleJSONBytes: [%s]", dJSONBytes) | ||
|
||
req, err := c.NewRequestWithContext( | ||
ctx, | ||
http.MethodPost, | ||
DiscoveryRuleEndpointPrefix, | ||
bytes.NewBuffer(dJSONBytes), | ||
) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var createdDiscoveryRule ForemanDiscoveryRule | ||
if err := c.SendAndParse(req, &createdDiscoveryRule); err != nil { | ||
return nil, err | ||
} | ||
|
||
log.Debugf("createdDiscoveryRule: [%+v]", createdDiscoveryRule) | ||
|
||
return &createdDiscoveryRule, nil | ||
} | ||
|
||
// ReadDiscoveryRule reads the ForemanDiscoveryRule identified by the supplied ID | ||
func (c *Client) ReadDiscoveryRule(ctx context.Context, id int) (*ForemanDiscoveryRuleResponse, error) { | ||
log.Tracef("foreman/api/discovery_rule.go#Read") | ||
|
||
reqEndpoint := path.Join(DiscoveryRuleEndpointPrefix, strconv.Itoa(id)) | ||
req, err := c.NewRequestWithContext( | ||
ctx, | ||
http.MethodGet, | ||
reqEndpoint, | ||
nil, | ||
) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var readDiscoveryRule ForemanDiscoveryRuleResponse | ||
if err := c.SendAndParse(req, &readDiscoveryRule); err != nil { | ||
return nil, err | ||
} | ||
|
||
log.Debugf("readDiscoveryRule: [%+v]", readDiscoveryRule) | ||
|
||
return &readDiscoveryRule, nil | ||
} | ||
|
||
// UpdateDiscoveryRule updates the ForemanDiscoveryRule identified by the supplied ForemanDiscoveryRule | ||
func (c *Client) UpdateDiscoveryRule(ctx context.Context, d *ForemanDiscoveryRule) (*ForemanDiscoveryRule, error) { | ||
log.Tracef("foreman/api/discovery_rule.go#Update") | ||
|
||
reqEndpoint := path.Join(DiscoveryRuleEndpointPrefix, strconv.Itoa(d.Id)) | ||
|
||
discoveryruleJSONBytes, err := c.WrapJSON("discovery_rule", d) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
log.Debugf("discoveryruleJSONBytes: [%s]", discoveryruleJSONBytes) | ||
|
||
req, err := c.NewRequestWithContext( | ||
ctx, | ||
http.MethodPut, | ||
reqEndpoint, | ||
bytes.NewBuffer(discoveryruleJSONBytes), | ||
) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var updatedDiscoveryRule ForemanDiscoveryRule | ||
|
||
if err := c.SendAndParse(req, &updatedDiscoveryRule); err != nil { | ||
return nil, err | ||
} | ||
|
||
log.Debugf("updatedDiscoveryRule: [%+v]", updatedDiscoveryRule) | ||
|
||
return &updatedDiscoveryRule, nil | ||
} | ||
|
||
// DeleteDiscoveryRule deletes the ForemanDiscoveryRule identified by the supplied ID | ||
func (c *Client) DeleteDiscoveryRule(ctx context.Context, id int) error { | ||
log.Tracef("foreman/api/discovery_rule.go#Delete") | ||
|
||
reqEndpoint := path.Join(DiscoveryRuleEndpointPrefix, strconv.Itoa(id)) | ||
|
||
req, err := c.NewRequestWithContext( | ||
ctx, | ||
http.MethodDelete, | ||
reqEndpoint, | ||
nil, | ||
) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return c.SendAndParse(req, nil) | ||
} | ||
|
||
// QueryDiscoveryRule queries the ForemanDiscoveryRule identified by the supplied ForemanDiscoveryRule | ||
func (c *Client) QueryDiscoveryRule(ctx context.Context, d *ForemanDiscoveryRule) (QueryResponse, error) { | ||
log.Tracef("foreman/api/discovery_rule.go#Search") | ||
|
||
queryResponse := QueryResponse{} | ||
|
||
req, err := c.NewRequestWithContext( | ||
ctx, | ||
http.MethodGet, | ||
DiscoveryRuleEndpointPrefix, | ||
nil, | ||
) | ||
if err != nil { | ||
return queryResponse, err | ||
} | ||
|
||
reqQuery := req.URL.Query() | ||
reqQuery.Set("search", fmt.Sprintf("name=\"%s\"", d.Name)) | ||
|
||
req.URL.RawQuery = reqQuery.Encode() | ||
if err := c.SendAndParse(req, &queryResponse); err != nil { | ||
return queryResponse, err | ||
} | ||
|
||
log.Debugf("queryResponse: [%+v]", queryResponse) | ||
|
||
results := []ForemanDiscoveryRule{} | ||
resultsBytes, err := json.Marshal(queryResponse.Results) | ||
if err != nil { | ||
return queryResponse, err | ||
} | ||
|
||
if err := json.Unmarshal(resultsBytes, &results); err != nil { | ||
return queryResponse, err | ||
} | ||
|
||
iArr := make([]interface{}, len(results)) | ||
for idx, val := range results { | ||
iArr[idx] = val | ||
} | ||
queryResponse.Results = iArr | ||
|
||
return queryResponse, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.