@@ -10,6 +10,7 @@ import (
1010
1111 "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1212 "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
13+ "github.com/nsf/jsondiff"
1314
1415 elastic7 "github.com/olivere/elastic/v7"
1516 elastic6 "gopkg.in/olivere/elastic.v6"
@@ -355,7 +356,6 @@ var (
355356 Type : schema .TypeString ,
356357 Description : "A JSON string defining how documents in the index, and the fields they contain, are stored and indexed. To avoid the complexities of field mapping updates, updates of this field are not allowed via this provider. See the upstream [Elasticsearch docs](https://www.elastic.co/guide/en/elasticsearch/reference/6.8/indices-put-mapping.html#updating-field-mappings) for more details." ,
357358 Optional : true ,
358- ForceNew : true ,
359359 ValidateFunc : validation .StringIsJSON ,
360360 },
361361 "aliases" : {
@@ -670,52 +670,92 @@ func allowIndexDestroy(indexName string, d *schema.ResourceData, meta interface{
670670}
671671
672672func resourceElasticsearchIndexUpdate (d * schema.ResourceData , meta interface {}) error {
673- settings := make (map [string ]interface {})
674- for _ , key := range settingsKeys {
675- schemaName := strings .Replace (key , "." , "_" , - 1 )
676- if d .HasChange (schemaName ) {
677- settings [key ] = d .Get (schemaName )
678- }
679- }
680-
681- // if we're not changing any settings, no-op this function
682- if len (settings ) == 0 {
683- return resourceElasticsearchIndexRead (d , meta )
684- }
685-
686- body := map [string ]interface {}{
687- // Note you do not have to explicitly specify the `index` section inside
688- // the `settings` section
689- "settings" : settings ,
690- }
691-
692- var (
693- name = d .Id ()
694- ctx = context .Background ()
695- err error
696- )
673+ var err error
674+ settings := make (map [string ]interface {})
675+ for _ , key := range settingsKeys {
676+ schemaName := strings .Replace (key , "." , "_" , - 1 )
677+ if d .HasChange (schemaName ) {
678+ settings [key ] = d .Get (schemaName )
679+ }
680+ }
681+
682+ o , n := d .GetChange ("mappings" )
683+ difference , _ := jsondiff .Compare ([]byte (n .(string )), []byte (o .(string )), & jsondiff.Options {})
684+
685+ // if we're not changing any settings, no-op this function
686+ if len (settings ) == 0 && difference == jsondiff .FullMatch {
687+ return resourceElasticsearchIndexRead (d , meta )
688+ }
689+
690+ if len (settings ) != 0 {
691+ err = updateIndexSettings (d , meta , settings )
692+ }
693+ if err != nil {
694+ return err
695+ }
696+
697+ if difference == jsondiff .SupersetMatch {
698+ err = updateIndexMappings (d , meta , n .(string ))
699+ }
700+ if err != nil {
701+ return err
702+ }
703+
704+ return resourceElasticsearchIndexRead (d , meta .(* ProviderConf ))
705+ }
697706
698- if alias , ok := d .GetOk ("rollover_alias" ); ok {
699- name = getWriteIndexByAlias (alias .(string ), d , meta )
700- }
707+ func updateIndexSettings (d * schema.ResourceData , meta interface {}, settings map [string ]interface {}) error {
708+ body := map [string ]interface {}{
709+ // Note you do not have to explicitly specify the `index` section inside
710+ // the `settings` section
711+ "settings" : settings ,
712+ }
713+
714+ var (
715+ name = d .Id ()
716+ ctx = context .Background ()
717+ err error
718+ )
719+
720+ if alias , ok := d .GetOk ("rollover_alias" ); ok {
721+ name = getWriteIndexByAlias (alias .(string ), d , meta )
722+ }
723+
724+ esClient , err := getClient (meta .(* ProviderConf ))
725+ if err != nil {
726+ return err
727+ }
728+ switch client := esClient .(type ) {
729+ case * elastic7.Client :
730+ _ , err = client .IndexPutSettings (name ).BodyJson (body ).Do (ctx )
731+ case * elastic6.Client :
732+ _ , err = client .IndexPutSettings (name ).BodyJson (body ).Do (ctx )
733+ default :
734+ return errors .New ("Elasticsearch version not supported" )
735+ }
736+ return err
737+ }
701738
702- esClient , err := getClient (meta .(* ProviderConf ))
703- if err != nil {
704- return err
705- }
706- switch client := esClient .(type ) {
707- case * elastic7.Client :
708- _ , err = client .IndexPutSettings (name ).BodyJson (body ).Do (ctx )
709- case * elastic6.Client :
710- _ , err = client .IndexPutSettings (name ).BodyJson (body ).Do (ctx )
711- default :
712- return errors .New ("Elasticsearch version not supported" )
713- }
739+ func updateIndexMappings (d * schema.ResourceData , meta interface {}, mapping string ) error {
740+ var (
741+ name = d .Id ()
742+ ctx = context .Background ()
743+ err error
744+ )
745+ esClient , err := getClient (meta .(* ProviderConf ))
746+ if err != nil {
747+ return err
748+ }
749+ switch client := esClient .(type ) {
750+ case * elastic7.Client :
751+ _ , err = client .PutMapping ().Index (name ).BodyString (mapping ).Do (ctx )
752+ case * elastic6.Client :
753+ _ , err = client .PutMapping ().Index (name ).BodyString (mapping ).Do (ctx )
754+ default :
755+ return errors .New ("Elasticsearch version not supported" )
756+ }
714757
715- if err == nil {
716- return resourceElasticsearchIndexRead (d , meta .(* ProviderConf ))
717- }
718- return err
758+ return err
719759}
720760
721761func getWriteIndexByAlias (alias string , d * schema.ResourceData , meta interface {}) string {
0 commit comments