diff --git a/src/BPManager.ts b/src/BPManager.ts index 1d7a3f4..3f31ea3 100644 --- a/src/BPManager.ts +++ b/src/BPManager.ts @@ -11,7 +11,7 @@ export class BPManager { // --- private readonly bpSets: - Record = {} + Record = {} private readonly bpSetMetadatas: Record = {} @@ -32,10 +32,10 @@ export class BPManager { continue const bpSetPath = path.join(bpSetFile.parentPath, bpSetFile.name) - const bpSetClasses = await import('../' + bpSetPath) as Record + const bpSetClasses = await import('../' + bpSetPath) as Record BPSet> for (const bpSetClass of Object.keys(bpSetClasses)) - this.bpSets[bpSetClass] = bpSetClasses[bpSetClass] + this.bpSets[bpSetClass] = new bpSetClasses[bpSetClass]() } } @@ -49,11 +49,36 @@ export class BPManager { nonCompliantResources: [], compliantResources: [], status:'LOADED', + errorMessage: [], idx } } } + public async runCheck() { + for (const name in this.bpSets) { + this.bpSetMetadatas[name].status = 'CHECKING' + + const result = await this.bpSets[name].check() + .catch((err) => { + this.bpSetMetadatas[name].status = 'ERROR' + this.bpSetMetadatas[name].errorMessage.push({ + date: new Date(), + message: err + }) + + return undefined + }) + + if (result === undefined) + continue + + this.bpSetMetadatas[name].compliantResources = result.compliantResources + this.bpSetMetadatas[name].nonCompliantResources = result.nonCompliantResources + this.bpSetMetadatas[name].status = 'FINISHED' + } + } + public readonly getBPSet = (name: string) => this.bpSets[name] diff --git a/src/WebServer.ts b/src/WebServer.ts index bd28c6a..772decc 100644 --- a/src/WebServer.ts +++ b/src/WebServer.ts @@ -15,6 +15,7 @@ export class WebServer { this.app.use(express.static('./public')) this.app.get('/', this.getMainPage.bind(this)) + this.app.get('/check_all', this.runCheck.bind(this)) this.app.use(this.error404) this.app.listen(this.port, this.showBanner.bind(this)) @@ -41,6 +42,12 @@ export class WebServer { }) } + + private runCheck(_: Request, res: Response) { + void this.bpManager.runCheck() + res.redirect('/') + } + private error404 (_: Request, res: Response) { res.status(404).send({ success: false, message: 'Page not found' }) } diff --git a/src/types.d.ts b/src/types.d.ts index 6b50a5b..d49a02a 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -51,4 +51,8 @@ export interface BPSetMetadata { compliantResources: string[] status: 'LOADED' | 'CHECKING' | 'ERROR' | 'FINISHED' idx: number + errorMessage: { + date: Date, + message: string + }[] } diff --git a/views/index.ejs b/views/index.ejs index 39b62be..782082d 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -9,8 +9,7 @@
-

BPSets (<%= bpLength %>)

-

Created by Minhyeok Park

+ <%- include('partial/page_header.ejs') %> @@ -31,65 +30,9 @@ <% metadatas.forEach((metadata) => { %> - - - - - - <% if (metadata.status === 'FINISHED') { %> - <% if (metadata.nonCompliantResources.length < 1) { %> - - <% } else { %> - - <% } %> - - <% } else if (metadata.status === 'CHECKING') { %> - - <% } else if (metadata.status === 'ERROR') { %> - - <% } else if (metadata.status === 'LOADED') { %> - - <% } %> - - - - - + <%- include('./partial/bpset_item.ejs', { metadata }) %> + <%- include('./partial/bpset_details.ejs', { metadata }) %> + <%- include('./partial/bpset_logs.ejs', { metadata }) %> <% }) %> <% }) %> @@ -97,5 +40,9 @@ + diff --git a/views/partial/bpset_actions.ejs b/views/partial/bpset_actions.ejs new file mode 100644 index 0000000..99b8199 --- /dev/null +++ b/views/partial/bpset_actions.ejs @@ -0,0 +1,8 @@ + diff --git a/views/partial/bpset_details.ejs b/views/partial/bpset_details.ejs new file mode 100644 index 0000000..1b66f76 --- /dev/null +++ b/views/partial/bpset_details.ejs @@ -0,0 +1,59 @@ +<% + const priorityLabel = ['CRITICAL', 'Required', 'Recommend'][metadata.priority-1] || 'Recommend' + const priorityColor = ['danger', 'warning', 'secondary'][metadata.priority-1] || 'secondary' +%> + + + + diff --git a/views/partial/bpset_item.ejs b/views/partial/bpset_item.ejs new file mode 100644 index 0000000..8244793 --- /dev/null +++ b/views/partial/bpset_item.ejs @@ -0,0 +1,19 @@ +<% + const priorityLabel = ['CRITICAL', 'Required', 'Recommend'][metadata.priority-1] || 'Recommend' + const priorityColor = ['danger', 'warning', 'secondary'][metadata.priority-1] || 'secondary' +%> + + + + + + + + + <%- include('./bpset_progress.ejs', { metadata }) %> + <%- include('./bpset_actions.ejs', { metadata }) %> + diff --git a/views/partial/bpset_logs.ejs b/views/partial/bpset_logs.ejs new file mode 100644 index 0000000..919a7fd --- /dev/null +++ b/views/partial/bpset_logs.ejs @@ -0,0 +1,34 @@ + + + diff --git a/views/partial/bpset_progress.ejs b/views/partial/bpset_progress.ejs new file mode 100644 index 0000000..730ce49 --- /dev/null +++ b/views/partial/bpset_progress.ejs @@ -0,0 +1,57 @@ +<% + const passResources = metadata.compliantResources.length + const failResources = metadata.nonCompliantResources.length + + const totalResources = passResources + failResources + const passPercent = + totalResources > 0 + ? passResources / totalResources * 100 + : 100 + + const isPass = failResources < 1 +%> + +<% if (metadata.status === 'FINISHED') { %> + + + +<% } %> + +<% if (metadata.status === 'CHECKING') { %> + +<% } %> + +<% if (metadata.status === 'ERROR') { %> + +<% } %> + +<% if (metadata.status === 'LOADED') { %> + +<% } %> diff --git a/views/partial/page_header.ejs b/views/partial/page_header.ejs new file mode 100644 index 0000000..06c8ac7 --- /dev/null +++ b/views/partial/page_header.ejs @@ -0,0 +1,23 @@ +
+
+

BPSets (<%= bpLength %>)

+

Created by Minhyeok Park

+
+ +
+
+

Pass

+

<%= %>

+
+
+

Fail

+
+
+

Error

+
+
+ +
+ Check All +
+
#<%= metadata.idx + 1 %><%= metadata.name %><%= metadata.bestPracticeCategory %> - <%= metadata.priority %> - <%= ['CRITICAL', 'Required', 'Recommend'][metadata.priority-1] %> - PassFail -
-
-
- (<%= metadata.compliantResources.length %>/<%= metadata.nonCompliantResources.length + metadata.compliantResources.length %>) -
-
-
-
-
-
-
-
-
-
-
-
-
-
- - - -
-
-
-
-

<%= metadata.name %>

-

<%= metadata.description %>

- -

Category: <%= metadata.bestPracticeCategory %> <%= metadata.awsServiceCategory %> - <%= metadata.awsService %>

-

Priority: <%= metadata.priority %> - <%= ['CRITICAL', 'Required', 'Recommend'][metadata.priority-1] %> (<%= metadata.priorityReason %>)

-
-
-
+
+ + + + +
+
+
+
+

<%= metadata.name %>

+

<%= metadata.description %>

+ +

+ Category: + <%= metadata.bestPracticeCategory %> + <%= metadata.awsServiceCategory %> - <%= metadata.awsService %> +

+ +

+ Priority: + + <%= metadata.priority %> - <%= priorityLabel %> + + + <%= metadata.priorityReason %> +

+ +

Operations used in check function

+
+ <% metadata.commandUsedInCheckFunction.forEach(({ name, reason }) => { %> +
+
+
<%= name %>
+
+ <%= reason %> +
+
+
+ <% }) %> +
+
+ +

Operations used in fix function

+
+ <% metadata.commandUsedInFixFunction.forEach(({ name, reason }) => { %> +
+
+
<%= name %>
+
+ <%= reason %> +
+
+
+ <% }) %> +
+
+
+
#<%= metadata.idx + 1 %><%= metadata.name %><%= metadata.bestPracticeCategory %> + + <%= metadata.priority %> - <%= priorityLabel %> + +
+
+
+

Non-Compliant Resources

+
    + <% metadata.nonCompliantResources.forEach((id) => { %> +
  • <%= id %>
  • + <% }) %> +
+ +
+ +

Compliant Resources

+
    + <% metadata.compliantResources.forEach((id) => { %> +
  • <%= id %>
  • + <% }) %> +
+
+ +

Error Logs

+
    + <% metadata.errorMessage.forEach((log) => { %> +
  • +

    <%= log.date %>

    +
    <%= log.message %>
    +
  • + <% }) %> +
+
+
+
+ + <%= isPass ? 'Pass' : 'Fail' %> + + +
+
+
+ (<%= passResources %>/<%= totalResources %>) +
+
+
+
+ +

Progressing

+
+
+
+
+ +

Error

+
+
+
+
+ +

Ready

+