Blame


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