commit 02a1a10065dd3be4f89f30756adc670b1a8ab468
parent da19a2fd0fbbf44bc5495e68c7f24103d025b3b6
Author: Oliver Lowe <o@olowe.co>
Date: Tue, 18 Jan 2022 22:27:28 +1100
Support cascading delete of objects
Diffstat:
5 files changed, 67 insertions(+), 29 deletions(-)
diff --git a/crud.go b/crud.go
@@ -46,10 +46,11 @@ func (c *Client) CreateHost(host Host) error {
return nil
}
-// DeleteHost deletes the Host identified by name.
-// If no Host is found, error wraps ErrNotExist.
-func (c *Client) DeleteHost(name string) error {
- if err := c.deleteObject("/objects/hosts/" + name); err != nil {
+// DeleteHost deletes the Host identified by name. If cascade is true, objects
+// depending on the Host are also deleted. If no Host is found, error wraps
+// ErrNotExist.
+func (c *Client) DeleteHost(name string, cascade bool) error {
+ if err := c.deleteObject("/objects/hosts/"+name, cascade); err != nil {
return fmt.Errorf("delete host %s: %w", name, err)
}
return nil
@@ -97,10 +98,11 @@ func (c *Client) CreateService(service Service) error {
return nil
}
-// DeleteService deletes the Service identified by name.
-// If no Service is found, error wraps ErrNotExist.
-func (c *Client) DeleteService(name string) error {
- if err := c.deleteObject("/objects/services/" + name); err != nil {
+// DeleteService deletes the Service identified by name. If cascade is true, objects
+// depending on the Service are also deleted. If no Service is found, error wraps
+// ErrNotExist.
+func (c *Client) DeleteService(name string, cascade bool) error {
+ if err := c.deleteObject("/objects/services/"+name, cascade); err != nil {
return fmt.Errorf("delete service %s: %w", name, err)
}
return nil
@@ -148,10 +150,11 @@ func (c *Client) CreateUser(user User) error {
return nil
}
-// DeleteUser deletes the User identified by name.
-// If no User is found, error wraps ErrNotExist.
-func (c *Client) DeleteUser(name string) error {
- if err := c.deleteObject("/objects/users/" + name); err != nil {
+// DeleteUser deletes the User identified by name. If cascade is true, objects
+// depending on the User are also deleted. If no User is found, error wraps
+// ErrNotExist.
+func (c *Client) DeleteUser(name string, cascade bool) error {
+ if err := c.deleteObject("/objects/users/"+name, cascade); err != nil {
return fmt.Errorf("delete user %s: %w", name, err)
}
return nil
@@ -199,10 +202,11 @@ func (c *Client) CreateHostGroup(hostgroup HostGroup) error {
return nil
}
-// DeleteHostGroup deletes the HostGroup identified by name.
-// If no HostGroup is found, error wraps ErrNotExist.
-func (c *Client) DeleteHostGroup(name string) error {
- if err := c.deleteObject("/objects/hostgroups/" + name); err != nil {
+// DeleteHostGroup deletes the HostGroup identified by name. If cascade is true, objects
+// depending on the HostGroup are also deleted. If no HostGroup is found, error wraps
+// ErrNotExist.
+func (c *Client) DeleteHostGroup(name string, cascade bool) error {
+ if err := c.deleteObject("/objects/hostgroups/"+name, cascade); err != nil {
return fmt.Errorf("delete hostgroup %s: %w", name, err)
}
return nil
diff --git a/crud.skel b/crud.skel
@@ -40,12 +40,12 @@ func (c *Client) CreateTYPE(LOWER TYPE) error {
return nil
}
-// DeleteTYPE deletes the TYPE identified by name.
-// If no TYPE is found, error wraps ErrNotExist.
-func (c *Client) DeleteTYPE(name string) error {
- if err := c.deleteObject("/objects/PLURAL/" + name); err != nil {
+// DeleteTYPE deletes the TYPE identified by name. If cascade is true, objects
+// depending on the TYPE are also deleted. If no TYPE is found, error wraps
+// ErrNotExist.
+func (c *Client) DeleteTYPE(name string, cascade bool) error {
+ if err := c.deleteObject("/objects/PLURAL/" + name, cascade); err != nil {
return fmt.Errorf("delete LOWER %s: %w", name, err)
}
return nil
}
-
diff --git a/http.go b/http.go
@@ -64,9 +64,17 @@ func (c *Client) put(path string, body io.Reader) (*http.Response, error) {
return c.Do(req)
}
-func (c *Client) delete(path string) (*http.Response, error) {
- url := "https://" + c.addr + versionPrefix + path
- req, err := NewRequest(http.MethodDelete, url, c.username, c.password, nil)
+func (c *Client) delete(path string, cascade bool) (*http.Response, error) {
+ u, err := url.Parse("https://" + c.addr + versionPrefix + path)
+ if err != nil {
+ return nil, err
+ }
+ if cascade {
+ v := url.Values{}
+ v.Set("cascade", "1")
+ u.RawQuery = v.Encode()
+ }
+ req, err := NewRequest(http.MethodDelete, u.String(), c.username, c.password, nil)
if err != nil {
return nil, err
}
diff --git a/icinga_test.go b/icinga_test.go
@@ -55,7 +55,7 @@ func TestFilter(t *testing.T) {
if err != nil {
t.Error(err)
}
- defer client.DeleteHostGroup(hostgroup.Name)
+ defer client.DeleteHostGroup(hostgroup.Name, false)
var want, got []string
for i := 0; i < 5; i++ {
@@ -75,7 +75,7 @@ func TestFilter(t *testing.T) {
}
defer func() {
for _, name := range want {
- if err := client.DeleteHost(name); err != nil {
+ if err := client.DeleteHost(name, false); err != nil {
t.Log(err)
}
}
@@ -105,7 +105,7 @@ func TestUserRoundTrip(t *testing.T) {
t.Fatal(err)
}
defer func() {
- if err := client.DeleteUser(want.Name); err != nil {
+ if err := client.DeleteUser(want.Name, false); err != nil {
t.Error(err)
}
}()
@@ -134,3 +134,29 @@ func TestChecker(t *testing.T) {
}
t.Logf("%+v\n", s)
}
+
+func TestCreateService(t *testing.T) {
+ client, err := newTestClient()
+ if err != nil {
+ t.Skipf("no local test icinga? got: %v", err)
+ }
+
+ h := icinga.Host{
+ Name: "example.com",
+ Address: "example.com",
+ CheckCommand: "dummy",
+ DisplayName: "RFC 2606 example host",
+ }
+ if err := client.CreateHost(h); err != nil {
+ t.Error(err)
+ }
+ defer client.DeleteHost(h.Name, true)
+ s := icinga.Service{
+ Name: h.Name + "!http",
+ CheckCommand: "http",
+ DisplayName: "RFC 2606 example website",
+ }
+ if err := client.CreateService(s); err != nil {
+ t.Error(err)
+ }
+}
diff --git a/object.go b/object.go
@@ -85,8 +85,8 @@ func (c *Client) createObject(obj object) error {
return iresp.Error
}
-func (c *Client) deleteObject(objpath string) error {
- resp, err := c.delete(objpath)
+func (c *Client) deleteObject(objpath string, cascade bool) error {
+ resp, err := c.delete(objpath, cascade)
if err != nil {
return err
}