Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3 of 3, remaining alpha commits #391

Merged
merged 6 commits into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 0 additions & 20 deletions .codecov.yml

This file was deleted.

59 changes: 59 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# dockerignore exclusives
Containerfile
.dockerignore

# dependencies
node_modules/

# coverage
lib-cov
coverage
.nyc_output

# optional
.npm
.eslintcache
.node_repl_history
*.tgz

# build & production
build
dist/
public/assets

.css
templates/client
styles/*.css
src/styles/css
src/styles/.css
public/locales/*.json
!public/locales/locales.json
!public/locales/en.json
!public/icons/

# misc
.qpc
.container
!.env
.env*.local
pids
*.pid
*.seed
*.pid.lock
pr.txt
stats.json
storybook-static
.DS_Store
.idea

# logs
dependency-update-log.txt
logs
*.log
npm-debug.log*
api-debug*

.vscode

# local files
var/
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ REACT_APP_CONFIG_SERVICE_LOCALES_PATH=/locales/{{lng}}.json
REACT_APP_CONFIG_SERVICE_LOCALES_EXPIRE=604800000

REACT_APP_CREDENTIALS_SERVICE=/api/v1/credentials/
REACT_APP_CREDENTIALS_SERVICE_BULK_DELETE=/api/v1/credentials/bulk_delete/
REACT_APP_FACTS_SERVICE=/api/v1/facts/

REACT_APP_REPORTS_SERVICE=/api/v1/reports/
Expand Down
52 changes: 52 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Build Container Image

on:
push:
branches: [ v2-alpha ]
tags:
- '*'
pull_request:
branches: [ v2-alpha ]

env:
STABLE_TAG: ${{ github.event_name == 'push' && github.ref_name || format('pr-{0}', github.event.pull_request.number) }}
# We had a problem with GitHub setting quay expiration label also during
# merge to main, so we just set meaningless value as a workaround.
EXPIRATION_LABEL: ${{ github.event_name == 'push' && 'quipucords.source=github' || 'quay.expires-after=5d' }}
IMAGE_NAME: ${{ vars.IMAGE_NAME || 'quipucords/quipucords-ui' }}
REGISTRY: ${{ vars.REGISTRY || 'quay.io' }}

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Clone repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # fetches all commits/tags

- name: Build image
id: build-image
uses: redhat-actions/buildah-build@v2
with:
image: ${{ env.IMAGE_NAME }}
tags: ${{ env.STABLE_TAG }} ${{ env.STABLE_TAG == 'main' && 'latest' || '' }}
containerfiles: |
./Containerfile
labels: |
${{ env.EXPIRATION_LABEL }}
quipucords.backend.git_sha=${{ github.sha }}
extra-args: |
--ulimit nofile=4096:4096

- name: Push To quay.io
# Forks that do not set secrets and override the variables may fail this step.
uses: redhat-actions/push-to-registry@v2
with:
image: ${{ env.IMAGE_NAME }}
tags: ${{ steps.build-image.outputs.tags }}
registry: ${{ env.REGISTRY }}
username: ${{ secrets.QUAYIO_USERNAME }}
password: ${{ secrets.QUAYIO_PASSWORD }}
continue-on-error: true
14 changes: 6 additions & 8 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,12 @@ jobs:
- name: Install Node.js packages
if: ${{ steps.modules-cache.outputs.cache-hit != 'true' }}
run: npm install
- name: Lint and test
run: npm test
- name: Code coverage
if: ${{ success() && contains(matrix.node-version, env.COV_NODE_VERSION) }}
uses: codecov/[email protected]
- name: Confirm build integration
if: ${{ success() }}
run: npm run build
- name: Linting
run: npm run test:ci-lint
- name: Build integration
run: npm run test:ci-build
- name: Unit tests
run: npm run test:ci-coverage
- name: Compress upstream assets
if: ${{ success() && startsWith(matrix.node-version, env.COV_NODE_VERSION) && startsWith(github.ref, 'refs/tags/') }}
run: |
Expand Down
18 changes: 18 additions & 0 deletions Containerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM registry.access.redhat.com/ubi9/nodejs-18 as npm_builder
# Become root before installing anything
USER root
RUN dnf update -y && dnf clean all

# install dependencies in a separate layer to save dev time
WORKDIR /app
COPY package.json package-lock.json .
RUN npm install

COPY . .
RUN npm run build

FROM registry.access.redhat.com/ubi9/nginx-122
COPY --from=npm_builder /app/build /opt/app-root/src
COPY deploy/nginx.conf /etc/nginx/nginx.conf.template
COPY deploy/entrypoint.sh /opt/app-root/.
CMD ["/bin/bash", "/opt/app-root/entrypoint.sh"]
14 changes: 14 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

QUIPUCORDS_UI_CONTAINER_TAG ?= quipucords-ui

help:
@echo "Please use 'make <target>' where <target> is one of:"
@echo " help to show this message"
@echo " build-container to build the container image for the quipucords UI"

all: help

build-container:
podman build \
-t $(QUIPUCORDS_UI_CONTAINER_TAG) --ulimit nofile=4096:4096 .

1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# Quipucords UI
[![Build Status](https://github.com/quipucords/quipucords-ui/actions/workflows/integration.yml/badge.svg)](https://github.com/quipucords/quipucords-ui/actions/workflows/integration.yml)
[![codecov](https://codecov.io/gh/quipucords/quipucords-ui/branch/main/graph/badge.svg)](https://codecov.io/gh/quipucords/quipucords-ui)
[![License](https://img.shields.io/github/license/quipucords/quipucords-ui.svg)](https://github.com/quipucords/quipucords-ui/blob/main/LICENSE)

Web user interface for [Quipucords](https://github.com/quipucords/quipucords), based on [Patternfly](https://www.patternfly.org/)
Expand Down
35 changes: 35 additions & 0 deletions deploy/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/bash

set -e

# on podman, host.containers.internal resolves to the host. this is equivalent to
# host.docker.internal for docker.
export QUIPUCORDS_SERVER_URL="${QUIPUCORDS_SERVER_URL:-http://host.containers.internal:8000}"
CERTS_PATH="/opt/app-root/certs"

# verify if user provided certificates exist or create a self signed certificate.
mkdir -p ${CERTS_PATH}

if ([ -f "${CERTS_PATH}/server.key" ] && [ -f "${CERTS_PATH}/server.crt" ]); then
echo "Using user provided certificates..."
openssl rsa -in "${CERTS_PATH}/server.key" -check
openssl x509 -in "${CERTS_PATH}/server.crt" -text -noout
elif [ ! -f "${CERTS_PATH}/server.key" ] && [ ! -f "${CERTS_PATH}/server.crt" ]; then
echo "No certificates provided. Creating them..."
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout "${CERTS_PATH}/server.key" \
-out "${CERTS_PATH}/server.crt" \
-subj "/C=US/ST=Raleigh/L=Raleigh/O=IT/OU=IT Department/CN=example.com"
else
echo "Either key or certificate is missing."
echo "Please provide both named as server.key and server.crt."
echo "Tip: this container expects these files at ${CERTS_PATH}/"
exit 1
fi

envsubst "\$QUIPUCORDS_APP_PORT,\$QUIPUCORDS_APP_ENABLE_V2UI,\$QUIPUCORDS_SERVER_URL" \
< /etc/nginx/nginx.conf.template \
> /etc/nginx/nginx.conf

mkdir -p /var/log/nginx
nginx -g "daemon off;"
75 changes: 75 additions & 0 deletions deploy/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# configuration shamelessly copied from https://github.com/sclorg/nginx-container/blob/master/examples/1.22/test-app/nginx.conf
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/

worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
worker_connections 1024;
}

http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

sendfile on;
tcp_nopush on;
keepalive_timeout 65;
types_hash_max_size 4096;

include /etc/nginx/mime.types;
default_type application/octet-stream;

server {
listen 8079 default_server;
listen [::]:8079 default_server;
server_name _;
return 301 https://$host$request_uri;
}

server {
listen ${QUIPUCORDS_APP_PORT} ssl;
listen [::]:${QUIPUCORDS_APP_PORT} ssl;
server_name _;
root /opt/app-root/src;

ssl_certificate "/opt/app-root/certs/server.crt";
ssl_certificate_key "/opt/app-root/certs/server.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers PROFILE=SYSTEM;
ssl_prefer_server_ciphers on;

location / {
set $enable_v2ui "${QUIPUCORDS_APP_ENABLE_V2UI}";
if ($enable_v2ui = "0") {
rewrite (.*) /ui-v1$1 last;
}
try_files $uri /index.html;
}
location /ui-v1/ {
rewrite /ui-v1/(.*) /$1 break;
proxy_pass ${QUIPUCORDS_SERVER_URL};
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass_header X-CSRFToken;
}
location /api/ {
proxy_pass ${QUIPUCORDS_SERVER_URL};
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass_header X-CSRFToken;
}
}
}

8 changes: 4 additions & 4 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ module.exports = {
collectCoverageFrom: ['src/**/*.{ts,tsx}', '!src/**/.*/**', '!src/**/**/index.{ts,tsx}'],
coverageThreshold: {
global: {
branches: 50,
functions: 50,
lines: 50,
statements: 50
branches: 60,
functions: 80,
lines: 80,
statements: 80
}
},
moduleFileExtensions: ['web.js', 'js', 'web.ts', 'ts', 'web.tsx', 'tsx', 'json', 'web.jsx', 'jsx', 'node'],
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@
"start:js": "export NODE_ENV=development; weldable -l ts -x ./config/webpack.dev.js",
"start:open": "xdg-open $PROTOCOL://$HOST:$PORT/login || open $PROTOCOL://$HOST:$PORT/login",
"start:stage": "export PROTOCOL=https; export HOST=127.0.0.1; export PORT=${PORT:-3000}; export MOCK_PORT=${MOCK_PORT:-9443}; run-p -l api:stage start:js start:open",
"test": "export NODE_ENV=test; run-s test:spell* test:types test:lint test:ci",
"test:ci": "export CI=true; jest ./src --coverage",
"test": "export NODE_ENV=test; run-s test:ci-lint test:ci-build test:ci-coverage",
"test:ci-build": "run-s build",
"test:ci-coverage": "export CI=true; jest ./src --coverage",
"test:ci-lint": "run-s test:spell* test:types test:lint",
"test:clearCache": "jest --clearCache",
"test:dev": "export NODE_ENV=test; run-s test:lint test:local",
"test:integration": "jest --roots=./tests",
Expand Down
10 changes: 7 additions & 3 deletions public/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"confirmation_heading_add-scan": " Are you sure you want to cancel this scan?",
"confirmation_title_delete-scan": "Delete Scan",
"confirmation_heading_delete-scan": "Are you sure you want to delete the scan <0>{{name}}</0>?",
"confirmation_heading_delete-credential": "Are you sure you want to delete the credential <0>{{name}}</0>?",
"confirmation_heading_delete-credential": "Are you sure you want to delete the credential {{name}}?",
"confirmation_heading_delete-credential_other": "Are you sure you want to delete the following credentials?",
"confirmation_title_delete-credential": "Delete Credential",
"confirmation_title_delete-credential_other": "Delete Credentials",
Expand Down Expand Up @@ -306,8 +306,12 @@
"description_add-source_hidden_error_edit": "{{message}}",
"description_credential": "Credential was added",
"description_credential_edit": "Credential was updated",
"description_deleted-credential": "Deleted credential {{name}}",
"description_deleted-credential_other": "Deleted credentials {{name}} and more",
"description_deleted-credential_one": "Credential {{name}} was successfully deleted.",
"description_deleted-credential_other": "Credentials {{name}} were successfully deleted.",
"description_deleted-credentials-skipped-credentials_one": "The following could be successfully deleted: {{deleted_names}}. Credential {{skipped_names}} could not be deleted due to an attached source.",
"description_deleted-credentials-skipped-credentials_other": "The following could be successfully deleted: {{deleted_names}}. Credentials {{skipped_names}} could not be deleted due to attached sources.",
"description_skipped-credential_one": "Credential {{name}} could not be deleted due to an attached source.",
"description_skipped-credential_other": "Credentials {{name}} could not be deleted due to attached sources.",
"description_deleted-credential_error": "Error removing credential {{name}}. {{message}}",
"description_deleted-credential_error_other": "Error removing credentials {{name}} and more. {{message}}",
"description_deleted-source": "Source {{name}} deleted successfully.",
Expand Down
5 changes: 5 additions & 0 deletions src/helpers/__tests__/helpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ it(`should throw an error if the timestamp is not valid`, () => {
expect(() => helpers.getTimeDisplayHowLongAgo('')).toThrow(`Invalid timestamp: `);
});

it('should support generated strings and flags', () => {
expect(helpers.generateId()).toBe('generatedid-');
expect(helpers.generateId('lorem')).toBe('lorem-');
});

describe('getAuthType', () => {
const generateAuthType = partialCredential =>
helpers.getAuthType({
Expand Down
Loading
Loading