Skip to content

Commit 8873452

Browse files
authored
Fixes 4293: add support for upload only repos (#728)
* Fixes 4293: add support for upload only repos * address comments * Reject create/update with a URL for upload repos
1 parent 77d4bae commit 8873452

20 files changed

+448
-99
lines changed

api/docs.go

+51-1
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,7 @@ const docTemplate = `{
851851
"in": "body",
852852
"required": true,
853853
"schema": {
854-
"$ref": "#/definitions/api.RepositoryRequest"
854+
"$ref": "#/definitions/api.RepositoryUpdateRequest"
855855
}
856856
}
857857
],
@@ -3348,6 +3348,11 @@ const docTemplate = `{
33483348
"description": "Name of the remote yum repository",
33493349
"type": "string"
33503350
},
3351+
"origin": {
3352+
"description": "Origin of the repository",
3353+
"type": "string",
3354+
"readOnly": true
3355+
},
33513356
"snapshot": {
33523357
"description": "Enable snapshotting and hosting of this repository",
33533358
"type": "boolean"
@@ -3535,6 +3540,51 @@ const docTemplate = `{
35353540
}
35363541
}
35373542
},
3543+
"api.RepositoryUpdateRequest": {
3544+
"type": "object",
3545+
"properties": {
3546+
"distribution_arch": {
3547+
"description": "Architecture to restrict client usage to",
3548+
"type": "string",
3549+
"example": "x86_64"
3550+
},
3551+
"distribution_versions": {
3552+
"description": "Versions to restrict client usage to",
3553+
"type": "array",
3554+
"items": {
3555+
"type": "string"
3556+
},
3557+
"example": [
3558+
"7",
3559+
"8"
3560+
]
3561+
},
3562+
"gpg_key": {
3563+
"description": "GPG key for repository",
3564+
"type": "string"
3565+
},
3566+
"metadata_verification": {
3567+
"description": "Verify packages",
3568+
"type": "boolean"
3569+
},
3570+
"module_hotfixes": {
3571+
"description": "Disable modularity filtering on this repository",
3572+
"type": "boolean"
3573+
},
3574+
"name": {
3575+
"description": "Name of the remote yum repository",
3576+
"type": "string"
3577+
},
3578+
"snapshot": {
3579+
"description": "Enable snapshotting and hosting of this repository",
3580+
"type": "boolean"
3581+
},
3582+
"url": {
3583+
"description": "URL of the remote yum repository",
3584+
"type": "string"
3585+
}
3586+
}
3587+
},
35383588
"api.RepositoryValidationRequest": {
35393589
"type": "object",
35403590
"properties": {

api/openapi.json

+51-1
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,11 @@
461461
"description": "Name of the remote yum repository",
462462
"type": "string"
463463
},
464+
"origin": {
465+
"description": "Origin of the repository",
466+
"readOnly": true,
467+
"type": "string"
468+
},
464469
"snapshot": {
465470
"description": "Enable snapshotting and hosting of this repository",
466471
"type": "boolean"
@@ -645,6 +650,51 @@
645650
},
646651
"type": "object"
647652
},
653+
"api.RepositoryUpdateRequest": {
654+
"properties": {
655+
"distribution_arch": {
656+
"description": "Architecture to restrict client usage to",
657+
"example": "x86_64",
658+
"type": "string"
659+
},
660+
"distribution_versions": {
661+
"description": "Versions to restrict client usage to",
662+
"example": [
663+
"7",
664+
"8"
665+
],
666+
"items": {
667+
"type": "string"
668+
},
669+
"type": "array"
670+
},
671+
"gpg_key": {
672+
"description": "GPG key for repository",
673+
"type": "string"
674+
},
675+
"metadata_verification": {
676+
"description": "Verify packages",
677+
"type": "boolean"
678+
},
679+
"module_hotfixes": {
680+
"description": "Disable modularity filtering on this repository",
681+
"type": "boolean"
682+
},
683+
"name": {
684+
"description": "Name of the remote yum repository",
685+
"type": "string"
686+
},
687+
"snapshot": {
688+
"description": "Enable snapshotting and hosting of this repository",
689+
"type": "boolean"
690+
},
691+
"url": {
692+
"description": "URL of the remote yum repository",
693+
"type": "string"
694+
}
695+
},
696+
"type": "object"
697+
},
648698
"api.RepositoryValidationRequest": {
649699
"properties": {
650700
"gpg_key": {
@@ -2233,7 +2283,7 @@
22332283
"content": {
22342284
"application/json": {
22352285
"schema": {
2236-
"$ref": "#/components/schemas/api.RepositoryRequest"
2286+
"$ref": "#/components/schemas/api.RepositoryUpdateRequest"
22372287
}
22382288
}
22392289
},

db/migrations.latest

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20240610112037
1+
20240627171711
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
BEGIN;
2+
alter table repositories alter column URL set not null;
3+
COMMIT;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
BEGIN;
2+
3+
alter table repositories alter column URL drop not null;
4+
5+
COMMIT;

pkg/api/repositories.go

+95-31
Original file line numberDiff line numberDiff line change
@@ -36,56 +36,112 @@ type RepositoryResponse struct {
3636
LastSnapshotTask *TaskInfoResponse `json:"last_snapshot_task,omitempty"` // Last snapshot task response (contains last snapshot status)
3737
}
3838

39-
// RepositoryRequest holds data received from request to create/update repository
39+
// RepositoryRequest holds data received from request to create repository
4040
type RepositoryRequest struct {
41-
UUID *string `json:"uuid" readonly:"true" swaggerignore:"true"`
42-
Name *string `json:"name"` // Name of the remote yum repository
43-
URL *string `json:"url"` // URL of the remote yum repository
44-
DistributionVersions *[]string `json:"distribution_versions" example:"7,8"` // Versions to restrict client usage to
45-
DistributionArch *string `json:"distribution_arch" example:"x86_64"` // Architecture to restrict client usage to
46-
GpgKey *string `json:"gpg_key"` // GPG key for repository
47-
MetadataVerification *bool `json:"metadata_verification"` // Verify packages
48-
ModuleHotfixes *bool `json:"module_hotfixes"` // Disable modularity filtering on this repository
49-
Snapshot *bool `json:"snapshot"` // Enable snapshotting and hosting of this repository
50-
AccountID *string `json:"account_id" readonly:"true" swaggerignore:"true"` // Account ID of the owner
51-
OrgID *string `json:"org_id" readonly:"true" swaggerignore:"true"` // Organization ID of the owner
52-
Origin *string `json:"origin" readonly:"true" swaggerignore:"true"` // Origin of the repository
53-
ContentType *string `json:"content_type" readonly:"true" swaggerignore:"true"` // Content Type (rpm) of the repository
41+
UUID *string `json:"uuid" readonly:"true" swaggerignore:"true"`
42+
AccountID *string `json:"account_id" readonly:"true" swaggerignore:"true"` // Account ID of the owner
43+
OrgID *string `json:"org_id" readonly:"true" swaggerignore:"true"` // Organization ID of the owner
44+
Origin *string `json:"origin" readonly:"true"` // Origin of the repository
45+
ContentType *string `json:"content_type" readonly:"true" swaggerignore:"true"` // Content Type (rpm) of the repository
46+
47+
Name *string `json:"name"` // Name of the remote yum repository
48+
URL *string `json:"url"` // URL of the remote yum repository
49+
DistributionVersions *[]string `json:"distribution_versions" example:"7,8"` // Versions to restrict client usage to
50+
DistributionArch *string `json:"distribution_arch" example:"x86_64"` // Architecture to restrict client usage to
51+
GpgKey *string `json:"gpg_key"` // GPG key for repository
52+
MetadataVerification *bool `json:"metadata_verification"` // Verify packages
53+
ModuleHotfixes *bool `json:"module_hotfixes"` // Disable modularity filtering on this repository
54+
Snapshot *bool `json:"snapshot"` // Enable snapshotting and hosting of this repository
55+
}
56+
57+
type RepositoryUpdateRequest struct {
58+
Name *string `json:"name"` // Name of the remote yum repository
59+
URL *string `json:"url"` // URL of the remote yum repository
60+
DistributionVersions *[]string `json:"distribution_versions" example:"7,8"` // Versions to restrict client usage to
61+
DistributionArch *string `json:"distribution_arch" example:"x86_64"` // Architecture to restrict client usage to
62+
GpgKey *string `json:"gpg_key"` // GPG key for repository
63+
MetadataVerification *bool `json:"metadata_verification"` // Verify packages
64+
ModuleHotfixes *bool `json:"module_hotfixes"` // Disable modularity filtering on this repository
65+
Snapshot *bool `json:"snapshot"` // Enable snapshotting and hosting of this repository
66+
}
67+
68+
func (r *RepositoryRequest) ToRepositoryUpdateRequest() RepositoryUpdateRequest {
69+
return RepositoryUpdateRequest{
70+
Name: r.Name,
71+
URL: r.URL,
72+
DistributionVersions: r.DistributionVersions,
73+
DistributionArch: r.DistributionArch,
74+
GpgKey: r.GpgKey,
75+
MetadataVerification: r.MetadataVerification,
76+
ModuleHotfixes: r.ModuleHotfixes,
77+
Snapshot: r.Snapshot,
78+
}
79+
}
80+
81+
var defaultRepoValues = RepositoryUpdateRequest{
82+
Name: pointy.Pointer(""),
83+
URL: pointy.Pointer(""),
84+
DistributionVersions: pointy.Pointer([]string{"any"}),
85+
DistributionArch: pointy.Pointer("any"),
86+
GpgKey: pointy.Pointer(""),
87+
MetadataVerification: pointy.Pointer(false),
88+
ModuleHotfixes: pointy.Pointer(false),
89+
Snapshot: pointy.Pointer(false),
90+
}
91+
92+
func (r *RepositoryUpdateRequest) FillDefaults() {
93+
if r.Name == nil {
94+
r.Name = defaultRepoValues.Name
95+
}
96+
if r.URL == nil {
97+
r.URL = defaultRepoValues.URL
98+
}
99+
if r.DistributionVersions == nil {
100+
r.DistributionVersions = defaultRepoValues.DistributionVersions
101+
}
102+
if r.DistributionArch == nil {
103+
r.DistributionArch = defaultRepoValues.DistributionArch
104+
}
105+
if r.GpgKey == nil {
106+
r.GpgKey = defaultRepoValues.GpgKey
107+
}
108+
if r.MetadataVerification == nil {
109+
r.MetadataVerification = defaultRepoValues.MetadataVerification
110+
}
111+
if r.ModuleHotfixes == nil {
112+
r.ModuleHotfixes = defaultRepoValues.ModuleHotfixes
113+
}
54114
}
55115

56116
func (r *RepositoryRequest) FillDefaults() {
57-
// Currently the user cannot change these
58-
r.Origin = pointy.Pointer(config.OriginExternal)
117+
// Currently the user cannot change these, only set at creation
59118
r.ContentType = pointy.Pointer(config.ContentTypeRpm)
60-
// Fill in default values in case of PUT request, doesn't have to be valid, let the db validate that
61-
defaultName := ""
62-
defaultUrl := ""
63-
defaultVersions := []string{"any"}
64-
defaultArch := "any"
65-
defaultGpgKey := ""
66-
defaultMetadataVerification := false
67-
defaultModuleHotfixes := false
68119

120+
if r.Origin == nil {
121+
r.Origin = pointy.Pointer(config.OriginExternal)
122+
}
123+
124+
// copied from RepositoryUpdateRequest FillDefaults
69125
if r.Name == nil {
70-
r.Name = &defaultName
126+
r.Name = defaultRepoValues.Name
71127
}
72128
if r.URL == nil {
73-
r.URL = &defaultUrl
129+
r.URL = defaultRepoValues.URL
74130
}
75131
if r.DistributionVersions == nil {
76-
r.DistributionVersions = &defaultVersions
132+
r.DistributionVersions = defaultRepoValues.DistributionVersions
77133
}
78134
if r.DistributionArch == nil {
79-
r.DistributionArch = &defaultArch
135+
r.DistributionArch = defaultRepoValues.DistributionArch
80136
}
81137
if r.GpgKey == nil {
82-
r.GpgKey = &defaultGpgKey
138+
r.GpgKey = defaultRepoValues.GpgKey
83139
}
84140
if r.MetadataVerification == nil {
85-
r.MetadataVerification = &defaultMetadataVerification
141+
r.MetadataVerification = defaultRepoValues.MetadataVerification
86142
}
87143
if r.ModuleHotfixes == nil {
88-
r.ModuleHotfixes = &defaultModuleHotfixes
144+
r.ModuleHotfixes = defaultRepoValues.ModuleHotfixes
89145
}
90146
}
91147

@@ -103,3 +159,11 @@ func (r *RepositoryCollectionResponse) SetMetadata(meta ResponseMetadata, links
103159
r.Meta = meta
104160
r.Links = links
105161
}
162+
163+
func (r *RepositoryResponse) Snapshottable() bool {
164+
return r.Origin != config.OriginUpload && r.Snapshot
165+
}
166+
167+
func (r *RepositoryResponse) Introspectable() bool {
168+
return r.Origin != config.OriginUpload
169+
}

pkg/config/value_constraints.go

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ const (
1616
const (
1717
OriginExternal = "external"
1818
OriginRedHat = "red_hat"
19+
OriginUpload = "upload"
1920
)
2021

2122
const RedHatOrg = "-1"

pkg/dao/interfaces.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ func SetupGormTableOrFail(db *gorm.DB) {
6666
type RepositoryConfigDao interface {
6767
Create(ctx context.Context, newRepo api.RepositoryRequest) (api.RepositoryResponse, error)
6868
BulkCreate(ctx context.Context, newRepositories []api.RepositoryRequest) ([]api.RepositoryResponse, []error)
69-
Update(ctx context.Context, orgID, uuid string, repoParams api.RepositoryRequest) (bool, error)
69+
Update(ctx context.Context, orgID, uuid string, repoParams api.RepositoryUpdateRequest) (bool, error)
7070
Fetch(ctx context.Context, orgID string, uuid string) (api.RepositoryResponse, error)
7171
InternalOnly_ListReposToSnapshot(ctx context.Context, filter *ListRepoFilter) ([]models.RepositoryConfiguration, error)
7272
List(ctx context.Context, orgID string, paginationData api.PaginationData, filterData api.FilterData) (api.RepositoryCollectionResponse, int64, error)

pkg/dao/repositories.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ func (p repositoryDaoImpl) ListForIntrospection(ctx context.Context, urls *[]str
100100
db = db.Where("url in ?", *urls)
101101
}
102102

103-
result := db.Find(&dbRepos)
103+
result := db.Where("origin in ?", []string{config.OriginExternal, config.OriginRedHat}).Find(&dbRepos)
104104
if result.Error != nil {
105105
return repos, result.Error
106106
}

0 commit comments

Comments
 (0)