Skip to content

Commit

Permalink
Merge pull request #27 from netdata/feat/node-room-member
Browse files Browse the repository at this point in the history
feat: add netdata_node_room_member
  • Loading branch information
witalisoft authored May 29, 2024
2 parents b2b1ddb + cd65265 commit b9945bf
Show file tree
Hide file tree
Showing 10 changed files with 565 additions and 0 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 0.2.0

FEATURES:

- add `netdata_node_room_member` resource

## 0.1.3

FEATURES:
Expand Down
47 changes: 47 additions & 0 deletions docs/resources/node_room_member.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "netdata_node_room_member Resource - terraform-provider-netdata"
subcategory: ""
description: |-
Provides a Netdata Cloud Node Room Member resource. Use this resource to manage node membership to the room in the selected space, only reachable nodes can be added to the room.
This resource is useful in the case of Netdata Streaming and Replication https://learn.netdata.cloud/docs/observability-centralization-points/metrics-centralization-points/ when you want to spread
the Netdata child agents across different rooms because by default all of them end in the same room like the Netdata parent.
---

# netdata_node_room_member (Resource)

Provides a Netdata Cloud Node Room Member resource. Use this resource to manage node membership to the room in the selected space, only reachable nodes can be added to the room.
This resource is useful in the case of [Netdata Streaming and Replication](https://learn.netdata.cloud/docs/observability-centralization-points/metrics-centralization-points/) when you want to spread
the Netdata child agents across different rooms because by default all of them end in the same room like the Netdata parent.

## Example Usage

```terraform
resource "netdata_node_room_member" "test" {
space_id = "<space_id>"
room_id = "<room_id>"
node_names = [
"node1",
"node2"
]
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `node_names` (List of String) List of node names to add to the room
- `room_id` (String) The Room ID of the space
- `space_id` (String) Space ID of the member

## Import

Import is supported using the following syntax:

```shell
#!/bin/sh

terraform import netdata_node_room_member.test space_id,room_id
```
9 changes: 9 additions & 0 deletions examples/complete/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ resource "netdata_room_member" "test" {
space_member_id = netdata_space_member.test.id
}

resource "netdata_node_room_member" "test" {
room_id = netdata_room.test.id
space_id = netdata_space.test.id
node_names = [
"node1",
"node2"
]
}

resource "netdata_notification_slack_channel" "test" {
name = "slack"

Expand Down
3 changes: 3 additions & 0 deletions examples/resources/netdata_node_room_member/import.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

terraform import netdata_node_room_member.test space_id,room_id
8 changes: 8 additions & 0 deletions examples/resources/netdata_node_room_member/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
resource "netdata_node_room_member" "test" {
space_id = "<space_id>"
room_id = "<room_id>"
node_names = [
"node1",
"node2"
]
}
1 change: 1 addition & 0 deletions internal/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ var (
ErrChannelIDRequired = errors.New("channelID is required")
ErrRoomIDRequired = errors.New("roomID is required")
ErrMemberIDRequired = errors.New("memberID is required")
ErrNodeID = errors.New("nodeID is required")
)

type Client struct {
Expand Down
10 changes: 10 additions & 0 deletions internal/client/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,13 @@ type Invitation struct {
ID string `json:"id"`
Email string `json:"email"`
}

type RoomNodes struct {
Nodes []RoomNode `json:"nodes"`
}

type RoomNode struct {
NodeID string `json:"nd"`
NodeName string `json:"nm"`
State string `json:"state"`
}
113 changes: 113 additions & 0 deletions internal/client/node_room_member.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package client

import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)

func (c *Client) GetRoomNodes(spaceID, roomID string) (*RoomNodes, error) {
if spaceID == "" {
return nil, ErrSpaceIDRequired
}
if roomID == "" {
return nil, ErrRoomIDRequired
}

reqBody := []byte(`{"scope":{"nodes":[]}}`)

req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/api/v3/spaces/%s/rooms/%s/nodes", c.HostURL, spaceID, roomID), bytes.NewReader(reqBody))
if err != nil {
return nil, err
}

var roomNodes RoomNodes

err = c.doRequestUnmarshal(req, &roomNodes)
if err != nil {
return nil, err
}

return &roomNodes, nil
}

func (c *Client) GetAllNodes(spaceID string) (*RoomNodes, error) {
if spaceID == "" {
return nil, ErrSpaceIDRequired
}

allRooms, err := c.GetRooms(spaceID)
if err != nil {
return nil, err
}

var allNodesRoomID string
for _, room := range *allRooms {
if room.Name == "All nodes" {
allNodesRoomID = room.ID
break
}
}

roomNodes, err := c.GetRoomNodes(spaceID, allNodesRoomID)
if err != nil {
return nil, err
}

return roomNodes, nil
}

func (c *Client) CreateNodeRoomMember(spaceID, roomID, nodeID string) error {
if spaceID == "" {
return ErrSpaceIDRequired
}
if roomID == "" {
return ErrRoomIDRequired
}
if nodeID == "" {
return ErrNodeID
}

reqBody, err := json.Marshal([]string{nodeID})
if err != nil {
return err
}

req, err := http.NewRequest(http.MethodPost, fmt.Sprintf("%s/api/v1/spaces/%s/rooms/%s/claimed-nodes", c.HostURL, spaceID, roomID), bytes.NewReader(reqBody))
if err != nil {
return err
}

_, err = c.doRequest(req)
if err != nil {
return err
}

return nil

}

func (c *Client) DeleteNodeRoomMember(spaceID, roomID, nodeID string) error {
if spaceID == "" {
return ErrSpaceIDRequired
}
if roomID == "" {
return ErrRoomIDRequired
}
if nodeID == "" {
return ErrNodeID
}

req, err := http.NewRequest(http.MethodDelete, fmt.Sprintf("%s/api/v1/spaces/%s/rooms/%s/claimed-nodes?node_ids=%s", c.HostURL, spaceID, roomID, nodeID), nil)
if err != nil {
return err
}

_, err = c.doRequest(req)
if err != nil {
return err
}

return nil
}
Loading

0 comments on commit b9945bf

Please sign in to comment.