@@ -27,6 +27,7 @@ import (
2727 "fmt"
2828 "io"
2929 "net/http"
30+ "slices"
3031 "time"
3132)
3233
@@ -235,3 +236,108 @@ func (c *Client) EnableIntegrationsServer(ctx context.Context) error {
235236
236237 return nil
237238}
239+
240+ func (c * Client ) ResolveMigrationDeprecations (ctx context.Context ) error {
241+ ctx , cancel := context .WithTimeout (ctx , 30 * time .Second )
242+ defer cancel ()
243+
244+ deprecations , err := c .QueryCriticalESDeprecations (ctx )
245+ if err != nil {
246+ return fmt .Errorf ("failed to query critical deprecations: %w" , err )
247+ }
248+
249+ for _ , deprecation := range deprecations {
250+ switch deprecation .Type {
251+ case "index_settings" :
252+ if err = c .markIndexAsReadOnly (ctx , deprecation .Name ); err != nil {
253+ return fmt .Errorf ("failed to mark index as read-only: %w" , err )
254+ }
255+ case "data_streams" :
256+ if err = c .markDataStreamAsReadOnly (
257+ ctx ,
258+ deprecation .Name ,
259+ deprecation .CorrectiveAction .Metadata .IndicesRequiringUpgrade ,
260+ ); err != nil {
261+ return fmt .Errorf ("failed to mark data stream as read-only: %w" , err )
262+ }
263+ default :
264+ return fmt .Errorf ("unknown deprecation type: %s" , deprecation .Type )
265+ }
266+ }
267+
268+ return nil
269+ }
270+
271+ type MigrationDeprecation struct {
272+ Name string `json:"index"`
273+ Type string `json:"type"`
274+ IsCritical bool `json:"isCritical"`
275+ CorrectiveAction struct {
276+ Type string `json:"type"`
277+ Metadata struct {
278+ IndicesRequiringUpgrade []string `json:"indicesRequiringUpgrade,omitempty"`
279+ }
280+ } `json:"correctiveAction"`
281+ }
282+
283+ type esDeprecationsResponse struct {
284+ MigrationDeprecations []MigrationDeprecation `json:"migrationsDeprecations"`
285+ }
286+
287+ // QueryCriticalESDeprecations retrieves the critical deprecation warnings for Elasticsearch.
288+ // It is essentially equivalent to `GET _migration/deprecations`, but through Kibana Upgrade
289+ // Assistant API.
290+ func (c * Client ) QueryCriticalESDeprecations (ctx context.Context ) ([]MigrationDeprecation , error ) {
291+ path := "/api/upgrade_assistant/es_deprecations"
292+ b , err := c .sendRequest (ctx , http .MethodGet , path , nil , nil )
293+ if err != nil {
294+ return nil , err
295+ }
296+
297+ var esDeprecationsResp esDeprecationsResponse
298+ if err = json .Unmarshal (b , & esDeprecationsResp ); err != nil {
299+ return nil , fmt .Errorf ("cannot unmarshal response body: %w" , err )
300+ }
301+
302+ // Remove all non-critical deprecation info.
303+ return slices .DeleteFunc (
304+ esDeprecationsResp .MigrationDeprecations ,
305+ func (dep MigrationDeprecation ) bool {
306+ return ! dep .IsCritical
307+ },
308+ ), nil
309+ }
310+
311+ type upgradeAssistUpdateIndexRequest struct {
312+ Operations []string `json:"operations"`
313+ }
314+
315+ // markIndexAsReadOnly updates the index to read-only through the Upgrade Assistant API:
316+ // https://www.elastic.co/guide/en/kibana/current/upgrade-assistant.html.
317+ func (c * Client ) markIndexAsReadOnly (ctx context.Context , index string ) error {
318+ path := fmt .Sprintf ("/api/upgrade_assistant/update_index/%s" , index )
319+ req := upgradeAssistUpdateIndexRequest {
320+ Operations : []string {"blockWrite" , "unfreeze" },
321+ }
322+
323+ _ , err := c .sendRequest (ctx , http .MethodPost , path , req , nil )
324+ return err
325+ }
326+
327+ type upgradeAssistMigrateDSRequest struct {
328+ Indices []string `json:"indices"`
329+ }
330+
331+ // markDataStreamAsReadOnly marks the backing indices of the data stream as read-only
332+ // through the Upgrade Assistant API:
333+ // https://www.elastic.co/guide/en/kibana/current/upgrade-assistant.html.
334+ func (c * Client ) markDataStreamAsReadOnly (ctx context.Context , dataStream string , indices []string ) error {
335+ // Data stream
336+ path := fmt .Sprintf ("/api/upgrade_assistant/migrate_data_stream/%s/readonly" , dataStream )
337+ req := upgradeAssistMigrateDSRequest {
338+ Indices : indices ,
339+ }
340+
341+ _ , err := c .sendRequest (ctx , http .MethodPost , path , req , nil )
342+ return err
343+ }
0 commit comments