Skip to content

Commit

Permalink
feat: validate app name is consistent with pkg name
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenruizdegauna committed Feb 11, 2025
1 parent 7cfcbf4 commit 8d1fdee
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 9 deletions.
43 changes: 42 additions & 1 deletion publisher/config/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,21 @@ import (
"fmt"
"gopkg.in/yaml.v2"
"io/ioutil"
"strings"
)

//Errors
// Errors
const (
noDestinationError = "no uploads were provided for the schema"
//FileTypes
TypeFile = "file"
TypeZypp = "zypp"
TypeYum = "yum"
TypeApt = "apt"
)

var fileTypes = []string{TypeFile, TypeZypp, TypeYum, TypeApt}

type UploadArtifactSchema struct {
Src string `yaml:"src"`
Arch []string `yaml:"arch"`
Expand Down Expand Up @@ -65,3 +73,36 @@ func parseUploadSchema(fileContent []byte) (UploadArtifactSchemas, error) {

return schema, nil
}

// ValidateSchemas validates that some components of the schema are correct (this is still wip)
// It validates:
// - no incorrect fileType is present
// - the app name is the prefix of the src package. This is mandatory to create consistent apt repositories.
// If they are not equal, the file will be uploaded to a location, and the metadata will point to different location
// which will break the apt repository as you'll receive a 404 when trying to install the package.
func ValidateSchemas(appName string, schemas UploadArtifactSchemas) error {
for _, schema := range schemas {
if !isValidAppName(appName, schema) {
return fmt.Errorf("invalid app name: %s", appName)
}
for _, upload := range schema.Uploads {
if !isValidType(upload.Type) {
return fmt.Errorf("invalid upload type: %s", upload.Type)
}
}
}
return nil
}

func isValidType(uploadType string) bool {
for _, validType := range fileTypes {
if uploadType == validType {
return true
}
}
return false
}

func isValidAppName(appName string, schemas UploadArtifactSchema) bool {
return strings.HasPrefix(schemas.Src, appName)
}
44 changes: 44 additions & 0 deletions publisher/config/schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,47 @@ func TestSchema(t *testing.T) {
})
}
}

func TestValidateSchemas_UploadType(t *testing.T) {
tests := []struct {
name string
appName string
schemas UploadArtifactSchemas
expectedError error
}{
{name: "valid apt", appName: "some-app-name", schemas: UploadArtifactSchemas{{Src: "some-app-name_0.0.1_amd64.deb", Uploads: []Upload{{Type: TypeApt}}}}, expectedError: nil},
{name: "valid yum", appName: "some-app-name", schemas: UploadArtifactSchemas{{Src: "some-app-name_0.0.1_amd64.rpm", Uploads: []Upload{{Type: TypeYum}}}}, expectedError: nil},
{name: "valid file", appName: "some-app-name", schemas: UploadArtifactSchemas{{Src: "some-app-name_0.0.1_amd64.tar-gz", Uploads: []Upload{{Type: TypeFile}}}}, expectedError: nil},
{name: "valid zypp", appName: "some-app-name", schemas: UploadArtifactSchemas{{Src: "some-app-name_0.0.1_amd64.rpm", Uploads: []Upload{{Type: TypeZypp}}}}, expectedError: nil},
{name: "invalid type even with valid file", appName: "some-app-name", schemas: UploadArtifactSchemas{{Src: "some-app-name_0.0.1_amd64.deb", Uploads: []Upload{{Type: "something wrong"}}}}, expectedError: errors.New("invalid upload type: something wrong")},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
err := ValidateSchemas(tt.appName, tt.schemas)
assert.Equal(t, tt.expectedError, err)
})
}
}

func TestValidateSchemas_AppNameShouldBePkgPrefix(t *testing.T) {
tests := []struct {
name string
appName string
schemas UploadArtifactSchemas
expectedError error
}{
{name: "valid app name with pkg suffix", appName: "some-app-name", schemas: UploadArtifactSchemas{{Src: "some-app-name_some_suffix_0.0.1_amd64.deb", Uploads: []Upload{{Type: TypeApt}}}}, expectedError: nil},
{name: "valid app name exactly as pkg name", appName: "some-app-name", schemas: UploadArtifactSchemas{{Src: "some-app-name_0.0.1_amd64.deb", Uploads: []Upload{{Type: TypeApt}}}}, expectedError: nil},
{name: "invalid app name", appName: "some-app-name", schemas: UploadArtifactSchemas{{Src: "some-other-name_0.0.1_amd64.deb", Uploads: []Upload{{Type: TypeFile}}}}, expectedError: errors.New("invalid app name: some-app-name")},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
err := ValidateSchemas(tt.appName, tt.schemas)
assert.Equal(t, tt.expectedError, err)
})
}
}
4 changes: 4 additions & 0 deletions publisher/publisher.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ func main() {
if err != nil {
l.Fatal(err)
}
// validate schemas
if err = config.ValidateSchemas(conf.AppName, uploadSchemas); err != nil {
l.Fatal(err)
}

if conf.LocalPackagesPath == "" {
d := download.NewDownloader(http.DefaultClient)
Expand Down
11 changes: 3 additions & 8 deletions publisher/upload/upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,6 @@ import (
)

const (
//FileTypes
typeFile = "file"
typeZypp = "zypp"
typeYum = "yum"
typeApt = "apt"
repodataRpmPath = "/repodata/repomd.xml"
signatureRpmPath = "/repodata/repomd.xml.asc"
aptPoolMain = "pool/main/"
Expand All @@ -33,7 +28,7 @@ const (
)

func uploadArtifact(conf config.Config, schema config.UploadArtifactSchema, upload config.Upload) (err error) {
if upload.Type == typeFile {
if upload.Type == config.TypeFile {
utils.Logger.Println("Uploading file artifact")
for _, arch := range schema.Arch {
if len(upload.OsVersion) == 0 {
Expand All @@ -50,15 +45,15 @@ func uploadArtifact(conf config.Config, schema config.UploadArtifactSchema, uplo
}
}
}
} else if upload.Type == typeYum || upload.Type == typeZypp {
} else if upload.Type == config.TypeYum || upload.Type == config.TypeZypp {
utils.Logger.Println("Uploading rpm as yum or zypp")
for _, arch := range schema.Arch {
err = uploadRpm(conf, schema.Src, upload, arch)
if err != nil {
return err
}
}
} else if upload.Type == typeApt {
} else if upload.Type == config.TypeApt {
utils.Logger.Println("Uploading apt")
err = uploadApt(conf, schema.Src, upload, schema.Arch)
if err != nil {
Expand Down

0 comments on commit 8d1fdee

Please sign in to comment.