66 "strings"
77
88 "github.com/Bonial-International-GmbH/terraform-provider-spinnaker/spinnaker/api"
9- "github.com/Bonial-International-GmbH/terraform-provider-spinnaker/spinnaker/api/errors"
9+ apierrors "github.com/Bonial-International-GmbH/terraform-provider-spinnaker/spinnaker/api/errors"
1010 "github.com/hashicorp/terraform-plugin-sdk/helper/schema"
1111)
1212
@@ -57,11 +57,9 @@ func resourcePipelineCreate(data *schema.ResourceData, meta interface{}) error {
5757
5858 applicationName := data .Get ("application" ).(string )
5959 pipelineName := data .Get ("name" ).(string )
60- rawPipeline := [] byte ( data .Get ("pipeline" ).(string ) )
60+ rawPipeline := data .Get ("pipeline" ).(string )
6161
62- var pipeline map [string ]interface {}
63-
64- err = json .Unmarshal (rawPipeline , & pipeline )
62+ pipeline , err := parsePipeline (rawPipeline )
6563 if err != nil {
6664 return err
6765 }
@@ -71,12 +69,13 @@ func resourcePipelineCreate(data *schema.ResourceData, meta interface{}) error {
7169 delete (pipeline , "id" )
7270
7371 err = api .CreatePipeline (client , pipeline )
74- if errors .IsPipelineAlreadyExists (err ) {
72+ if apierrors .IsPipelineAlreadyExists (err ) {
7573 err = api .RecreatePipeline (client , applicationName , pipelineName , pipeline )
7674 }
7775
7876 if err != nil {
79- return err
77+ return fmt .Errorf ("failed to create pipeline %q for application %q: %w" ,
78+ pipelineName , applicationName , err )
8079 }
8180
8281 return resourcePipelineRead (data , meta )
@@ -94,24 +93,23 @@ func resourcePipelineRead(data *schema.ResourceData, meta interface{}) error {
9493 pipelineName := data .Get ("name" ).(string )
9594
9695 var p pipelineRead
97- jsonMap , err := api .GetPipeline (client , applicationName , pipelineName , & p )
98- if err != nil {
99- return err
96+
97+ pipeline , err := api .GetPipeline (client , applicationName , pipelineName , & p )
98+ if apierrors .IsNotFound (err ) {
99+ data .SetId ("" )
100+ return nil
101+ } else if err != nil {
102+ return fmt .Errorf ("failed to fetch pipeline %q for application %q: %w" ,
103+ pipelineName , applicationName , err )
100104 }
101105
102- pipeline , err := editAndEncodePipeline (jsonMap )
106+ encodedPipeline , err := editAndEncodePipeline (pipeline )
103107 if err != nil {
104108 return err
105109 }
106- err = data .Set ("pipeline" , pipeline )
107- if err != nil {
108- return fmt .Errorf ("Could not set pipeline for pipeline %s: %s" , pipelineName , err )
109- }
110110
111- err = data .Set ("pipeline_id" , p .ID )
112- if err != nil {
113- return fmt .Errorf ("Could not set pipeline_id for pipeline %s: %s" , pipelineName , err )
114- }
111+ data .Set ("pipeline" , encodedPipeline )
112+ data .Set ("pipeline_id" , p .ID )
115113 data .SetId (p .ID )
116114
117115 return nil
@@ -127,33 +125,28 @@ func resourcePipelineUpdate(data *schema.ResourceData, meta interface{}) error {
127125
128126 applicationName := data .Get ("application" ).(string )
129127 pipelineName := data .Get ("name" ).(string )
130- rawPipeline := []byte (data .Get ("pipeline" ).(string ))
131-
132- pipelineID , ok := data .GetOk ("pipeline_id" )
133- if ! ok {
134- return fmt .Errorf ("No pipeline_id found to pipeline in %s with name %s" , applicationName , pipelineName )
135- }
128+ pipelineID := data .Get ("pipeline_id" ).(string )
129+ rawPipeline := data .Get ("pipeline" ).(string )
136130
137- var pipeline map [string ]interface {}
138-
139- err = json .Unmarshal (rawPipeline , & pipeline )
131+ pipeline , err := parsePipeline (rawPipeline )
140132 if err != nil {
141- return fmt . Errorf ( "could not unmarshal pipeline" )
133+ return err
142134 }
143135
144136 pipeline ["application" ] = applicationName
145137 pipeline ["name" ] = pipelineName
146- pipeline ["id" ] = pipelineID .( string )
138+ pipeline ["id" ] = pipelineID
147139
148- err = api .UpdatePipeline (client , pipelineID .( string ) , pipeline )
149- if errors .IsPipelineAlreadyExists (err ) {
140+ err = api .UpdatePipeline (client , pipelineID , pipeline )
141+ if apierrors .IsPipelineAlreadyExists (err ) {
150142 // Although it seems odd, this error can happen here due to the hideous
151143 // spinnaker API. We handle it by just recreating the pipeline.
152144 err = api .RecreatePipeline (client , applicationName , pipelineName , pipeline )
153145 }
154146
155147 if err != nil {
156- return err
148+ return fmt .Errorf ("failed to update pipeline %q for application %q: %w" ,
149+ pipelineName , applicationName , err )
157150 }
158151
159152 return resourcePipelineRead (data , meta )
@@ -170,8 +163,10 @@ func resourcePipelineDelete(data *schema.ResourceData, meta interface{}) error {
170163 applicationName := data .Get ("application" ).(string )
171164 pipelineName := data .Get ("name" ).(string )
172165
173- if err := api .DeletePipeline (client , applicationName , pipelineName ); err != nil {
174- return err
166+ err = api .DeletePipeline (client , applicationName , pipelineName )
167+ if err != nil && ! apierrors .IsNotFound (err ) {
168+ return fmt .Errorf ("failed to delete pipeline %q for application %q: %w" ,
169+ pipelineName , applicationName , err )
175170 }
176171
177172 return nil
@@ -189,12 +184,16 @@ func resourcePipelineExists(data *schema.ResourceData, meta interface{}) (bool,
189184 pipelineName := data .Get ("name" ).(string )
190185
191186 var p pipelineRead
192- if _ , err := api .GetPipeline (client , applicationName , pipelineName , & p ); err != nil && ! strings .Contains (err .Error (), "EOF" ) {
193- return false , err
194- }
195187
196- if p .Name == "" {
197- return false , nil
188+ _ , err = api .GetPipeline (client , applicationName , pipelineName , & p )
189+ if err != nil {
190+ // Weird error case: sometimes spinnaker returns an EOF error for non-existing pipelines.
191+ if apierrors .IsNotFound (err ) || strings .Contains (err .Error (), "EOF" ) {
192+ return false , nil
193+ }
194+
195+ return false , fmt .Errorf ("failed to fetch pipeline %q for application %q: %w" ,
196+ pipelineName , applicationName , err )
198197 }
199198
200199 return true , nil
@@ -217,37 +216,39 @@ func pipelineDiffSuppressFunc(k, old, new string, d *schema.ResourceData) bool {
217216 return editedOld == editedNew
218217}
219218
220- func decodeEditAndEncodePipeline (pipeline string ) (encodedPipeline string , err error ) {
221- // Decode the pipeline into a map we can edit
222- pipelineBytes := []byte (pipeline )
223- var pipelineMapGeneric interface {}
224- err = json .Unmarshal (pipelineBytes , & pipelineMapGeneric )
225- if err != nil {
226- return
219+ func parsePipeline (rawPipeline string ) (map [string ]interface {}, error ) {
220+ var pipeline map [string ]interface {}
221+
222+ if err := json .Unmarshal ([]byte (rawPipeline ), & pipeline ); err != nil {
223+ return nil , fmt .Errorf ("invalid pipeline json: %w" , err )
227224 }
228225
229- pipelineMap := pipelineMapGeneric .(map [string ]interface {})
226+ return pipeline , nil
227+ }
230228
231- return editAndEncodePipeline (pipelineMap )
229+ func decodeEditAndEncodePipeline (rawPipeline string ) (string , error ) {
230+ pipeline , err := parsePipeline (rawPipeline )
231+ if err != nil {
232+ return "" , err
233+ }
234+
235+ return editAndEncodePipeline (pipeline )
232236}
233237
234- func editAndEncodePipeline (pipelineMap map [string ]interface {}) (encodedPipeline string , err error ) {
238+ func editAndEncodePipeline (pipeline map [string ]interface {}) (string , error ) {
235239 // Remove the keys we know are problematic because they are managed
236240 // by spinnaker or are handled by other schema attributes.
237- delete (pipelineMap , "application" )
238- delete (pipelineMap , "lastModifiedBy" )
239- delete (pipelineMap , "id" )
240- delete (pipelineMap , "index" )
241- delete (pipelineMap , "name" )
242- delete (pipelineMap , "updateTs" )
243-
244- // Encode the pipeline into a single string
245- // This will sort all keys, etc.
246- editedPipelineBytes , err := json .Marshal (pipelineMap )
241+ delete (pipeline , "application" )
242+ delete (pipeline , "lastModifiedBy" )
243+ delete (pipeline , "id" )
244+ delete (pipeline , "index" )
245+ delete (pipeline , "name" )
246+ delete (pipeline , "updateTs" )
247+
248+ encoded , err := json .Marshal (pipeline )
247249 if err != nil {
248- return
250+ return "" , fmt . Errorf ( "failed to marshal pipeline: %w" , err )
249251 }
250252
251- encodedPipeline = string (editedPipelineBytes )
252- return
253+ return string (encoded ), nil
253254}
0 commit comments