Skip to content

Commit

Permalink
Merge branch 'main' into DEV-349_forreal
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/app/pages/server-details/server-details.component.ts
  • Loading branch information
Palabola committed Oct 2, 2024
2 parents b1bbb7c + 2f7cf50 commit d872081
Show file tree
Hide file tree
Showing 46 changed files with 3,386 additions and 154 deletions.
65 changes: 65 additions & 0 deletions .github/workflows/docker.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Build and publish sc-www image for prod
on:
push:
branches:
- main

jobs:
build-and-push-image:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Inject legal docs
env:
LEGAL_TOKEN: ${{ secrets.LEGAL_TOKEN }}
LEGAL_URL: ${{ secrets.LEGAL_URL }}
run: 'curl -s -L -H "Authorization: token ${LEGAL_TOKEN}" ${LEGAL_URL} | tar xz --strip-components=1'
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-central-1
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
file: Dockerfile
context: .
push: true
tags: ${{ steps.login-ecr.outputs.registry }}/${{ secrets.ECR_REPO_NAME }}:latest
build-args: |
POSTHOG_KEY=${{ secrets.POSTHOG_KEY }}
POSTHOG_HOST=${{ secrets.POSTHOG_HOST }}
SENTRY_DSN=${{ secrets.SENTRY_DSN }}
SENTRY_ENVIRONMENT=production
SENTRY_ORG=${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT=${{ secrets.SENTRY_PROJECT }}
SENTRY_URL=${{ secrets.SENTRY_URL }}
SENTRY_RELEASE=${{ env.GITHUB_SHA }}
SENTRY_TRACE_SAMPLE_RATE=1
SENTRY_PROFILE_SAMPLE_RATE=1
- name: Create Sentry release
uses: getsentry/action-release@v1
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
SENTRY_URL: ${{ secrets.SENTRY_URL }}
with:
environment: production
ignore_missing: true

- name: Redeploy ECS service
env:
CLUSTER: ${{ secrets.ECS_CLUSTER }}
SERVICE: ${{ secrets.ECS_SERVICE }}
REGION: eu-central-1
run: |
aws ecs update-service --cluster $CLUSTER --service $SERVICE --force-new-deployment --region $REGION
44 changes: 44 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
FROM public.ecr.aws/docker/library/node:lts-iron AS build

ARG BACKEND_BASE_URI=https://keeper.sparecores.net
ENV NG_APP_BACKEND_BASE_URI=$BACKEND_BASE_URI
ARG BACKEND_BASE_URI_SSR=https://keeper.sparecores.net
ENV NG_APP_BACKEND_BASE_URI_SSR=$BACKEND_BASE_URI_SSR

ARG POSTHOG_KEY
ENV NG_APP_POSTHOG_KEY=$POSTHOG_KEY
ARG POSTHOG_HOST
ENV NG_APP_POSTHOG_HOST=$POSTHOG_HOST

ARG SENTRY_ORG
ENV SENTRY_ORG=$SENTRY_ORG
ARG SENTRY_PROJECT
ENV SENTRY_PROJECT=$SENTRY_PROJECT
ARG SENTRY_URL
ENV SENTRY_URL=$SENTRY_URL

ARG SENTRY_DSN
ENV NG_APP_SENTRY_DSN=$SENTRY_DSN
ARG SENTRY_TRACE_SAMPLE_RATE=0
ENV NG_APP_SENTRY_TRACE_SAMPLE_RATE=$SENTRY_TRACE_SAMPLE_RATE
ARG SENTRY_PROFILE_SAMPLE_RATE=0
ENV NG_APP_SENTRY_PROFILE_SAMPLE_RATE=$SENTRY_PROFILE_SAMPLE_RATE
ARG SENTRY_ENVIRONMENT=development
ENV NG_APP_SENTRY_ENVIRONMENT=$SENTRY_ENVIRONMENT
ARG SENTRY_RELEASE
ENV NG_APP_SENTRY_RELEASE=$SENTRY_RELEASE

WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build \
--mount=type=secret,id=aws-key-id,env=AWS_ACCESS_KEY_ID

FROM public.ecr.aws/docker/library/node:lts-iron
COPY package*.json ./
RUN npm install --omit=dev --no-audit
COPY --from=build /usr/src/app/dist/sc-www/server /usr/share/www
COPY --from=build /usr/src/app/dist/sc-www/browser /usr/share/www/static
EXPOSE 3000
CMD ["node", "/usr/share/www/server.mjs"]
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ following environment variable(s):
- NG_APP_SENTRY_TRACE_SAMPLE_RATE (default to 0)
- NG_APP_SENTRY_PROFILE_SAMPLE_RATE (default to 0)
- NG_APP_SENTRY_ENVIRONMENT (default to "development")
- NG_APP_SENTRY_RELEASE

If you need to update the Keeper SDK, use the `generate-api(-prod)` script.

## Development server

Expand All @@ -56,7 +59,9 @@ Run `ng build` to build the project. The build artifacts will be
stored in the `dist/` directory.

Note that the project heavily relies on SSR, so you will need a
node.js backend running to serve requests.
node.js backend running to serve requests. You can set the
`ENABLE_PERFORMANCE_PROFILER` env var to `true` to get performance
metrics on the SSR steps.

## Linting tools

Expand All @@ -68,9 +73,7 @@ Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.

## Running end-to-end tests

Run `ng e2e` to execute the end-to-end tests via a platform of your
choice. To use this command, you need to first add a package that
implements end-to-end testing capabilities.
End-to-end tests are implemented using Cypress.

## License

Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/servers_details.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ describe('Server Details', () => {
});

it('Server without price and charts', () => {
E2EEvent.visitURL('/server/gcp/c4-standard-192', 4000);
E2EEvent.visitURL('/server/gcp/x4-megamem-1440-metal', 4000);

E2EEvent.checkBreadcrumbs();

Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/servers_page.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe('Server listing', () => {
E2EEvent.isVisible(`[id="servers_table"]`);

// count lines
E2EEvent.countElements(`[id="servers_table"]`, `[id="server_table_data_line"]`,25);
E2EEvent.countElements(`[id="servers_table"]`, `[id="server_table_data_line"]`, 25);

// pagination
E2EEvent.isVisible(`[id="pagination_next_arrow"]`);
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/servers_prices_page.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('Server prices', () => {

E2EEvent.isVisible(`[id="server_prices_table"]`);

E2EEvent.countElements(`[id="server_prices_table"]`, `[id="server_table_data_line"]`,25);
E2EEvent.countElements(`[id="server_prices_table"]`, `[id="server_table_data_line"]`, 25);

E2EEvent.isVisible(`[id="pagination_next_arrow"]`);

Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@
"postbuild": "./amplify-manifester.sh",
"watch": "ng build --watch --configuration development",
"test": "ng test",
"serve:ssr:sc-www": "node dist/sc-www/server/server.mjs --inspect",
"serve:ssr:sc-www": "node dist/sc-www/server/server.mjs",
"lint": "ng lint",
"sentry:sourcemaps": "sentry-cli sourcemaps inject ./dist/sc-www && sentry-cli sourcemaps upload ./dist/sc-www",
"sentry:release": "SENTRY_RELEASE=`sentry-cli releases propose-version` && sentry-cli releases new $SENTRY_RELEASE",
"sentry:release-with-commits": "SENTRY_RELEASE=`sentry-cli releases propose-version` && sentry-cli releases new $SENTRY_RELEASE && sentry-cli releases set-commits $SENTRY_RELEASE --auto && sentry-cli releases finalize $SENTRY_RELEASE",
"cypress:open": "cypress open",
"cypress:run": "cypress run"
"cypress:run": "cypress run",
"generate-api": "npx swagger-typescript-api -p http://localhost:8000/openapi.json -o ./sdk -n KeeperApi.ts --extract-request-params --extract-request-body --extract-response-body --route-types --modular --single-http-client",
"generate-api-prod": "npx swagger-typescript-api -p https://keeper.sparecores.net/openapi.json -o ./sdk -n KeeperApi.ts --extract-request-params --extract-request-body --extract-response-body --route-types --modular --single-http-client"
},
"private": true,
"dependencies": {
Expand Down
42 changes: 42 additions & 0 deletions sdk/Ai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ import {
AssistServerFiltersAiAssistServerFiltersGetParams,
AssistServerPriceFiltersAiAssistServerPriceFiltersGetData,
AssistServerPriceFiltersAiAssistServerPriceFiltersGetParams,
AssistStoragePriceFiltersAiAssistStoragePriceFiltersGetData,
AssistStoragePriceFiltersAiAssistStoragePriceFiltersGetParams,
AssistTrafficPriceFiltersAiAssistTrafficPriceFiltersGetData,
AssistTrafficPriceFiltersAiAssistTrafficPriceFiltersGetParams,
HTTPValidationError,
} from "./data-contracts";
import { HttpClient, RequestParams } from "./http-client";
Expand Down Expand Up @@ -63,4 +67,42 @@ export class Ai<SecurityDataType = unknown> {
format: "json",
...params,
});
/**
* @description Extract StoragePrice JSON filters from freetext.
*
* @tags AI
* @name AssistStoragePriceFiltersAiAssistStoragePriceFiltersGet
* @summary Assist Storage Price Filters
* @request GET:/ai/assist_storage_price_filters
*/
assistStoragePriceFiltersAiAssistStoragePriceFiltersGet = (
query: AssistStoragePriceFiltersAiAssistStoragePriceFiltersGetParams,
params: RequestParams = {},
) =>
this.http.request<AssistStoragePriceFiltersAiAssistStoragePriceFiltersGetData, HTTPValidationError>({
path: `/ai/assist_storage_price_filters`,
method: "GET",
query: query,
format: "json",
...params,
});
/**
* @description Extract TrafficPrice JSON filters from freetext.
*
* @tags AI
* @name AssistTrafficPriceFiltersAiAssistTrafficPriceFiltersGet
* @summary Assist Traffic Price Filters
* @request GET:/ai/assist_traffic_price_filters
*/
assistTrafficPriceFiltersAiAssistTrafficPriceFiltersGet = (
query: AssistTrafficPriceFiltersAiAssistTrafficPriceFiltersGetParams,
params: RequestParams = {},
) =>
this.http.request<AssistTrafficPriceFiltersAiAssistTrafficPriceFiltersGetData, HTTPValidationError>({
path: `/ai/assist_traffic_price_filters`,
method: "GET",
query: query,
format: "json",
...params,
});
}
38 changes: 38 additions & 0 deletions sdk/AiRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import {
AssistServerFiltersAiAssistServerFiltersGetData,
AssistServerPriceFiltersAiAssistServerPriceFiltersGetData,
AssistStoragePriceFiltersAiAssistStoragePriceFiltersGetData,
AssistTrafficPriceFiltersAiAssistTrafficPriceFiltersGetData,
} from "./data-contracts";

export namespace Ai {
Expand Down Expand Up @@ -50,4 +52,40 @@ export namespace Ai {
export type RequestHeaders = {};
export type ResponseBody = AssistServerPriceFiltersAiAssistServerPriceFiltersGetData;
}

/**
* @description Extract StoragePrice JSON filters from freetext.
* @tags AI
* @name AssistStoragePriceFiltersAiAssistStoragePriceFiltersGet
* @summary Assist Storage Price Filters
* @request GET:/ai/assist_storage_price_filters
*/
export namespace AssistStoragePriceFiltersAiAssistStoragePriceFiltersGet {
export type RequestParams = {};
export type RequestQuery = {
/** Text */
text: string;
};
export type RequestBody = never;
export type RequestHeaders = {};
export type ResponseBody = AssistStoragePriceFiltersAiAssistStoragePriceFiltersGetData;
}

/**
* @description Extract TrafficPrice JSON filters from freetext.
* @tags AI
* @name AssistTrafficPriceFiltersAiAssistTrafficPriceFiltersGet
* @summary Assist Traffic Price Filters
* @request GET:/ai/assist_traffic_price_filters
*/
export namespace AssistTrafficPriceFiltersAiAssistTrafficPriceFiltersGet {
export type RequestParams = {};
export type RequestQuery = {
/** Text */
text: string;
};
export type RequestBody = never;
export type RequestHeaders = {};
export type ResponseBody = AssistTrafficPriceFiltersAiAssistTrafficPriceFiltersGetData;
}
}
2 changes: 1 addition & 1 deletion sdk/Healthcheck.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class Healthcheck<SecurityDataType = unknown> {
}

/**
* @description Return database hash and last updated timestamp.
* @description Quickly return package and database version information.
*
* @tags Administrative endpoints
* @name HealthcheckHealthcheckGet
Expand Down
2 changes: 1 addition & 1 deletion sdk/HealthcheckRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { HealthcheckHealthcheckGetData } from "./data-contracts";

export namespace Healthcheck {
/**
* @description Return database hash and last updated timestamp.
* @description Quickly return package and database version information.
* @tags Administrative endpoints
* @name HealthcheckHealthcheckGet
* @summary Healthcheck
Expand Down
16 changes: 8 additions & 8 deletions sdk/Server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import {
GetServerPricesServerVendorServerPricesGetParams,
GetServerServerVendorServerGetData,
GetServerServerVendorServerGetParams,
GetSimilarServersServerVendorServerSimilarServersByNGetData,
GetSimilarServersServerVendorServerSimilarServersByNGetParams,
GetSimilarServersServerVendorServerSimilarServersByNumGetData,
GetSimilarServersServerVendorServerSimilarServersByNumGetParams,
HTTPValidationError,
} from "./data-contracts";
import { HttpClient, RequestParams } from "./http-client";
Expand Down Expand Up @@ -52,16 +52,16 @@ export class Server<SecurityDataType = unknown> {
* @description Search similar servers to the provided one. The "family" method returns all servers from the same family of the same vendor. The "specs" approach will prioritize the number of GPUs, then CPUs, lastly the amount of memory. The "score" method will find the servers with the closest performance using the multi-core SCore.
*
* @tags Server Details
* @name GetSimilarServersServerVendorServerSimilarServersByNGet
* @name GetSimilarServersServerVendorServerSimilarServersByNumGet
* @summary Get Similar Servers
* @request GET:/server/{vendor}/{server}/similar_servers/{by}/{n}
* @request GET:/server/{vendor}/{server}/similar_servers/{by}/{num}
*/
getSimilarServersServerVendorServerSimilarServersByNGet = (
{ vendor, server, by, n, ...query }: GetSimilarServersServerVendorServerSimilarServersByNGetParams,
getSimilarServersServerVendorServerSimilarServersByNumGet = (
{ vendor, server, by, num, ...query }: GetSimilarServersServerVendorServerSimilarServersByNumGetParams,
params: RequestParams = {},
) =>
this.http.request<GetSimilarServersServerVendorServerSimilarServersByNGetData, HTTPValidationError>({
path: `/server/${vendor}/${server}/similar_servers/${by}/${n}`,
this.http.request<GetSimilarServersServerVendorServerSimilarServersByNumGetData, HTTPValidationError>({
path: `/server/${vendor}/${server}/similar_servers/${by}/${num}`,
method: "GET",
query: query,
format: "json",
Expand Down
Loading

0 comments on commit d872081

Please sign in to comment.