@@ -79,7 +79,7 @@ func resourceElasticsearchOpenDistroDestinationCreate(d *schema.ResourceData, m
7979}
8080
8181func resourceElasticsearchOpenDistroDestinationRead (d * schema.ResourceData , m interface {}) error {
82- res , err := resourceElasticsearchOpenDistroGetDestination (d .Id (), m )
82+ destination , err := resourceElasticsearchOpenDistroQueryOrGetDestination (d .Id (), m )
8383
8484 if elastic6 .IsNotFound (err ) || elastic7 .IsNotFound (err ) {
8585 log .Printf ("[WARN] Destination (%s) not found, removing from state" , d .Id ())
@@ -91,7 +91,12 @@ func resourceElasticsearchOpenDistroDestinationRead(d *schema.ResourceData, m in
9191 return err
9292 }
9393
94- err = d .Set ("body" , res )
94+ body , err := json .Marshal (destination )
95+ if err != nil {
96+ return err
97+ }
98+
99+ err = d .Set ("body" , string (body ))
95100 return err
96101}
97102
@@ -137,39 +142,79 @@ func resourceElasticsearchOpenDistroDestinationDelete(d *schema.ResourceData, m
137142 return err
138143}
139144
140- func resourceElasticsearchOpenDistroGetDestination (destinationID string , m interface {}) (string , error ) {
141- var err error
142- response := new (destinationResponse )
143-
144- // See https://github.com/opendistro-for-elasticsearch/alerting/issues/56, no API endpoint for retrieving destination
145- var body * json.RawMessage
146- esClient , err := getClient (m .(* ProviderConf ))
147- if err != nil {
148- return "" , err
149- }
145+ func resourceElasticsearchOpenDistroGetDestination (destinationID string , esClient interface {}) (Destination , error ) {
150146 switch client := esClient .(type ) {
151147 case * elastic7.Client :
152- body , err = elastic7GetObject (client , DESTINATION_INDEX , destinationID )
153- case * elastic6.Client :
154- body , err = elastic6GetObject (client , DESTINATION_TYPE , DESTINATION_INDEX , destinationID )
148+ path , err := uritemplates .Expand ("/_opendistro/_alerting/destinations/{id}" , map [string ]string {
149+ "id" : destinationID ,
150+ })
151+ if err != nil {
152+ return Destination {}, fmt .Errorf ("error building URL path for destination: %+v" , err )
153+ }
154+
155+ httpResponse , err := client .PerformRequest (context .TODO (), elastic7.PerformRequestOptions {
156+ Method : "GET" ,
157+ Path : path ,
158+ })
159+ if err != nil {
160+ return Destination {}, err
161+ }
162+
163+ var drg destinationResponseGet
164+ if err := json .Unmarshal (httpResponse .Body , & drg ); err != nil {
165+ return Destination {}, fmt .Errorf ("error unmarshalling destination body: %+v" , err )
166+ }
167+ // The response structure from the API is the same for the index and get
168+ // endpoints :|, and different from the other endpoints. Normalize the
169+ // response here.
170+ if len (drg .Destinations ) > 0 {
171+ return drg .Destinations [0 ], nil
172+ } else {
173+ return Destination {}, fmt .Errorf ("endpoint returned empty set of destinations: %+v" , drg )
174+ }
155175 default :
156- err = errors .New ("destination resource not implemented prior to Elastic v6 " )
176+ return Destination {}, errors .New ("destination get api not implemented prior to ODFE 1.11.0 " )
157177 }
178+ }
158179
180+ func resourceElasticsearchOpenDistroQueryOrGetDestination (destinationID string , m interface {}) (Destination , error ) {
181+ esClient , err := getClient (m .(* ProviderConf ))
159182 if err != nil {
160- return "" , err
161- }
162-
163- if err := json .Unmarshal (* body , response ); err != nil {
164- return "" , fmt .Errorf ("error unmarshalling destination body: %+v: %+v" , err , body )
183+ return Destination {}, err
165184 }
166185
167- tj , err := json .Marshal (response .Destination )
168- if err != nil {
169- return "" , err
186+ var dr destinationResponse
187+ switch client := esClient .(type ) {
188+ case * elastic7.Client :
189+ // See https://github.com/opendistro-for-elasticsearch/alerting/issues/56,
190+ // no API endpoint for retrieving destination prior to ODFE 1.11.0. So do
191+ // a request, if it 404s, fall back to trying to query the index.
192+ destination , err := resourceElasticsearchOpenDistroGetDestination (destinationID , client )
193+ if err == nil {
194+ return destination , err
195+ } else {
196+ body , err := elastic7GetObject (client , DESTINATION_INDEX , destinationID )
197+
198+ if err != nil {
199+ return Destination {}, err
200+ }
201+ if err := json .Unmarshal (* body , & dr ); err != nil {
202+ return Destination {}, fmt .Errorf ("error unmarshalling destination body: %+v: %+v" , err , body )
203+ }
204+ return dr .Destination , nil
205+ }
206+ case * elastic6.Client :
207+ body , err := elastic6GetObject (client , DESTINATION_TYPE , DESTINATION_INDEX , destinationID )
208+ if err != nil {
209+ return Destination {}, err
210+ }
211+ if err := json .Unmarshal (* body , & dr ); err != nil {
212+ return Destination {}, fmt .Errorf ("error unmarshalling destination body: %+v: %+v" , err , body )
213+ }
214+ return dr .Destination , nil
215+ default :
216+ return Destination {}, errors .New ("destination resource not implemented prior to Elastic v6" )
170217 }
171-
172- return string (tj ), err
173218}
174219
175220func resourceElasticsearchOpenDistroPostDestination (d * schema.ResourceData , m interface {}) (* destinationResponse , error ) {
@@ -270,5 +315,23 @@ func resourceElasticsearchOpenDistroPutDestination(d *schema.ResourceData, m int
270315type destinationResponse struct {
271316 Version int `json:"_version"`
272317 ID string `json:"_id"`
273- Destination interface {} `json:"destination"`
318+ Destination Destination `json:"destination"`
319+ }
320+
321+ // When this api endpoint was introduced after the other endpoints, it has a
322+ // different response structure
323+ type destinationResponseGet struct {
324+ Total int `json:"totalDestinations"`
325+ Destinations []Destination `json:"destinations"`
326+ }
327+
328+ type Destination struct {
329+ ID string `json:"id"`
330+ Type string `json:"type"`
331+ Name string `json:"name"`
332+ Slack interface {} `json:"slack,omitempty"`
333+ CustomWebhook interface {} `json:"custom_webhook,omitempty"`
334+ Chime interface {} `json:"chime,omitempty"`
335+ SNS interface {} `json:"sns,omitempty"`
336+ Email interface {} `json:"email,omitempty"`
274337}
0 commit comments