44 "context"
55 "errors"
66 "fmt"
7+ "github.com/spectrocloud/palette-sdk-go/client"
78 "time"
89
910 "github.com/go-openapi/strfmt"
@@ -58,6 +59,18 @@ func resourceRegistryOciEcr() *schema.Resource {
5859 Required : true ,
5960 Description : "The URL endpoint of the OCI registry. This is where the container images are hosted and accessed." ,
6061 },
62+ "endpoint_suffix" : {
63+ Type : schema .TypeString ,
64+ Optional : true ,
65+ Default : "" ,
66+ Description : "Specifies a suffix to append to the endpoint. This field is optional, but some registries (e.g., JFrog) may require it. The final registry URL is constructed by appending this suffix to the endpoint." ,
67+ },
68+ "base_content_path" : {
69+ Type : schema .TypeString ,
70+ Optional : true ,
71+ Default : "" ,
72+ Description : "The relative path to the endpoint specified." ,
73+ },
6174 "provider_type" : {
6275 Type : schema .TypeString ,
6376 Optional : true ,
@@ -110,40 +123,94 @@ func resourceRegistryOciEcr() *schema.Resource {
110123 Sensitive : true ,
111124 Description : "The password for basic authentication. Required if 'credential_type' is 'basic'." ,
112125 },
126+ "tls_config" : {
127+ Type : schema .TypeList ,
128+ Optional : true ,
129+ MaxItems : 1 ,
130+ Description : "TLS configuration for the registry." ,
131+ Elem : & schema.Resource {
132+ Schema : map [string ]* schema.Schema {
133+ "certificate" : {
134+ Type : schema .TypeString ,
135+ Optional : true ,
136+ Default : "" ,
137+ Description : "Specifies the TLS certificate used for secure communication. Required for enabling SSL/TLS encryption." ,
138+ },
139+ "insecure_skip_verify" : {
140+ Type : schema .TypeBool ,
141+ Optional : true ,
142+ Default : false ,
143+ Description : "Disables TLS certificate verification when set to true. Use with caution as it may expose connections to security risks." ,
144+ },
145+ },
146+ },
147+ },
113148 },
114149 },
115150 },
116151 },
117152 CustomizeDiff : func (ctx context.Context , d * schema.ResourceDiff , meta interface {}) error {
118153 providerType := d .Get ("provider_type" ).(string )
119154 registryType := d .Get ("type" ).(string )
155+ isSync := d .Get ("is_synchronization" ).(bool )
120156 // Validate that `provider_type` is "zarf" only if `type` is "basic"
121157 if providerType == "zarf" && registryType != "basic" {
122158 return fmt .Errorf ("`provider_type` set to `zarf` is only allowed when `type` is `basic`" )
123159 }
160+ if providerType == "zarf" && isSync {
161+ return fmt .Errorf ("`provider_type` set to `zarf` is only allowed when `is_synchronization` is set to `false`" )
162+ }
163+ if providerType == "pack" && ! isSync {
164+ return fmt .Errorf ("`provider_type` set to `pack` is only allowed when `is_synchronization` is set to `true`" )
165+ }
124166 return nil
125167 },
126168 }
127169}
128170
171+ func validateRegistryCred (c * client.V1Client , registryType string , providerType string , isSync bool , basicSpec * models.V1BasicOciRegistrySpec , ecrSpec * models.V1EcrRegistrySpec ) error {
172+ if isSync && (providerType == "pack" || providerType == "helm" ) {
173+ switch registryType {
174+ case "basic" :
175+ if basicSpec != nil {
176+ if err := c .ValidateOciBasicRegistry (basicSpec ); err != nil {
177+ return err
178+ }
179+ }
180+ case "ecr" :
181+ if ecrSpec != nil {
182+ if err := c .ValidateOciEcrRegistry (ecrSpec ); err != nil {
183+ return err
184+ }
185+ }
186+ }
187+ }
188+ return nil
189+ }
190+
129191func resourceRegistryEcrCreate (ctx context.Context , d * schema.ResourceData , m interface {}) diag.Diagnostics {
130192 c := getV1ClientWithResourceContext (m , "tenant" )
131193 var diags diag.Diagnostics
132194
133195 registryType := d .Get ("type" ).(string )
134-
196+ providerType := d .Get ("provider_type" ).(string )
197+ isSync := d .Get ("is_synchronization" ).(bool )
135198 if registryType == "ecr" {
136199
137200 registry := toRegistryEcr (d )
138-
201+ if err := validateRegistryCred (c , registryType , providerType , isSync , nil , registry .Spec ); err != nil {
202+ return diag .FromErr (err )
203+ }
139204 uid , err := c .CreateOciEcrRegistry (registry )
140205 if err != nil {
141206 return diag .FromErr (err )
142207 }
143208 d .SetId (uid )
144209 } else if registryType == "basic" {
145210 registry := toRegistryBasic (d )
146-
211+ if err := validateRegistryCred (c , registryType , providerType , isSync , registry .Spec , nil ); err != nil {
212+ return diag .FromErr (err )
213+ }
147214 uid , err := c .CreateOciBasicRegistry (registry )
148215 if err != nil {
149216 return diag .FromErr (err )
@@ -180,31 +247,36 @@ func resourceRegistryEcrRead(ctx context.Context, d *schema.ResourceData, m inte
180247 if err := d .Set ("endpoint" , registry .Spec .Endpoint ); err != nil {
181248 return diag .FromErr (err )
182249 }
250+ if err := d .Set ("base_content_path" , registry .Spec .BaseContentPath ); err != nil {
251+ return diag .FromErr (err )
252+ }
253+ credentials := make ([]interface {}, 0 , 1 )
254+ acc := make (map [string ]interface {})
183255 switch registry .Spec .Credentials .CredentialType {
184256 case models .V1AwsCloudAccountCredentialTypeSts :
185- credentials := make ([]interface {}, 0 , 1 )
186- acc := make (map [string ]interface {})
187257 acc ["arn" ] = registry .Spec .Credentials .Sts .Arn
188258 acc ["external_id" ] = registry .Spec .Credentials .Sts .ExternalID
189259 acc ["credential_type" ] = models .V1AwsCloudAccountCredentialTypeSts
190- credentials = append (credentials , acc )
191- if err := d .Set ("credentials" , credentials ); err != nil {
192- return diag .FromErr (err )
193- }
194260 case models .V1AwsCloudAccountCredentialTypeSecret :
195- credentials := make ([]interface {}, 0 , 1 )
196- acc := make (map [string ]interface {})
197261 acc ["access_key" ] = registry .Spec .Credentials .AccessKey
198262 acc ["credential_type" ] = models .V1AwsCloudAccountCredentialTypeSecret
199- credentials = append (credentials , acc )
200- if err := d .Set ("credentials" , credentials ); err != nil {
201- return diag .FromErr (err )
202- }
203263 default :
204264 errMsg := fmt .Sprintf ("Registry type %s not implemented." , registry .Spec .Credentials .CredentialType )
205265 err = errors .New (errMsg )
206266 return diag .FromErr (err )
207267 }
268+ // tls configuration handling
269+ tlsConfig := make ([]interface {}, 0 , 1 )
270+ tls := make (map [string ]interface {})
271+ tls ["certificate" ] = registry .Spec .TLS .Certificate
272+ tls ["insecure_skip_verify" ] = registry .Spec .TLS .InsecureSkipVerify
273+ tlsConfig = append (tlsConfig , tls )
274+ acc ["tls_config" ] = tlsConfig
275+ credentials = append (credentials , acc )
276+
277+ if err := d .Set ("credentials" , credentials ); err != nil {
278+ return diag .FromErr (err )
279+ }
208280 return diags
209281
210282 } else if registryType == "basic" {
@@ -226,6 +298,27 @@ func resourceRegistryEcrRead(ctx context.Context, d *schema.ResourceData, m inte
226298 if err := d .Set ("provider_type" , registry .Spec .ProviderType ); err != nil {
227299 return diag .FromErr (err )
228300 }
301+ if err := d .Set ("base_content_path" , registry .Spec .BaseContentPath ); err != nil {
302+ return diag .FromErr (err )
303+ }
304+ if err := d .Set ("endpoint_suffix" , registry .Spec .BasePath ); err != nil {
305+ return diag .FromErr (err )
306+ }
307+ credentials := make ([]interface {}, 0 , 1 )
308+ acc := make (map [string ]interface {})
309+ acc ["username" ] = registry .Spec .Auth .Username
310+ acc ["password" ] = registry .Spec .Auth .Password
311+ // tls configuration handling
312+ tlsConfig := make ([]interface {}, 0 , 1 )
313+ tls := make (map [string ]interface {})
314+ tls ["certificate" ] = registry .Spec .Auth .TLS .Certificate
315+ tls ["insecure_skip_verify" ] = registry .Spec .Auth .TLS .InsecureSkipVerify
316+ tlsConfig = append (tlsConfig , tls )
317+ acc ["tls_config" ] = tlsConfig
318+ credentials = append (credentials , acc )
319+ if err := d .Set ("credentials" , credentials ); err != nil {
320+ return diag .FromErr (err )
321+ }
229322 return diags
230323 }
231324
@@ -237,15 +330,22 @@ func resourceRegistryEcrUpdate(ctx context.Context, d *schema.ResourceData, m in
237330 var diags diag.Diagnostics
238331
239332 registryType := d .Get ("type" ).(string )
240-
333+ providerType := d .Get ("provider_type" ).(string )
334+ isSync := d .Get ("is_synchronization" ).(bool )
241335 if registryType == "ecr" {
242336 registry := toRegistryEcr (d )
337+ if err := validateRegistryCred (c , registryType , providerType , isSync , nil , registry .Spec ); err != nil {
338+ return diag .FromErr (err )
339+ }
243340 err := c .UpdateOciEcrRegistry (d .Id (), registry )
244341 if err != nil {
245342 return diag .FromErr (err )
246343 }
247344 } else if registryType == "basic" {
248345 registry := toRegistryBasic (d )
346+ if err := validateRegistryCred (c , registryType , providerType , isSync , registry .Spec , nil ); err != nil {
347+ return diag .FromErr (err )
348+ }
249349 err := c .UpdateOciBasicRegistry (d .Id (), registry )
250350 if err != nil {
251351 return diag .FromErr (err )
@@ -280,7 +380,10 @@ func toRegistryEcr(d *schema.ResourceData) *models.V1EcrRegistry {
280380 isPrivate := d .Get ("is_private" ).(bool )
281381 isSynchronization := d .Get ("is_synchronization" ).(bool )
282382 providerType := d .Get ("provider_type" ).(string )
383+ baseContentPath := d .Get ("base_content_path" ).(string )
283384 s3config := d .Get ("credentials" ).([]interface {})[0 ].(map [string ]interface {})
385+ tlsCertificate := s3config ["tls_config" ].([]interface {})[0 ].(map [string ]interface {})["certificate" ].(string )
386+ tlsSkipVerify := s3config ["tls_config" ].([]interface {})[0 ].(map [string ]interface {})["insecure_skip_verify" ].(bool )
284387 return & models.V1EcrRegistry {
285388 Metadata : & models.V1ObjectMeta {
286389 Name : d .Get ("name" ).(string ),
@@ -291,6 +394,12 @@ func toRegistryEcr(d *schema.ResourceData) *models.V1EcrRegistry {
291394 IsPrivate : & isPrivate ,
292395 ProviderType : & providerType ,
293396 IsSyncSupported : isSynchronization ,
397+ BaseContentPath : baseContentPath ,
398+ TLS : & models.V1TLSConfiguration {
399+ Certificate : tlsCertificate ,
400+ Enabled : true ,
401+ InsecureSkipVerify : tlsSkipVerify ,
402+ },
294403 },
295404 }
296405}
@@ -299,8 +408,11 @@ func toRegistryBasic(d *schema.ResourceData) *models.V1BasicOciRegistry {
299408 endpoint := d .Get ("endpoint" ).(string )
300409 provider := d .Get ("provider_type" ).(string )
301410 isSynchronization := d .Get ("is_synchronization" ).(bool )
411+ endpointSuffix := d .Get ("endpoint_suffix" ).(string )
412+ baseContentPath := d .Get ("base_content_path" ).(string )
302413 authConfig := d .Get ("credentials" ).([]interface {})[0 ].(map [string ]interface {})
303-
414+ tlsCertificate := authConfig ["tls_config" ].([]interface {})[0 ].(map [string ]interface {})["certificate" ].(string )
415+ tlsSkipVerify := authConfig ["tls_config" ].([]interface {})[0 ].(map [string ]interface {})["insecure_skip_verify" ].(bool )
304416 var username , password string
305417
306418 username = authConfig ["username" ].(string )
@@ -312,15 +424,17 @@ func toRegistryBasic(d *schema.ResourceData) *models.V1BasicOciRegistry {
312424 },
313425 Spec : & models.V1BasicOciRegistrySpec {
314426 Endpoint : & endpoint ,
427+ BasePath : endpointSuffix ,
315428 ProviderType : & provider ,
316- BaseContentPath : "" ,
429+ BaseContentPath : baseContentPath ,
317430 Auth : & models.V1RegistryAuth {
318431 Username : username ,
319432 Password : strfmt .Password (password ),
320433 Type : "basic" ,
321434 TLS : & models.V1TLSConfiguration {
435+ Certificate : tlsCertificate ,
322436 Enabled : true ,
323- InsecureSkipVerify : false ,
437+ InsecureSkipVerify : tlsSkipVerify ,
324438 },
325439 },
326440 IsSyncSupported : isSynchronization ,
0 commit comments