@@ -15,6 +15,7 @@ import (
1515 "github.com/stretchr/testify/assert"
1616 "github.com/stretchr/testify/require"
1717 "go.uber.org/zap"
18+ "golang.org/x/exp/slices"
1819 "io"
1920 "reflect"
2021 "sort"
@@ -328,7 +329,7 @@ func TestObjectSync(t *testing.T) {
328329 t .Parallel ()
329330
330331 client .CreateObject (t , "services" , * service .HostName + "!" + service .Name , map [string ]interface {}{
331- "attrs" : makeIcinga2ApiAttributes (service ),
332+ "attrs" : makeIcinga2ApiAttributes (service , false ),
332333 })
333334
334335 eventually .Assert (t , func (t require.TestingT ) {
@@ -387,7 +388,7 @@ func TestObjectSync(t *testing.T) {
387388 }, 20 * time .Second , 1 * time .Second , "service with name=%q should exist in database" , service .Name )
388389
389390 client .UpdateObject (t , "services" , * service .HostName + "!" + service .Name , map [string ]interface {}{
390- "attrs" : makeIcinga2ApiAttributes (service ),
391+ "attrs" : makeIcinga2ApiAttributes (service , true ),
391392 })
392393
393394 eventually .Assert (t , func (t require.TestingT ) {
@@ -426,7 +427,7 @@ func TestObjectSync(t *testing.T) {
426427 t .Parallel ()
427428
428429 client .CreateObject (t , "users" , user .Name , map [string ]interface {}{
429- "attrs" : makeIcinga2ApiAttributes (user ),
430+ "attrs" : makeIcinga2ApiAttributes (user , false ),
430431 })
431432
432433 eventually .Assert (t , func (t require.TestingT ) {
@@ -465,7 +466,7 @@ func TestObjectSync(t *testing.T) {
465466
466467 t .Run (user .VariantInfoString (), func (t * testing.T ) {
467468 client .UpdateObject (t , "users" , userName , map [string ]interface {}{
468- "attrs" : makeIcinga2ApiAttributes (user ),
469+ "attrs" : makeIcinga2ApiAttributes (user , true ),
469470 })
470471
471472 eventually .Assert (t , func (t require.TestingT ) {
@@ -488,7 +489,7 @@ func TestObjectSync(t *testing.T) {
488489 t .Parallel ()
489490
490491 client .CreateObject (t , "notifications" , notification .fullName (), map [string ]interface {}{
491- "attrs" : makeIcinga2ApiAttributes (notification ),
492+ "attrs" : makeIcinga2ApiAttributes (notification , false ),
492493 })
493494
494495 eventually .Assert (t , func (t require.TestingT ) {
@@ -520,7 +521,7 @@ func TestObjectSync(t *testing.T) {
520521 }
521522
522523 client .CreateObject (t , "notifications" , baseNotification .fullName (), map [string ]interface {}{
523- "attrs" : makeIcinga2ApiAttributes (baseNotification ),
524+ "attrs" : makeIcinga2ApiAttributes (baseNotification , false ),
524525 })
525526
526527 require .Eventuallyf (t , func () bool {
@@ -597,7 +598,7 @@ func TestObjectSync(t *testing.T) {
597598
598599 t .Run (notification .VariantInfoString (), func (t * testing.T ) {
599600 client .UpdateObject (t , "notifications" , notification .fullName (), map [string ]interface {}{
600- "attrs" : makeIcinga2ApiAttributes (notification ),
601+ "attrs" : makeIcinga2ApiAttributes (notification , true ),
601602 })
602603
603604 eventually .Assert (t , func (t require.TestingT ) {
@@ -743,7 +744,7 @@ func makeTestSyncHosts(t *testing.T) []Host {
743744type Service struct {
744745 Name string ` icingadb:"name"`
745746 DisplayName string `icinga2:"display_name" icingadb:"display_name"`
746- HostName * string `icinga2:"host_name" icingadb:"host.name"`
747+ HostName * string `icinga2:"host_name,nomodify" icingadb:"host.name"`
747748 CheckCommandName string `icinga2:"check_command" icingadb:"checkcommand_name"`
748749 MaxCheckAttempts float64 `icinga2:"max_check_attempts" icingadb:"max_check_attempts"`
749750 CheckPeriodName string `icinga2:"check_period" icingadb:"check_timeperiod_name"`
@@ -889,8 +890,8 @@ func makeTestUsers(t *testing.T) []User {
889890
890891type Notification struct {
891892 Name string ` icingadb:"name"`
892- HostName * string `icinga2:"host_name" icingadb:"host.name"`
893- ServiceName * string `icinga2:"service_name" icingadb:"service.name"`
893+ HostName * string `icinga2:"host_name,nomodify" icingadb:"host.name"`
894+ ServiceName * string `icinga2:"service_name,nomodify" icingadb:"service.name"`
894895 Command string `icinga2:"command" icingadb:"notificationcommand.name"`
895896 Times map [string ]string `icinga2:"times"`
896897 Interval int `icinga2:"interval" icingadb:"notification_interval"`
@@ -1061,7 +1062,9 @@ func writeIcinga2ConfigObject(w io.Writer, obj interface{}) error {
10611062 }
10621063
10631064 for fieldIndex := 0 ; fieldIndex < typ .NumField (); fieldIndex ++ {
1064- if attr := typ .Field (fieldIndex ).Tag .Get ("icinga2" ); attr != "" {
1065+ tag := typ .Field (fieldIndex ).Tag .Get ("icinga2" )
1066+ attr := strings .Split (tag , "," )[0 ]
1067+ if attr != "" {
10651068 if v := o .Field (fieldIndex ).Interface (); v != nil {
10661069 _ , err := fmt .Fprintf (w , "\t %s = %s\n " , attr , value .ToIcinga2Config (v ))
10671070 if err != nil {
@@ -1076,17 +1079,23 @@ func writeIcinga2ConfigObject(w io.Writer, obj interface{}) error {
10761079}
10771080
10781081// makeIcinga2ApiAttributes generates a map that can be JSON marshaled and passed to the icinga2 API
1079- // based on the type of obj and its field having icinga2 struct tags.
1080- func makeIcinga2ApiAttributes (obj interface {}) map [string ]interface {} {
1082+ // based on the type of obj and its field having icinga2 struct tags. Fields that are marked as "nomodify"
1083+ // (for example `icinga2:"host_name,nomodify"`) are omitted if the modify parameter is set to true.
1084+ func makeIcinga2ApiAttributes (obj interface {}, modify bool ) map [string ]interface {} {
10811085 attrs := make (map [string ]interface {})
10821086
10831087 o := reflect .ValueOf (obj )
10841088 typ := o .Type ()
10851089 for fieldIndex := 0 ; fieldIndex < typ .NumField (); fieldIndex ++ {
1086- if attr := typ .Field (fieldIndex ).Tag .Get ("icinga2" ); attr != "" {
1087- if val := o .Field (fieldIndex ).Interface (); val != nil {
1088- attrs [attr ] = value .ToIcinga2Api (val )
1089- }
1090+ tag := typ .Field (fieldIndex ).Tag .Get ("icinga2" )
1091+ parts := strings .Split (tag , "," )
1092+ attr := parts [0 ]
1093+ flags := parts [1 :]
1094+ if attr == "" || (modify && slices .Contains (flags , "nomodify" )) {
1095+ continue
1096+ }
1097+ if val := o .Field (fieldIndex ).Interface (); val != nil {
1098+ attrs [attr ] = value .ToIcinga2Api (val )
10901099 }
10911100 }
10921101
0 commit comments