Skip to content

Commit

Permalink
feat: add announcements section to the website
Browse files Browse the repository at this point in the history
Signed-off-by: Adam Talbot <[email protected]>
  • Loading branch information
ThatsMrTalbot authored and SgtCoDFish committed Mar 15, 2024
1 parent 6726fd3 commit f54a952
Show file tree
Hide file tree
Showing 7 changed files with 338 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .spelling
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,7 @@ v1.13.0.
v1.13.1
v1.13.2
v1.13.3
v1.13.4
v1.13.
v1.12.5
v1.12.6
Expand Down Expand Up @@ -717,3 +718,10 @@ md#renew
# correct spelling. The spelling "x509" and "X509" are incorrect.

X.509

# Announcements

Logics
OpenSSF
OSS-Fuzz
Korczynski
1 change: 1 addition & 0 deletions components/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ function closeMenu(setOpen) {

function NavItem({ active, item, setOpen = null }) {
active = active === '/[...docs]' ? '/docs' : active
active = active === '/announcements/[[...article]]' ? '/announcements' : active
const isActive = active === item.href
return (
<li key={item.href}>
Expand Down
24 changes: 24 additions & 0 deletions content/announcements/2024-03-04-cert-manager-security-audit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
slug: cert-manager-security-audit
title: cert-manager completes it security audit!
description: As part of our graduation processes cert-manager has completed a security audit of the project
date: 03-04-2024
---

Between late 2023 and early 2024 the cert-manager project has undergone a security audit by the team at [Ada Logics](https://adalogics.com/). This is part of the ongoing [graduation of cert-manager](https://github.com/cncf/toc/pull/1212).

The goal of the engagement was to assess cert-managers code quality, its development and its release practices. The thread model was determined along with potential threat actors, the codebase was reviewed, dependencies were evaluated and the project was integrated into OSS-Fuzz.

The threat model of cert-manager is built upon the existing threat model for acquiring certificates from issuers. However, the specific procedures for acquiring certificates as documented by external entities were not scrutinized in this audit.

Threat actors include contributors to cert-manager or any of its dependencies, users on the clusters where cert-manager is deployed and external users in cases where cert-manager is deployed in use cases that process input from untrusted internet users.

For a full breakdown of the threat model and actors, see the [full report](TODO).

A total of 8 issues were raised as part of the audit, of which 5 were low severity, 2 were moderate severity and 1 was informational. All issues have been resolved as of cert-manager 1.12.8, v1.13.4 and 1.14.3.

Dependencies of the cert-manager project were assessed using [OpenSSF Scorecard](https://github.com/ossf/scorecard). This is a process that scores repositories using several factors to build a picture of their maintenance status and suitability. Based on the results, three dependencies have been removed from cert-manager. The full findings and scoring for dependencies can be found on the [full report](TODO).

On top of assessing existing dependencies, the cert-manager team have [opened an issue](TODO) to investigate how we can implement a strategy for evaluating new dependencies as they arise.

Thanks to to team at [Ada Logics](https://adalogics.com/), in particular Adam Korczynski and David Korczynski for completing this audit, it was an all-round pleasant experience with no real hiccups. Also thanks to CNCF who facilitated this audit and are key to the ongoing support of cert-manager.
5 changes: 5 additions & 0 deletions content/pages/article.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const meta = {
pageTitle: '- cert-manager Announcement',
title: 'cert-manager Announcements',
description: ''
}
4 changes: 4 additions & 0 deletions content/pages/site.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ export const meta = {
text: 'Documentation',
href: '/docs'
},
{
text: 'Announcements',
href: '/announcements'
},
{
text: 'Support',
href: '/support'
Expand Down
152 changes: 152 additions & 0 deletions lib/announcements.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import { getRawFile } from 'lib/files'
import { join } from 'path'
import { readdir } from 'fs/promises'
import { VFile } from 'vfile'
import { serialize } from 'next-mdx-remote/serialize'
import matter from 'gray-matter'
import { marked } from 'marked'
import GithubSlugger from 'github-slugger'
import rehypeSlug from 'rehype-slug'
import rehypeAutolink from 'rehype-autolink-headings'

import { codeImport as remarkCodeImport } from 'remark-code-import'
import remarkInlineLinks from 'remark-inline-links'
import remarkGfm from 'remark-gfm'
import remarkHeadingId from 'lib/remark-plugins/heading-ids'
import remarkExternalLinks from 'remark-external-links'
import remarkRewriteImages from 'lib/remark-plugins/images'


export async function getArticles() {
const files = await readdir(join(process.cwd(), 'content', 'announcements'))
const paths = await Promise.all(
files.map(async (file) => {
const rawFileContents = await getRawFile(join('announcements', file));
const { data } = matter(rawFileContents);
const date = new Date(data.date);
const slug = getSlug(date, data.slug)

return {
title: data.title,
description: data.description,
date: date,
path: slug.join("/"),
slug: slug,
file: file,
}
}
))

paths.sort((a, b) => new Date(b.date) - new Date(a.date))

return paths
}

export async function pageProps({params}) {
const articles = await getArticles()
const article = articles.find((article) => article.path == params.article.join("/"))
if (!article) return {
notFound: true
}

const path = join('announcements', article.file)
const mdxPathAbsolute = join(process.cwd(), 'content', path)
const mdxRawContent = await getRawFile(path)
const { content, data } = matter(mdxRawContent)
if (!data.title) {
data.title = ''
}

const slugger = new GithubSlugger()
const mdxSource = await serialize(
new VFile({
value: content,
path: mdxPathAbsolute
}),
{
parseFrontmatter: false,
scope: { data },
mdxOptions: {
mdExtensions: [],
mdxExtensions: ['.md', '.mdx'],
rehypePlugins: [
rehypeSlug,
[
rehypeAutolink,
{
behavior: 'append',
properties: {
className: ['btn-copy-link', 'invisible']
},
content: {
type: 'element',
tagName: 'svg',
properties: {
className: ['h-6', 'w-6', 'ml-2', 'docs-copy-btn'],
xmlns: 'http://www.w3.org/2000/svg',
fill: 'none',
viewBox: '0 0 24 24',
stroke: 'currentColor'
},
children: [
{
type: 'element',
tagName: 'path',
properties: {
strokeLinecap: 'round',
strokeLinejoin: 'round',
strokeWidth: 2,
d: 'M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1'
},
children: []
}
]
}
}
]
],
remarkPlugins: [
remarkHeadingId,
remarkGfm,
remarkCodeImport,
[
remarkRewriteImages,
{ destination: process.env.ASSETS_DESTINATION }
],
remarkInlineLinks,
[remarkExternalLinks, { target: false, rel: ['nofollow'] }],
]
},
target: ['esnext']
}
)

const markdownTokens = marked.lexer(content)
const headings = markdownTokens
.filter((t) => t.type === 'heading')
.map((heading) => {
heading.slug = slugger.slug(heading.text)
return heading
})

const firstHeadingText =
headings && headings.length > 0 ? headings[0].text : ''
const title = data.title.length > 0 ? data.title : firstHeadingText

return {
title,
date: article.date.toDateString(),
frontmatter: data,
source: mdxSource,
tocHeadings: headings,
}
}

function getSlug(date, slug) {
return [
'' + date.getFullYear(),
('0' + date.getMonth()+1).slice(-2),
('0' + date.getDate()).slice(-2),
slug,
]
}
144 changes: 144 additions & 0 deletions pages/announcements/[[...article]].jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
// You probably wonder why this file, [...docs].jsx, contains square brackets and
// dots. The reason is that the only way to do "dynamic routes" in Next.js is to
// use a file name containing square brackets and dots. You can learn more at:
// https://nextjs.org/docs/routing/dynamic-routes.

import { MDXRemote } from 'next-mdx-remote'
import { NextSeo } from 'next-seo'
import { withRouter } from 'next/router'
import { Element } from 'react-scroll'

import CodeBlock from 'components/docs/CodeBlock.jsx'
import InlineCode from 'components/docs/InlineCode.jsx'
import Toc from 'components/docs/Toc'

import getCurrentUrl from 'lib/currentUrl'
import theme from 'lib/github.js'
import { getArticles, pageProps } from 'lib/announcements'

import { meta as page } from 'content/pages/article.mdx'

const AnnouncementPage = ({
router,
title,
source,
tocHeadings,
frontmatter,
date,
isIndex,
articles
}) => {
const currentUrl = getCurrentUrl(router)

if (isIndex) {
return <AnnouncementIndex articles={articles} />
}

if (!source) return null
return (
<>
<NextSeo
title={`${title} ${page.pageTitle}`}
description={page.description}
canonical={currentUrl}
openGraph={{
url: currentUrl,
title: frontmatter.title,
description: frontmatter.description
}}
/>
<div className="container mt-6 pb-48">
<div className="w-full md:grid grid-cols-12 gap-12 xl:gap-16">
<div className="col-span-4 lg:col-span-3 xl:col-span-3 md:border-r border-gray-2/50 pr-5"></div>
<main className="col-span-8 lg:col-span-9 xl:col-span-7 docs">
<div className="mx-auto md:mx-0 prose max-w-full main-docs-section">
<h1>{title}</h1>
<i>{date}</i>
<Announcement source={source} theme={theme} />
</div>
</main>
<div className="hidden xl:block col-span-2 border-l border-gray-2/50 pl-5">
<Toc contents={tocHeadings} maxHeadingLevel={2} />
</div>
</div>
</div>
</>
)
}

function AnnouncementIndex({articles}) {
return (
<>
<NextSeo
title={page.title}
description={page.description}
canonical={'/announcements'}
openGraph={{
url: '/announcements',
title: page.title,
description: page.description
}}
/>
<div className="container mt-6 pb-48">
<div className="w-full md:grid grid-cols-12 gap-12 xl:gap-16">
<div className="col-span-4 lg:col-span-3 xl:col-span-3 md:border-r border-gray-2/50 pr-5"></div>
<main className="col-span-8 lg:col-span-9 xl:col-span-7 docs">
<div className="mx-auto md:mx-0 prose max-w-full main-docs-section">
<h1>Announcements</h1>
{articles.map((article) => (
<a key={article.path} href={article.path} className="block my-2 !no-underline p-6 bg-white border border-gray-200 rounded-lg shadow-md hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700">
<h5 className="mb-2 text-2xl font-bold tracking-tight text-gray-900 dark:text-white">{article.title}</h5>
<p className="font-normal text-gray-700 dark:text-gray-400">{article.description}</p>
<p className="font-thin text-gray-700 dark:text-gray-400 italic">{article.date}</p>
</a>
))}
</div>
</main>
<div className="hidden xl:block col-span-2 border-l border-gray-2/50 pl-5"></div>
</div>
</div>
</>
)
}

export default withRouter(AnnouncementPage)

function Announcement({ source, theme }) {
const components = {
Element: ({ name, ...props }) => {
return (
<Element
// remove name from parent div
name={props.children[0]?.props?.id === name ? null : name}
{...props}
/>
)
},
pre: (props) => <CodeBlock {...props} theme={theme} />,
code: (props) => <InlineCode {...props} theme={theme} />
}

return <MDXRemote {...source} components={components} theme={theme} />
}

export async function getStaticPaths() {
const articles = await getArticles()
const paths = articles.map((article) => ({params: {article: article.slug}})).concat([{params: {article: []}}])
return { paths, fallback: false }
}

export async function getStaticProps(ctx) {
const isIndex = !ctx.params.article
if (isIndex) {
const articles = await getArticles()
return {props: {
isIndex: true,
articles: articles.map(({title, description, path, date}) => ({title, description, path, date: date.toDateString()}))
}}
}

const props = await pageProps(ctx)
return { props }
}


0 comments on commit f54a952

Please sign in to comment.