forked from asuwebdesign/developer-intelligence-prototype
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Integrate the dashboard with Pelorus using the new pelorus-api, and s…
…et it up to be deployable to OpenShift. (#3) * keycloak init * update with KeyCloak * wip add appList * wip integrate DORA metrics * wip 4 DORA working * wip not working * Working * Refactor to have useEffect retrigger dashboard components * chart for LTFC * sort dates in LTFC * wip for ltfc table * add table to LTFC * Add percent change badges for ltfc and df * fix useState inits, and fix missing key in table * Add a github action to build the app into a NodeJS Image * Update trigger * trigger on pr * Change namespace * Try vars instead of env * Add dev tag * wip add openshift oauth * wip OpenShift OAuth - hardcoded URLs * externalize OpenShift OAuth Config * remove comments from options.js * update scope to user:info * Updated measure tabs to recalculate on date selection change * For now, go to 5 decimal places * Update to pass a timestamp along with a date range to the api call * updated to pass query param per new api updates. Date picker now works * Finally got the bug fixed, using a custom event handler * OK, date picker minimally works now * Remove unused code * Refactor to store the selected date in the browser cache so it survives a refresh * Add a few helpful comments * Get chart and table populating * Further refactors * fix issue with locality in the chart rendering * Code changes for enabling the MTTR chart and table, plus icon improvements * Enable chart and table for change failure rate * Get change sine list badges working for mttr and cfr * Modify the 'to' date to the end of the day (i.e. 23:59:59) instead of the start so we get data for that day (asuwebdesign#8) * Refactor to gather all the API calls into one place (asuwebdesign#9) * Refactor to gather all the API calls into one place * Fix spacing * Fix ESlint errors * Add a login with openshift option to dashboard homepage * Add multi-stage build containerfile for packaging dashboard in a more opinionated manner * Allow package-lock.json to be committed * Add deployment files and muck with a mysterious logo render issue * Add a local user/pass mechanism that will only redner for local development * Add commit_link to the ltfc table * Add labelling for commit data to the image * Starting a refactor of the dashboard to make it a server-side component, moving client side state handling into child components * Ensure user selections are not wiped out when page reloads * Convert ltfc tab trigger * Convert deployment-frequency data components * df tables does not need appname prop * Nevermind, i guess we do * Convert MTTR to new component structure * Add change failure rate in new component format * Fix openshift sign-in logo * Display image sha in lead time for change data table to add context for the user --------- Co-authored-by: Charro Gruver <null> Co-authored-by: Charro Gruver <39659182+cgruver@users.noreply.github.com>
- Loading branch information
Showing
69 changed files
with
5,430 additions
and
3,019 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Recommended to have .dockerignore file with the following content | ||
Containerfile | ||
Dockerfile | ||
.dockerignore | ||
node_modules | ||
npm-debug.log | ||
README.md | ||
.next | ||
.git |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
--- | ||
|
||
name: CD | ||
|
||
on: [push, pull_request] | ||
|
||
|
||
jobs: | ||
|
||
build_image: | ||
|
||
# The type of runner that the job will run on | ||
runs-on: ubuntu-latest | ||
|
||
# This workflow builds a container image of a java | ||
# application using the source to image build strategy, | ||
# and pushes the image to quay.io. | ||
env: | ||
IMAGE_NAME: pelorus-dashboard | ||
TAGS: dev ${{ github.sha }} | ||
|
||
steps: | ||
|
||
- name: Checkout | ||
uses: actions/checkout@v2 | ||
|
||
# Setup S2i and Build container image | ||
- name: Setup and Build | ||
id: build_image | ||
uses: redhat-actions/s2i-build@v2 | ||
with: | ||
path_context: '.' | ||
# Builder image for a java project | ||
builder_image: 'registry.access.redhat.com/ubi9/nodejs-18:1' | ||
image: ${{ env.IMAGE_NAME }} | ||
tags: ${{ env.TAGS }} | ||
|
||
# Push Image to Quay registry | ||
- name: Push To Quay Action | ||
uses: redhat-actions/push-to-registry@v2 | ||
with: | ||
image: ${{ steps.build_image.outputs.image }} | ||
tags: ${{ steps.build_image.outputs.tags }} | ||
registry: quay.io/${{ vars.QUAY_NAMESPACE }} | ||
username: ${{ secrets.QUAY_USERNAME }} | ||
password: ${{ secrets.QUAY_PASSWORD }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# adapted from https://github.com/vercel/next.js/tree/canary/examples/with-docker | ||
|
||
# Install dependencies only when needed | ||
FROM registry.access.redhat.com/ubi9/nodejs-20 AS deps | ||
USER 0 | ||
WORKDIR /app | ||
|
||
# Install dependencies based on the preferred package manager | ||
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./ | ||
RUN \ | ||
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \ | ||
elif [ -f package-lock.json ]; then npm ci; \ | ||
elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i; \ | ||
else echo "Lockfile not found." && exit 1; \ | ||
fi | ||
|
||
# Rebuild the source code only when needed | ||
FROM registry.access.redhat.com/ubi9/nodejs-20 AS builder | ||
USER 0 | ||
WORKDIR /app | ||
COPY --from=deps /app/node_modules ./node_modules | ||
COPY . . | ||
|
||
# Next.js collects completely anonymous telemetry data about general usage. | ||
# Learn more here: https://nextjs.org/telemetry | ||
# Uncomment the following line in case you want to disable telemetry during the build. | ||
ENV NEXT_TELEMETRY_DISABLED 1 | ||
|
||
# If using yarn uncomment out and comment out npm below | ||
# RUN yarn build | ||
|
||
# If using npm comment out above and use below instead | ||
RUN npm run build | ||
|
||
# Production image, copy all the files and run next | ||
FROM registry.access.redhat.com/ubi9/nodejs-20-minimal AS runner | ||
USER 0 | ||
WORKDIR /app | ||
|
||
ENV NODE_ENV production | ||
# Uncomment the following line in case you want to enable telemetry during runtime. | ||
ENV NEXT_TELEMETRY_DISABLED 1 | ||
|
||
COPY --from=builder /app/public ./public | ||
|
||
# Automatically leverage output traces to reduce image size | ||
# https://nextjs.org/docs/advanced-features/output-file-tracing | ||
COPY --from=builder --chown=1001:1001 /app/.next/standalone ./ | ||
COPY --from=builder --chown=1001:1001 /app/.next/static ./.next/static | ||
|
||
USER 1001 | ||
|
||
EXPOSE 3000 | ||
|
||
ENV PORT 3000 | ||
ENV NEXT_PUBLIC_PELORUS_API_URL https://pelorus-api-pelorus-api.apps.cluster-kwcgn.kwcgn.sandbox558.opentlc.com | ||
|
||
ARG ORIGIN_URL=unknown | ||
ARG COMMIT_DATE=unknown | ||
ARG COMMIT_ID=unknown | ||
|
||
LABEL io.openshift.build.source-location=${ORIGIN_URL} | ||
LABEL io.openshift.build.commit.date=${COMMIT_DATE} | ||
LABEL io.openshift.build.commit.id=${COMMIT_ID} | ||
|
||
CMD ["node", "server.js"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
'use server' | ||
import { signIn } from 'next-auth/react' | ||
|
||
export async function signInUser (formData) { | ||
signIn("credentials", formData) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,77 @@ | ||
import NextAuth from "next-auth" | ||
import GithubProvider from "next-auth/providers/github" | ||
import GoogleProvider from "next-auth/providers/google" | ||
import CredentialsProvider from "next-auth/providers/credentials" | ||
|
||
export const options = { | ||
providers: [ | ||
GithubProvider({ | ||
clientId: process.env.GITHUB_ID, | ||
clientSecret: process.env.GITHUB_SECRET, | ||
}), | ||
GoogleProvider({ | ||
clientId: process.env.GOOGLE_CLIENT_ID, | ||
clientSecret: process.env.GOOGLE_CLIENT_SECRET, | ||
async function makeUserinfoRequest(context) { | ||
console.log(context) | ||
|
||
const res = await fetch( | ||
'https://kubernetes.default.svc/apis/user.openshift.io/v1/users/~', | ||
{ | ||
headers: new Headers({ | ||
'Authorization': 'Bearer '+context.tokens.access_token, | ||
'Content-Type': 'application/json' | ||
}), | ||
} | ||
) | ||
|
||
return res.json() | ||
} | ||
|
||
const providers = [ | ||
{ | ||
id: "openshift", | ||
name: "OpenShift", | ||
type: "oauth", | ||
wellKnown: "https://openshift.default.svc/.well-known/oauth-authorization-server", | ||
authorization: { params: { scope: "user:info" } }, | ||
userinfo: { | ||
url: "https://kubernetes.default.svc/apis/user.openshift.io/v1/users/~", | ||
// The result of this method will be the input to the `profile` callback. | ||
async request(context) { | ||
// context contains useful properties to help you make the request. | ||
return await makeUserinfoRequest(context) | ||
} | ||
}, | ||
profile(profile) { | ||
return { | ||
id: profile.metadata.uid, | ||
username: profile.metadata.name, | ||
name: profile.metadata.name, | ||
email: profile.metadata.name, | ||
groups: profile.groups | ||
} | ||
}, | ||
clientId: process.env.OPENSHIFT_CLIENT_ID, // this should be a service account with name format system:serviceaccount:<namespace>:<serviceaccount name> | ||
clientSecret: process.env.OPENSHIFT_CLIENT_SECRET // this is the service account token, which can be extracted from a secret | ||
} | ||
] | ||
|
||
// Conditionally add the basic auth provider in development mode | ||
if (process.env.NODE_ENV === "development") { | ||
providers.push( | ||
CredentialsProvider({ | ||
id: "local", | ||
name: "Local", | ||
credentials: { | ||
username: { label: "Username", type: "text" }, | ||
password: { label: "Password", type: "password" } | ||
}, | ||
authorize(credentials) { | ||
if (credentials.username === "pelorus" && credentials.password === "pelorus") { | ||
return { id: 1, name: "pelorus", email: "pelorus@example.com" } | ||
} | ||
return null | ||
} | ||
}) | ||
], | ||
) | ||
} | ||
|
||
export const options = { | ||
providers, | ||
pages: { | ||
signIn: '/', | ||
signOut: '/', | ||
} | ||
} | ||
|
||
export default NextAuth(options) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { getDaysBetweenDates } from '@/lib/date-funcs'; | ||
|
||
// Get initial list of Apps that Pelorus has data for | ||
export async function getApps() { | ||
const response = await fetch(`${process.env.NEXT_PUBLIC_PELORUS_API_URL}/sdp/apps?range=1w`) | ||
if (!response.ok) { | ||
throw new Error('Failed to fetch list of Apps from Pelorus') | ||
} | ||
return response.json() | ||
} | ||
|
||
// Lead time for change | ||
export async function fetchLeadTimeForChangeData(appName, dateRange) { | ||
const req = `${process.env.PELORUS_API_URL}/sdp/lead_time_for_change/${appName}/data?range=${getDaysBetweenDates(dateRange)}d&start=${dateRange.to.getTime() / 1000}`; | ||
console.log(req) | ||
const response = await fetch(req); | ||
|
||
if (!response.ok) { | ||
throw new Error("Failed to fetch Lead Time for Change data"); | ||
} | ||
|
||
const data = await response.json(); | ||
return data.sort((d1, d2) => (d1.timestamp > d2.timestamp) ? 1 : (d1.timestamp < d2.timestamp) ? -1 : 0); | ||
} | ||
|
||
// Change Failure Rate | ||
export async function fetchChangeFailureRateData(appName, dateRange) { | ||
const req = `${process.env.PELORUS_API_URL}/sdp/change_failure_rate/${appName}/data?range=${getDaysBetweenDates(dateRange)}d&start=${Math.floor(dateRange.to.getTime() / 1000)}`; | ||
console.log(req) | ||
const response = await fetch(req); | ||
|
||
if (!response.ok) { | ||
throw new Error("Failed to fetch Change Failure Rate data"); | ||
} | ||
|
||
const data = await response.json(); | ||
return data.sort((d1, d2) => (d1.timestamp > d2.timestamp ? 1 : d1.timestamp < d2.timestamp ? -1 : 0)); | ||
} | ||
|
||
export function getDORA(appName) { | ||
|
||
const dora = {mttr: 0, cfr: 0, df: 0, ltfc: 0} | ||
const cfr = getCFR(appName) | ||
dora.cfr = cfr.cfr | ||
const df = getDF(appName) | ||
dora.df = df.df | ||
const mttr = getMTTR(appName) | ||
dora.mttr = mttr.mttr | ||
const ltfc = getLTFC(appName) | ||
dora.ltfc = ltfc.ltfc | ||
return dora | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.