From 75e2138878b5531e9d383a2f020e5f68831b22be Mon Sep 17 00:00:00 2001 From: Gianluca Zuccarelli Date: Thu, 19 Jan 2023 12:03:35 +0000 Subject: [PATCH] customizations: add custom repositories Define blueprint custom repositories. These definitions have been based on the upstream definitions of a DNF repo[1]. [1] See dnf.conf --- internal/blueprint/customizations.go | 16 ++++ .../blueprint/repository_customizations.go | 35 ++++++++ .../repository_customizations_test.go | 79 +++++++++++++++++++ 3 files changed, 130 insertions(+) create mode 100644 internal/blueprint/repository_customizations.go create mode 100644 internal/blueprint/repository_customizations_test.go diff --git a/internal/blueprint/customizations.go b/internal/blueprint/customizations.go index 408810167..2e5b03ed2 100644 --- a/internal/blueprint/customizations.go +++ b/internal/blueprint/customizations.go @@ -23,6 +23,7 @@ type Customizations struct { Ignition *IgnitionCustomization `json:"ignition,omitempty" toml:"ignition,omitempty"` Directories []DirectoryCustomization `json:"directories,omitempty" toml:"directories,omitempty"` Files []FileCustomization `json:"files,omitempty" toml:"files,omitempty"` + Repositories []RepositoryCustomization `json:"repositories,omitempty" toml:"repositories,omitempty"` } type IgnitionCustomization struct { @@ -333,3 +334,18 @@ func (c *Customizations) GetFiles() []FileCustomization { } return c.Files } + +func (c *Customizations) GetRepositories() ([]RepositoryCustomization, error) { + if c == nil { + return nil, nil + } + + for idx := range c.Repositories { + err := validateCustomRepository(&c.Repositories[idx]) + if err != nil { + return nil, err + } + } + + return c.Repositories, nil +} diff --git a/internal/blueprint/repository_customizations.go b/internal/blueprint/repository_customizations.go new file mode 100644 index 000000000..36666972d --- /dev/null +++ b/internal/blueprint/repository_customizations.go @@ -0,0 +1,35 @@ +package blueprint + +import ( + "fmt" +) + +type RepositoryCustomization struct { + Id string `json:"id" toml:"id"` + BaseURLs []string `json:"baseurls,omitempty" toml:"baseurls,omitempty"` + GPGKeys []string `json:"gpgkeys,omitempty" toml:"gpgkeys,omitempty"` + Metalink string `json:"metalink,omitempty" toml:"metalink,omitempty"` + Mirrorlist string `json:"mirrorlist,omitempty" toml:"mirrorlist,omitempty"` + Name string `json:"name,omitempty" toml:"name,omitempty"` + Priority *int `json:"priority,omitempty" toml:"priority,omitempty"` + Enabled *bool `json:"enabled,omitempty" toml:"enabled,omitempty"` + GPGCheck *bool `json:"gpgcheck,omitempty" toml:"gpgcheck,omitempty"` + RepoGPGCheck *bool `json:"repo_gpgcheck,omitempty" toml:"repo_gpgcheck,omitempty"` + SSLVerify bool `json:"sslverify,omitempty" toml:"sslverify,omitempty"` + Filename string `json:"filename,omitempty" toml:"filename,omitempty"` +} + +func validateCustomRepository(repo *RepositoryCustomization) error { + if repo.Id == "" { + return fmt.Errorf("Repository ID is required") + } + + if len(repo.BaseURLs) == 0 && repo.Mirrorlist == "" && repo.Metalink == "" { + return fmt.Errorf("Repository base URL, mirrorlist or metalink is required") + } + + if repo.GPGCheck != nil && *repo.GPGCheck && len(repo.GPGKeys) == 0 { + return fmt.Errorf("Repository gpg check is set to true but no gpg keys are provided") + } + return nil +} diff --git a/internal/blueprint/repository_customizations_test.go b/internal/blueprint/repository_customizations_test.go new file mode 100644 index 000000000..eb9918d09 --- /dev/null +++ b/internal/blueprint/repository_customizations_test.go @@ -0,0 +1,79 @@ +package blueprint + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetCustomRepositories(t *testing.T) { + testCases := []struct { + name string + expectedCustomizations Customizations + wantErr error + }{ + { + name: "Test no errors", + expectedCustomizations: Customizations{ + Repositories: []RepositoryCustomization{ + { + Id: "example-1", + BaseURLs: []string{"http://example-1.com"}, + }, + { + Id: "example-2", + BaseURLs: []string{"http://example-2.com"}, + }, + }, + }, + wantErr: nil, + }, + { + name: "Test empty id error", + expectedCustomizations: Customizations{ + Repositories: []RepositoryCustomization{ + {}, + }, + }, + wantErr: fmt.Errorf("Repository ID is required"), + }, + { + name: "Test empty baseurl, mirrorlist or metalink error", + expectedCustomizations: Customizations{ + Repositories: []RepositoryCustomization{ + { + Id: "example-1", + }, + }, + }, + wantErr: fmt.Errorf("Repository base URL, mirrorlist or metalink is required"), + }, + { + name: "Test missing GPG keys error", + expectedCustomizations: Customizations{ + Repositories: []RepositoryCustomization{ + { + Id: "example-1", + BaseURLs: []string{"http://example-1.com"}, + GPGCheck: common.ToPtr(true), + }, + }, + }, + wantErr: fmt.Errorf("Repository gpg check is set to true but no gpg keys are provided"), + }, + } + + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + if tt.wantErr == nil { + retCustomizations, err := tt.expectedCustomizations.GetRepositories() + assert.NoError(t, err) + assert.EqualValues(t, tt.expectedCustomizations.Repositories, retCustomizations) + } else { + _, err := tt.expectedCustomizations.GetRepositories() + assert.Equal(t, tt.wantErr, err) + } + }) + } +}