Skip to content

Commit

Permalink
feat: add support to use custom image name in GCP (#74)
Browse files Browse the repository at this point in the history
  • Loading branch information
sternik authored Oct 14, 2024
1 parent badeb01 commit 9ba4ba5
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 2 deletions.
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ terraform {
required_providers {
imagefactory = {
source = "nordcloud/imagefactory"
version = "1.10.0"
version = "1.11.0"
}
}
}
Expand Down
36 changes: 36 additions & 0 deletions docs/resources/template.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,33 @@ resource "imagefactory_template" "exoscale_template" {
output "template" {
value = imagefactory_template.exoscale_template
}
# GCP Template
data "imagefactory_distribution" "ubuntu22" {
name = "Ubuntu Server 22.04 LTS"
cloud_provider = "GCP"
}
resource "imagefactory_template" "gcp_template" {
name = "Ubuntu2204"
description = "Ubuntu Server 22.04 on GCP"
cloud_provider = "GCP"
distribution_id = data.imagefactory_distribution.ubuntu22.id
config {
gcp {
custom_image_name = "ubuntu-22-04-prod-1-3"
}
notifications {
type = "WEB_HOOK"
uri = "https://webhook.call.api.address"
}
}
}
output "template" {
value = imagefactory_template.gcp_template
}
```

<!-- schema generated by tfplugindocs -->
Expand Down Expand Up @@ -301,6 +328,7 @@ Optional:
- `cloud_account_ids` (List of String)
- `disable_cyclical_rebuilds` (Boolean) Disable cyclical rebuilds. Cyclical rebuilds are rebuilds that are triggered automatically by ImageFactory when the source image is updated or when there are security updates available for the packages installed in the image. If cyclical rebuilds are disabled, the template will not be rebuilt automatically and the user will have to trigger the rebuild manually. Default value is set to false.
- `exoscale` (Block List) (see [below for nested schema](#nestedblock--config--exoscale))
- `gcp` (Block List) (see [below for nested schema](#nestedblock--config--gcp))
- `notifications` (Block List) (see [below for nested schema](#nestedblock--config--notifications))
- `scope` (String)
- `tags` (Block List) (see [below for nested schema](#nestedblock--config--tags))
Expand Down Expand Up @@ -382,6 +410,14 @@ Required:
- `zone` (String)


<a id="nestedblock--config--gcp"></a>
### Nested Schema for `config.gcp`

Optional:

- `custom_image_name` (String) The name of the custom image. Must be a valid custom image name. The name must start with a lowercase letter, followed by a dash or a lowercase letter or a digit. The name must end with a lowercase letter or a digit. The name must be between 3 and 45 characters long.


<a id="nestedblock--config--notifications"></a>
### Nested Schema for `config.notifications`

Expand Down
2 changes: 1 addition & 1 deletion examples/provider/provider.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ terraform {
required_providers {
imagefactory = {
source = "nordcloud/imagefactory"
version = "1.10.0"
version = "1.11.0"
}
}
}
Expand Down
27 changes: 27 additions & 0 deletions examples/resources/imagefactory_template/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -254,3 +254,30 @@ resource "imagefactory_template" "exoscale_template" {
output "template" {
value = imagefactory_template.exoscale_template
}

# GCP Template

data "imagefactory_distribution" "ubuntu22" {
name = "Ubuntu Server 22.04 LTS"
cloud_provider = "GCP"
}

resource "imagefactory_template" "gcp_template" {
name = "Ubuntu2204"
description = "Ubuntu Server 22.04 on GCP"
cloud_provider = "GCP"
distribution_id = data.imagefactory_distribution.ubuntu22.id
config {
gcp {
custom_image_name = "ubuntu-22-04-prod-1-3"
}
notifications {
type = "WEB_HOOK"
uri = "https://webhook.call.api.address"
}
}
}

output "template" {
value = imagefactory_template.gcp_template
}
24 changes: 24 additions & 0 deletions imagefactory/imagetemplate/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,25 @@ var exoscaleTemplateConfigResource = &schema.Resource{
},
}

var customImageNameValidationDescription = "Must be a valid custom image name. " +
"The name must start with a lowercase letter, followed by a dash or a lowercase letter or a digit. " +
"The name must end with a lowercase letter or a digit. " +
"The name must be between 3 and 45 characters long."

var gcpTemplateConfigResource = &schema.Resource{
Schema: map[string]*schema.Schema{
"custom_image_name": {
Type: schema.TypeString,
Optional: true,
Description: "The name of the custom image. " + customImageNameValidationDescription,
ValidateFunc: validation.StringMatch(
regexp.MustCompile(`^[a-z]([-a-z0-9]*[a-z0-9]){2,44}$`),
customImageNameValidationDescription,
),
},
},
}

var templateComponentResource = &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Expand Down Expand Up @@ -252,6 +271,11 @@ var templateConfigResource = &schema.Resource{
Optional: true,
Elem: exoscaleTemplateConfigResource,
},
"gcp": {
Type: schema.TypeList,
Optional: true,
Elem: gcpTemplateConfigResource,
},
"build_components": {
Type: schema.TypeList,
Optional: true,
Expand Down
18 changes: 18 additions & 0 deletions imagefactory/imagetemplate/structures.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,23 @@ func expandTemplateExoscaleConfig(in []interface{}) *graphql.NewTemplateExoscale
}
}

func expandTemplateGcpConfig(in []interface{}) *graphql.NewTemplateGCPConfig {
if len(in) == 0 {
return nil
}

var imageName graphql.String

m := in[0].(map[string]interface{})
if m["custom_image_name"] != nil || m["custom_image_name"].(string) != "" {
imageName = graphql.String(m["custom_image_name"].(string))
}

return &graphql.NewTemplateGCPConfig{
CustomImageName: &imageName,
}
}

func expandTemplateConfig(in []interface{}) (*graphql.NewTemplateConfig, error) {
if len(in) == 0 {
return &graphql.NewTemplateConfig{}, nil
Expand All @@ -198,6 +215,7 @@ func expandTemplateConfig(in []interface{}) (*graphql.NewTemplateConfig, error)
Aws: awsCfg,
Azure: expandTemplateAzureConfig(m["azure"].([]interface{})),
Exoscale: expandTemplateExoscaleConfig(m["exoscale"].([]interface{})),
Gcp: expandTemplateGcpConfig(m["gcp"].([]interface{})),
BuildComponents: expandTemplateComponents(m["build_components"].([]interface{})),
TestComponents: expandTemplateComponents(m["test_components"].([]interface{})),
Notifications: expandTemplateNotifications(m["notifications"].([]interface{})),
Expand Down
11 changes: 11 additions & 0 deletions pkg/graphql/graphql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions pkg/graphql/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,7 @@ type ImageBuildDetails {
changeLog: String
compliance: Compliance
packageInventory: String
sbom: String
resultImageId: String
resultImageUri: String
buildTimeSec: Int
Expand Down Expand Up @@ -1042,6 +1043,10 @@ type TemplateExoscaleConfig {
zone: String
}

type TemplateGCPConfig {
customImageName: String
}

type TemplateConfig {
buildComponents: [TemplateComponent!]
testComponents: [TemplateComponent!]
Expand All @@ -1053,6 +1058,7 @@ type TemplateConfig {
aws: TemplateAWSConfig
azure: TemplateAZUREConfig
exoscale: TemplateExoscaleConfig
gcp: TemplateGCPConfig

"""
cloudAccountIds contains a list of Cloud Account IDs to which we will distribute the image
Expand Down Expand Up @@ -1217,6 +1223,19 @@ input NewTemplateExoscaleConfig {
zone: String
}

input NewTemplateGCPConfig {
"""
`customImageName` specifies the name of the image to be created in Google Cloud Platform.
The name must be unique within the project and adhere to the following restrictions:
* Must be 3-45 characters long.
* Must start with a lowercase letter, followed by up to 44 lowercase letters, numbers, or dashes.
ImageFactory will append a timestamp suffix to the image name in the format `custom-image-name-yyyymmddhhmmssmmm`.
"""
customImageName: String
}

"""
NewTemplateConfig defines the image customization.
Expand Down Expand Up @@ -1256,6 +1275,11 @@ input NewTemplateConfig {
"""
exoscale: NewTemplateExoscaleConfig

"""
gcp defines additional configuration for the Google Cloud provider. This is optional and can be used only for GOOGLE CLOUD template.
"""
gcp: NewTemplateGCPConfig

"""
cloudAccountIds defines a list of Cloud Account IDs to which we will distribute the image.
"""
Expand Down

0 comments on commit 9ba4ba5

Please sign in to comment.