Blob


1 package icinga provides a client to the Icinga2 HTTP API.
3 [![godocs.io](http://godocs.io/olowe.co/icinga?status.svg)](http://godocs.io/olowe.co/icinga)
5 Send any patches, questions or requests to the [mailing list][list] [~otl/icinga@lists.sr.ht](mailto:~otl/icinga@lists.sr.ht) 🙂
7 [list]: https://lists.sr.ht/~otl/icinga
9 ## Quick Start
11 A Client manages interaction with an Icinga2 server.
12 It is created using Dial. Provide the address, in `host:port` form, API username and password, and a `http.Client`:
14 client, err := icinga.Dial("icinga.example.com:5665", "icinga", "secret", http.DefaultClient)
15 if err != nil {
16 // handle error
17 }
19 Icinga2 servers in the wild often serve self-signed certificates which
20 fail verification by Go's tls client. To ignore the errors, Dial the server
21 with a modified `http.Client`:
23 t := http.DefaultTransport.(*http.Transport)
24 t.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
25 c := http.DefaultClient
26 c.Transport = t
27 client, err := icinga.Dial(addr, user, pass, c)
28 if err != nil {
29 // handle error
30 }
32 Methods on `Client` provide API actions like looking up users and creating hosts:
34 user, err := client.LookupUser("oliver")
35 if err != nil {
36 // handle error
37 }
38 host := Host{
39 Name: "myserver.example.com",
40 CheckCommand: "hostalive"
41 Address: "192.0.2.1"
42 Address6: "2001:db8::1"
43 }
44 if err := client.CreateHost(host); err != nil {
45 // handle error
46 }
48 Not all functionality of the Icinga2 API is implemented.
49 For more detail, see the [godocs][godocs].
51 [godocs]: https://godocs.io/olowe.co/icinga
53 ## Development
55 Some code is automatically generated. Ensure it's up-to-date before starting work:
57 go generate
59 Make some changes, then run the tests. No fancy test framework:
61 go test
63 Send any questions, patches, requests to the mailing list [~otl/icinga@lists.sr.ht](mailto:~otl/icinga@lists.sr.ht)
65 ### Testing
67 Some tests dial an instance of Icinga2 running on the loopback address
68 and the standard Icinga2 port 5665 ("127.0.0.1:5665"). If this fails,
69 those tests are skipped. To run these tests, create the following API
70 user:
72 object ApiUser "root" {
73 password = "icinga"
74 permissions = [ "*" ]
75 }
77 Getting data from 127.0.0.1:5665 to an Icinga server is left as an
78 exercise to the reader!
80 Personally, I run an Alpine Linux virtual machine using qemu. You
81 could also use the [official Icinga2 container image][image].
83 [image]: https://hub.docker.com/r/icinga/icinga2
85 ### Code generation
87 Source code for the basic lookup, create and delete operations of some
88 Icinga2 object types, such as Host and Service, are generated
89 automatically.
91 The shell script crud.sh writes Go source code by reading a template
92 file and doing some text substitution. It loops through object types,
93 piping the template file crud.skel into the awk script crud.awk for
94 each.
96 crud.sh writes code to the standard output by default:
98 ./crud.sh
100 If the flag `-o` is set, code will be written to the file
101 specified instead of to standard output:
103 ./crud.sh -o crud.go
105 Code generation is used because the functions are trivial and call the exact
106 same underlying methods on Client anyway. The only thing that differs is the type.
107 Perhaps when Go gets type parameters then this will go away?
109 ## Why Another Package?
111 The [icinga2 terraform provider][tf] uses the package [github.com/lrsmith/go-icinga2-api/iapi][lrsmith].
112 As I read the source code I felt I wasn't reading idiomatic Go as detailed in documents like [Effective Go][effectivego].
113 Other properties of `iapi` felt unusual to me:
115 * The client to the API has the confusing name `server`.
116 * Every HTTP request creates a new http.Client.
117 * Types have superfluous names like `HostStruct` instead of just `Host`.
118 * Every response body from the API is decoded from JSON into one data strucutre, marshalled into JSON again, then unmarshalled back into another.
119 * Every error returned from a function has a new name, rather than reusing the idiomatic name `err`.
121 If I was being paid, I'd create a fork and contribute patches upstream to carefully avoid breaking functionality of existing users of `iapi`.
123 But I'm not being paid ;)
125 [effectivego]: https://go.dev/doc/effective_go
126 [tf]: https://registry.terraform.io/providers/Icinga/icinga2/latest
127 [lrsmith]: https://godocs.io/github.com/lrsmith/go-icinga2-api/iapi