Skip to content

Commit

Permalink
Merge branch 'master' into PROJQUAY-6247
Browse files Browse the repository at this point in the history
  • Loading branch information
Sunandadadi committed Nov 16, 2023
2 parents a696794 + 0b6b159 commit 4d49f0f
Show file tree
Hide file tree
Showing 34 changed files with 794 additions and 281 deletions.
61 changes: 43 additions & 18 deletions config-tool/pkg/lib/fieldgroups/database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ type DbConnectionArgsStruct struct {
SslMaxProtocolVersion string `default:"" json:"ssl_max_protocol_version,omitempty" yaml:"ssl_max_protocol_version,omitempty"`
SslCrl string `default:"" json:"sslcrl,omitempty" yaml:"sslcrl,omitempty"`
SslCrlDir string `default:"" json:"sslcrldir,omitempty" yaml:"sslcrldir,omitempty"`
SslCompression int `default:0 json:"sslcompression,omitempty" yaml:"sslcompression,omitempty"`
SslCompression *int `default:"" json:"sslcompression,omitempty" yaml:"sslcompression,omitempty"`

// Network arguments
Keepalives int `default:0 json:"keepalives,omitempty" yaml:"keepalives,omitempty"`
KeepalivesIdle int `default:10 json:"keepalives_idle,omitempty" yaml:"keepalives_idle,omitempty"`
KeepalivesInterval int `default:2 json:"keepalives_interval,omitempty" yaml:"keepalives_interval,omitempty"`
KeepalivesCount int `default:3 json:"keepalives_count,omitempty" yaml:"keepalives_count,omitempty"`
TcpUserTimeout int `default:0 json:"tcp_user_timeout,omitempty" yaml:"tcp_user_timeout,omitempty"`
Keepalives *int `default:"" json:"keepalives,omitempty" yaml:"keepalives,omitempty"`
Keepalives_Idle *int `default:"" json:"keepalives_idle,omitempty" yaml:"keepalives_idle,omitempty"`
Keepalives_Interval *int `default:"" json:"keepalives_interval,omitempty" yaml:"keepalives_interval,omitempty"`
Keepalives_Count *int `default:"" json:"keepalives_count,omitempty" yaml:"keepalives_count,omitempty"`
Tcp_User_Timeout *int `default:"" json:"tcp_user_timeout,omitempty" yaml:"tcp_user_timeout,omitempty"`
}

// SslStruct represents the SslStruct config fields
Expand Down Expand Up @@ -165,41 +165,66 @@ func NewDbConnectionArgsStruct(fullConfig map[string]interface{}) (*DbConnection
return newDbConnectionArgsStruct, errors.New("sslcrldir must be of type string")
}
}

if value, ok := fullConfig["sslcompression"]; ok {
newDbConnectionArgsStruct.SslCompression, ok = value.(int)
val, ok := value.(int)
if !ok {
return newDbConnectionArgsStruct, errors.New("sslcompression must be of type int")
_, ok = value.(int)
if !ok {
return newDbConnectionArgsStruct, errors.New("sslcompression must be of type int")
}
}
newDbConnectionArgsStruct.SslCompression = &val
}
if value, ok := fullConfig["keepalives"]; ok {
newDbConnectionArgsStruct.Keepalives, ok = value.(int)
val, ok := value.(int)
if !ok {
return newDbConnectionArgsStruct, errors.New("keepalives must be of type int")
_, ok = value.(int)
if !ok {
return newDbConnectionArgsStruct, errors.New("keepalives must be of type int")
}
}
newDbConnectionArgsStruct.Keepalives = &val
}
if value, ok := fullConfig["keepalives_idle"]; ok {
newDbConnectionArgsStruct.KeepalivesIdle, ok = value.(int)
val, ok := value.(int)
if !ok {
return newDbConnectionArgsStruct, errors.New("keepalives_idle must be of type int")
_, ok = value.(int)
if !ok {
return newDbConnectionArgsStruct, errors.New("keepalives_idle must be of type int")
}
}
newDbConnectionArgsStruct.Keepalives_Idle = &val
}
if value, ok := fullConfig["keepalives_interval"]; ok {
newDbConnectionArgsStruct.KeepalivesInterval, ok = value.(int)
val, ok := value.(int)
if !ok {
return newDbConnectionArgsStruct, errors.New("keepalives_interval must be of type int")
_, ok = value.(int)
if !ok {
return newDbConnectionArgsStruct, errors.New("keepalives_interval must be of type int")
}
}
newDbConnectionArgsStruct.Keepalives_Interval = &val
}
if value, ok := fullConfig["keepalives_count"]; ok {
newDbConnectionArgsStruct.KeepalivesCount, ok = value.(int)
val, ok := value.(int)
if !ok {
return newDbConnectionArgsStruct, errors.New("keepalives_count must be of type int")
_, ok = value.(int)
if !ok {
return newDbConnectionArgsStruct, errors.New("keepalives_count must be of type int")
}
}
newDbConnectionArgsStruct.Keepalives_Count = &val
}
if value, ok := fullConfig["tcp_user_timeout"]; ok {
newDbConnectionArgsStruct.TcpUserTimeout, ok = value.(int)
val, ok := value.(int)
if !ok {
return newDbConnectionArgsStruct, errors.New("tcp_user_timeout must be of type int")
_, ok = value.(int)
if !ok {
return newDbConnectionArgsStruct, errors.New("tcp_user_timeout must be of type int")
}
}
newDbConnectionArgsStruct.Tcp_User_Timeout = &val
}

return newDbConnectionArgsStruct, nil
Expand Down
2 changes: 1 addition & 1 deletion config.py
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ def create_transaction(db):
SECURITY_SCANNER_V4_ENDPOINT: Optional[str] = None

# Cleanup deleted manifests from the security scanner service.
SECURITY_SCANNER_V4_MANIFEST_CLEANUP: Optional[bool] = False
SECURITY_SCANNER_V4_MANIFEST_CLEANUP: Optional[bool] = True

# The number of seconds between indexing intervals in the security scanner
SECURITY_SCANNER_INDEXING_INTERVAL = 30
Expand Down
2 changes: 2 additions & 0 deletions deploy/openshift/quay-py3-app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ objects:
value: ${QUAY_WORKER_MULTIPLIER_REGISTRY}
- name: WORKER_CONNECTION_COUNT_REGISTRY
value: ${QUAY_WORKER_CONNECTION_COUNT_REGISTRY}
- name: DB_CONNECTION_POOLING
value: ${DB_CONNECTION_POOLING}
parameters:
- name: NAME
value: "quay-py3"
Expand Down
2 changes: 2 additions & 0 deletions deploy/openshift/quay-py3-deploy-template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,8 @@ objects:
value: ${QUAY_WORKER_MULTIPLIER_REGISTRY}
- name: WORKER_CONNECTION_COUNT_REGISTRY
value: ${QUAY_WORKER_CONNECTION_COUNT_REGISTRY}
- name: DB_CONNECTION_POOLING
value: ${DB_CONNECTION_POOLING}
parameters:
- name: NAME
value: "quay-py3"
Expand Down
1 change: 1 addition & 0 deletions endpoints/api/billing.py
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,7 @@ def post(self, orgname):
"performer": get_authenticated_user().username,
"ip": get_request_ip(),
"plan": price["stripeId"],
"trial_period_days": price["free_trial_days"],
},
},
mode="subscription",
Expand Down
2 changes: 1 addition & 1 deletion endpoints/api/subscribe.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def get_price(plan, require_business_plan):
raise NotFound()

if require_business_plan and not plan_found["bus_features"] and not plan_found["price"] == 0:
logger.warning("Business attempting to subscribe to personal plan: %s", user.username)
logger.warning("Business attempting to subscribe to personal plan: %s", plan_found["title"])
raise request_error(message="No matching plan found")

return plan_found
Expand Down
2 changes: 2 additions & 0 deletions storage/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from storage.cloud import (
CloudFrontedS3Storage,
GoogleCloudStorage,
IBMCloudStorage,
RadosGWStorage,
RHOCSStorage,
S3Storage,
Expand Down Expand Up @@ -29,6 +30,7 @@
"RHOCSStorage": RHOCSStorage,
"CloudFlareStorage": CloudFlareS3Storage,
"MultiCDNStorage": MultiCDNStorage,
"IBMCloudStorage": IBMCloudStorage,
}


Expand Down
55 changes: 55 additions & 0 deletions storage/cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,61 @@ def setup(self):
)


class IBMCloudStorage(_CloudStorage):
def __init__(
self,
context,
hostname,
is_secure,
storage_path,
access_key,
secret_key,
bucket_name,
port=None,
maximum_chunk_size_mb=None,
):
upload_params = {}
connect_kwargs = {
"endpoint_url": _build_endpoint_url(hostname, port=port, is_secure=is_secure),
}

super(IBMCloudStorage, self).__init__(
context,
boto3.session.Session,
connect_kwargs,
upload_params,
storage_path,
bucket_name,
access_key,
secret_key,
)

chunk_size = (
maximum_chunk_size_mb if maximum_chunk_size_mb is not None else 100
) # 100mb default, recommended by IBM
self.maximum_chunk_size = chunk_size * 1024 * 1024

def setup(self):
self.get_cloud_bucket().Cors().put(
CORSConfiguration={
"CORSRules": [
{
"AllowedOrigins": ["*"],
"AllowedMethods": ["GET"],
"MaxAgeSeconds": 3000,
"AllowedHeaders": ["Authorization"],
},
{
"AllowedOrigins": ["*"],
"AllowedMethods": ["PUT"],
"MaxAgeSeconds": 3000,
"AllowedHeaders": ["Content-Type", "x-amz-acl", "origin"],
},
]
}
)


class GoogleCloudStorage(_CloudStorage):
ENDPOINT_URL = "https://storage.googleapis.com"

Expand Down
4 changes: 3 additions & 1 deletion storage/cloudflarestorage.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ def __init__(
*args,
**kwargs,
):
super(CloudFlareS3Storage, self).__init__(context, storage_path, s3_bucket, *args, **kwargs)
super(CloudFlareS3Storage, self).__init__(
context, storage_path, s3_bucket, s3_region=s3_region, *args, **kwargs
)

self.cloudflare_domain = cloudflare_domain
self.cloudflare_privatekey = self._load_private_key(cloudflare_privatekey_filename)
Expand Down
125 changes: 125 additions & 0 deletions web/cypress/e2e/breadcrumbs.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/// <reference types="cypress" />

describe('Tests for Breadcrumbs', () => {
beforeEach(() => {
cy.exec('npm run quay:seed');
cy.request('GET', `${Cypress.env('REACT_QUAY_APP_API_URL')}/csrf_token`)
.then((response) => response.body.csrf_token)
.then((token) => {
cy.loginByCSRF(token);
});
});

it('Organization list page', () => {
cy.visit('/organization');
cy.get('nav[test-id="page-breadcrumbs-list"]').should('not.exist');
});

it('Repository list page', () => {
cy.visit('/repository');
cy.get('nav[test-id="page-breadcrumbs-list"]').should('not.exist');
});

it('Organization page', () => {
cy.visit('/organization/projectquay');
cy.get('nav[test-id="page-breadcrumbs-list"]').within(() => {
cy.get('li')
.each(($el, index) => {
switch (index) {
case 0:
cy.wrap($el).should('have.text', 'organization');
cy.wrap($el)
.children('a')
.should('have.attr', 'href', '/organization');
break;
case 1:
cy.wrap($el).should('have.text', 'projectquay');
cy.wrap($el).children('a').should('have.class', 'disabled-link');
cy.wrap($el)
.children('a')
.should('have.attr', 'href', '/organization/projectquay');
break;
}
})
.then(($lis) => {
expect($lis).to.have.length(2);
});
});
});

it('Repository page', () => {
cy.visit('/repository/projectquay/repo1');
cy.get('nav[test-id="page-breadcrumbs-list"]').within(() => {
cy.get('li')
.each(($el, index) => {
switch (index) {
case 0:
cy.wrap($el).should('have.text', 'repository');
cy.wrap($el)
.children('a')
.should('have.attr', 'href', '/repository');
break;
case 1:
cy.wrap($el).should('have.text', 'projectquay');
cy.wrap($el)
.children('a')
.should('have.attr', 'href', '/organization/projectquay');
break;
case 2:
cy.wrap($el).should('have.text', 'repo1');
cy.wrap($el).children('a').should('have.class', 'disabled-link');
cy.wrap($el)
.children('a')
.should('have.attr', 'href', '/repository/projectquay/repo1');
break;
}
})
.then(($lis) => {
expect($lis).to.have.length(3);
});
});
});

it('Tags list page', () => {
cy.visit('/repository/user1/hello-world/tag/latest');
cy.get('nav[test-id="page-breadcrumbs-list"]').within(() => {
cy.get('li')
.each(($el, index) => {
switch (index) {
case 0:
cy.wrap($el).should('have.text', 'repository');
cy.wrap($el)
.children('a')
.should('have.attr', 'href', '/repository');
break;
case 1:
cy.wrap($el).should('have.text', 'user1');
cy.wrap($el)
.children('a')
.should('have.attr', 'href', '/organization/user1');
break;
case 2:
cy.wrap($el).should('have.text', 'hello-world');
cy.wrap($el)
.children('a')
.should('have.attr', 'href', '/repository/user1/hello-world');
break;
case 3:
cy.wrap($el).should('have.text', 'latest');
cy.wrap($el).children('a').should('have.class', 'disabled-link');
cy.wrap($el)
.children('a')
.should(
'have.attr',
'href',
'/repository/user1/hello-world/tag/latest',
);
break;
}
})
.then(($lis) => {
expect($lis).to.have.length(4);
});
});
});
});
10 changes: 5 additions & 5 deletions web/cypress/e2e/org-list.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,12 @@ describe('Org List Page', () => {
it('Pagination', () => {
cy.visit('/organization');

cy.contains('1 - 20 of 27').should('exist');
cy.contains('1 - 20 of 28').should('exist');
cy.get('td[data-label="Name"]').should('have.length', 20);

// cycle through the pages
cy.get('button[aria-label="Go to next page"]').first().click();
cy.get('td[data-label="Name"]').should('have.length', 7);
cy.get('td[data-label="Name"]').should('have.length', 8);

// Go to first page
cy.get('button[aria-label="Go to first page"]').first().click();
Expand All @@ -112,12 +112,12 @@ describe('Org List Page', () => {
// Go to last page
cy.get('button[aria-label="Go to last page"]').first().click();
cy.contains('user1').should('exist');
cy.get('td[data-label="Name"]').should('have.length', 7);
cy.get('td[data-label="Name"]').should('have.length', 8);

// Change per page
cy.get('button:contains("21 - 27 of 27")').first().click();
cy.get('button:contains("21 - 28 of 28")').first().click();
cy.contains('20 per page').click();
cy.get('td[data-label="Name"]').should('have.length', 20);
cy.contains('1 - 20 of 27').should('exist');
cy.contains('1 - 20 of 28').should('exist');
});
});

0 comments on commit 4d49f0f

Please sign in to comment.