66 "log"
77 "strings"
88
9- gapi "github.com/grafana/grafana-api-golang-client"
9+ "github.com/grafana/grafana-openapi-client-go/client/provisioning"
10+ "github.com/grafana/grafana-openapi-client-go/models"
1011 "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
1112 "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1213
@@ -46,7 +47,7 @@ Manages Grafana Alerting contact points.
4647
4748This resource requires Grafana 9.1.0 or later.
4849` ,
49- CreateContext : createContactPoint ,
50+ CreateContext : updateContactPoint ,
5051 ReadContext : readContactPoint ,
5152 UpdateContext : updateContactPoint ,
5253 DeleteContext : deleteContactPoint ,
@@ -86,12 +87,14 @@ This resource requires Grafana 9.1.0 or later.
8687
8788func importContactPoint (ctx context.Context , data * schema.ResourceData , meta interface {}) ([]* schema.ResourceData , error ) {
8889 name := data .Id ()
89- client := meta .( * common. Client ). DeprecatedGrafanaAPI
90+ client := OAPIGlobalClient ( meta ) // TODO: Support org-scoped contact points
9091
91- ps , err := client .ContactPointsByName (name )
92+ params := provisioning .NewGetContactpointsParams ().WithName (& name )
93+ resp , err := client .Provisioning .GetContactpoints (params )
9294 if err != nil {
9395 return nil , err
9496 }
97+ ps := resp .Payload
9598
9699 if len (ps ) == 0 {
97100 return nil , fmt .Errorf ("no contact points with the given name were found to import" )
@@ -107,25 +110,30 @@ func importContactPoint(ctx context.Context, data *schema.ResourceData, meta int
107110}
108111
109112func readContactPoint (ctx context.Context , data * schema.ResourceData , meta interface {}) diag.Diagnostics {
110- client := meta .( * common. Client ). DeprecatedGrafanaAPI
113+ client := OAPIGlobalClient ( meta ) // TODO: Support org-scoped contact points
111114
112115 uidsToFetch := unpackUIDs (data .Id ())
113116
114- points := []gapi.ContactPoint {}
117+ resp , err := client .Provisioning .GetContactpoints (nil )
118+ if err != nil {
119+ return diag .FromErr (err )
120+ }
121+ contactPointByUID := map [string ]* models.EmbeddedContactPoint {}
122+ for _ , p := range resp .Payload {
123+ contactPointByUID [p .UID ] = p
124+ }
125+
126+ points := []* models.EmbeddedContactPoint {}
115127 for _ , uid := range uidsToFetch {
116- p , err := client .ContactPoint (uid )
117- if err != nil {
118- if strings .HasPrefix (err .Error (), "status: 404" ) || strings .Contains (err .Error (), "not found" ) {
119- log .Printf ("[WARN] removing contact point %s from state because it no longer exists in grafana" , uid )
120- continue
121- }
122- return diag .FromErr (err )
128+ p , ok := contactPointByUID [uid ]
129+ if ! ok {
130+ log .Printf ("[WARN] removing contact point %s from state because it no longer exists in grafana" , uid )
131+ continue
123132 }
124133 points = append (points , p )
125134 }
126135
127- err := packContactPoints (points , data )
128- if err != nil {
136+ if err := packContactPoints (points , data ); err != nil {
129137 return diag .FromErr (err )
130138 }
131139 uids := make ([]string , 0 , len (points ))
@@ -137,51 +145,28 @@ func readContactPoint(ctx context.Context, data *schema.ResourceData, meta inter
137145 return nil
138146}
139147
140- func createContactPoint (ctx context.Context , data * schema.ResourceData , meta interface {}) diag.Diagnostics {
148+ func updateContactPoint (ctx context.Context , data * schema.ResourceData , meta interface {}) diag.Diagnostics {
141149 lock := & meta .(* common.Client ).AlertingMutex
142- client := meta .(* common.Client ).DeprecatedGrafanaAPI
143-
144- ps := unpackContactPoints (data )
145- uids := make ([]string , 0 , len (ps ))
146-
147150 lock .Lock ()
148151 defer lock .Unlock ()
149- for i := range ps {
150- p := ps [i ]
151- uid , err := client .NewContactPoint (& p .gfState )
152- if err != nil {
153- return diag .FromErr (err )
154- }
155- uids = append (uids , uid )
156-
157- // Since this is a new resource, the proposed state won't have a UID.
158- // We need the UID so that we can later associate it with the config returned in the api response.
159- p .tfState ["uid" ] = uid
160- }
161-
162- data .SetId (packUIDs (uids ))
163- return readContactPoint (ctx , data , meta )
164- }
165-
166- func updateContactPoint (ctx context.Context , data * schema.ResourceData , meta interface {}) diag.Diagnostics {
167- lock := & meta .(* common.Client ).AlertingMutex
168- client := meta .(* common.Client ).DeprecatedGrafanaAPI
152+ client := OAPIGlobalClient (meta ) // TODO: Support org-scoped contact points
169153
170154 existingUIDs := unpackUIDs (data .Id ())
171155 ps := unpackContactPoints (data )
172156
173157 unprocessedUIDs := toUIDSet (existingUIDs )
174158 newUIDs := make ([]string , 0 , len (ps ))
175- lock .Lock ()
176- defer lock .Unlock ()
177159 for i := range ps {
178160 p := ps [i ].gfState
179161 delete (unprocessedUIDs , p .UID )
180- err := client .UpdateContactPoint (& p )
162+ params := provisioning .NewPutContactpointParams ().WithUID (p .UID ).WithBody (p )
163+ _ , err := client .Provisioning .PutContactpoint (params )
181164 if err != nil {
182- if strings .HasPrefix (err .Error (), "status: 404" ) {
183- uid , err := client .NewContactPoint (& p )
184- newUIDs = append (newUIDs , uid )
165+ if common .IsNotFoundError (err ) {
166+ params := provisioning .NewPostContactpointsParams ().WithBody (p )
167+ resp , err := client .Provisioning .PostContactpoints (params )
168+ ps [i ].tfState ["uid" ] = resp .Payload .UID
169+ newUIDs = append (newUIDs , resp .Payload .UID )
185170 if err != nil {
186171 return diag .FromErr (err )
187172 }
@@ -195,7 +180,7 @@ func updateContactPoint(ctx context.Context, data *schema.ResourceData, meta int
195180 // Any UIDs still left in the state that we haven't seen must map to deleted receivers.
196181 // Delete them on the server and drop them from state.
197182 for u := range unprocessedUIDs {
198- if err := client .DeleteContactPoint (u ); err != nil {
183+ if _ , err := client .Provisioning . DeleteContactpoints (u ); err != nil {
199184 return diag .FromErr (err )
200185 }
201186 }
@@ -207,14 +192,14 @@ func updateContactPoint(ctx context.Context, data *schema.ResourceData, meta int
207192
208193func deleteContactPoint (ctx context.Context , data * schema.ResourceData , meta interface {}) diag.Diagnostics {
209194 lock := & meta .(* common.Client ).AlertingMutex
210- client := meta .(* common.Client ).DeprecatedGrafanaAPI
195+ lock .Lock ()
196+ defer lock .Unlock ()
197+ client := OAPIGlobalClient (meta ) // TODO: Support org-scoped contact points
211198
212199 uids := unpackUIDs (data .Id ())
213200
214- lock .Lock ()
215- defer lock .Unlock ()
216201 for _ , uid := range uids {
217- if err := client .DeleteContactPoint (uid ); err != nil {
202+ if _ , err := client .Provisioning . DeleteContactpoints (uid ); err != nil {
218203 return diag .FromErr (err )
219204 }
220205 }
@@ -239,24 +224,25 @@ func unpackContactPoints(data *schema.ResourceData) []statePair {
239224 return result
240225}
241226
242- func unpackPointConfig (n notifier , data interface {}, name string ) gapi. ContactPoint {
227+ func unpackPointConfig (n notifier , data interface {}, name string ) * models. EmbeddedContactPoint {
243228 pt := n .unpack (data , name )
229+ settings := pt .Settings .(map [string ]interface {})
244230 // Treat settings like `omitempty`. Workaround for versions affected by https://github.com/grafana/grafana/issues/55139
245- for k , v := range pt . Settings {
231+ for k , v := range settings {
246232 if v == "" {
247- delete (pt . Settings , k )
233+ delete (settings , k )
248234 }
249235 }
250236 return pt
251237}
252238
253- func packContactPoints (ps []gapi. ContactPoint , data * schema.ResourceData ) error {
239+ func packContactPoints (ps []* models. EmbeddedContactPoint , data * schema.ResourceData ) error {
254240 pointsPerNotifier := map [notifier ][]interface {}{}
255241 for _ , p := range ps {
256242 data .Set ("name" , p .Name )
257243
258244 for _ , n := range notifiers {
259- if p .Type == n .meta ().typeStr {
245+ if * p .Type == n .meta ().typeStr {
260246 packed , err := n .pack (p , data )
261247 if err != nil {
262248 return err
@@ -278,16 +264,16 @@ func unpackCommonNotifierFields(raw map[string]interface{}) (string, bool, map[s
278264 return raw ["uid" ].(string ), raw ["disable_resolve_message" ].(bool ), raw ["settings" ].(map [string ]interface {})
279265}
280266
281- func packCommonNotifierFields (p * gapi. ContactPoint ) map [string ]interface {} {
267+ func packCommonNotifierFields (p * models. EmbeddedContactPoint ) map [string ]interface {} {
282268 return map [string ]interface {}{
283269 "uid" : p .UID ,
284270 "disable_resolve_message" : p .DisableResolveMessage ,
285271 }
286272}
287273
288- func packSettings (p * gapi. ContactPoint ) map [string ]interface {} {
274+ func packSettings (p * models. EmbeddedContactPoint ) map [string ]interface {} {
289275 settings := map [string ]interface {}{}
290- for k , v := range p .Settings {
276+ for k , v := range p .Settings .( map [ string ] interface {}) {
291277 settings [k ] = fmt .Sprintf ("%#v" , v )
292278 }
293279 return settings
@@ -342,8 +328,8 @@ func toUIDSet(uids []string) map[string]bool {
342328type notifier interface {
343329 meta () notifierMeta
344330 schema () * schema.Resource
345- pack (p gapi. ContactPoint , data * schema.ResourceData ) (interface {}, error )
346- unpack (raw interface {}, name string ) gapi. ContactPoint
331+ pack (p * models. EmbeddedContactPoint , data * schema.ResourceData ) (interface {}, error )
332+ unpack (raw interface {}, name string ) * models. EmbeddedContactPoint
347333}
348334
349335type notifierMeta struct {
@@ -355,7 +341,7 @@ type notifierMeta struct {
355341
356342type statePair struct {
357343 tfState map [string ]interface {}
358- gfState gapi. ContactPoint
344+ gfState * models. EmbeddedContactPoint
359345}
360346
361347func packNotifierStringField (gfSettings , tfSettings * map [string ]interface {}, gfKey , tfKey string ) {
0 commit comments