diff --git a/dashboard/src/content/blog/README.md b/dashboard/src/content/blog/README.md new file mode 100644 index 0000000..9c57450 --- /dev/null +++ b/dashboard/src/content/blog/README.md @@ -0,0 +1,44 @@ +# Blog Content Directory + +This directory contains all blog posts for the Cloud-Neutral platform. + +## Directory Structure + +``` +src/content/blog/ +├── README.md # This file +├── first-post.md # Example blog post +└── ... +``` + +## Adding a New Blog Post + +1. Create a new markdown file in this directory +2. Use the following format: + +```markdown +--- +title: Your Post Title +author: Author Name +date: 2025-01-01 +tags: [tag1, tag2, tag3] +excerpt: Brief description of the post +--- + +Your post content here in Markdown format. +``` + +## File Naming Convention + +- Use kebab-case: `my-first-post.md` +- Avoid spaces and special characters +- Include the `.md` extension + +## Metadata Fields + +- **title**: The post title (required) +- **author**: Author name (optional) +- **date**: Publication date in YYYY-MM-DD format (required) +- **tags**: Array of tags (optional) +- **excerpt**: Brief description (optional, auto-generated if not provided) + diff --git a/dashboard/src/content/blog/gitops-security-compliance.md b/dashboard/src/content/blog/gitops-security-compliance.md new file mode 100644 index 0000000..df892c9 --- /dev/null +++ b/dashboard/src/content/blog/gitops-security-compliance.md @@ -0,0 +1,44 @@ +--- +title: GitOps Security & Compliance in 2025 +author: Security Team +date: 2025-01-05 +tags: [gitops, security, compliance, automation] +excerpt: How to implement robust security and compliance controls in your GitOps workflows. +--- + +GitOps has revolutionized how we manage infrastructure, but security and compliance remain critical concerns. + +## Security Considerations + +### Supply Chain Security +- Scan dependencies for vulnerabilities +- Use signed commits +- Implement code signing +- Verify container images + +### Access Control +- Principle of least privilege +- Multi-factor authentication +- Role-based access control +- Audit all changes + +## Compliance Framework + +### Policy as Code +- Define policies in version control +- Automate compliance checks +- Block non-compliant changes +- Regular policy reviews + +### Audit Trail +- Immutable Git history +- Signed commits +- Change tracking +- Compliance reporting + +## Implementation Strategy + +1. Start with high-level policies +2. Implement progressive enforcement +3. Automate validation +4. Monitor and alert diff --git a/dashboard/src/content/blog/kubernetes-observability-best-practices.md b/dashboard/src/content/blog/kubernetes-observability-best-practices.md new file mode 100644 index 0000000..00e4885 --- /dev/null +++ b/dashboard/src/content/blog/kubernetes-observability-best-practices.md @@ -0,0 +1,36 @@ +--- +title: Kubernetes Observability Best Practices +author: SRE Team +date: 2025-01-10 +tags: [kubernetes, observability, sre, monitoring] +excerpt: Learn the essential practices for building a robust observability strategy in Kubernetes environments. +--- + +Building effective observability in Kubernetes requires understanding the unique challenges of containerized environments. + +## The Three Pillars + +### Metrics +- Use Prometheus for metrics collection +- Monitor resource usage (CPU, memory, disk) +- Track application-specific metrics +- Set up alerting rules + +### Logs +- Centralize logs with ELK or similar stack +- Structured logging for better searchability +- Log levels: DEBUG, INFO, WARN, ERROR +- Correlate logs with trace IDs + +### Traces +- Use OpenTelemetry for distributed tracing +- Track request flows across services +- Identify performance bottlenecks +- Monitor service dependencies + +## Best Practices + +1. **Start with Golden Signals**: Latency, traffic, errors, saturation +2. **Use SLOs**: Define and track Service Level Objectives +3. **Alert Wisely**: Alert on symptoms, not causes +4. **Correlate Data**: Connect metrics, logs, and traces diff --git a/dashboard/src/content/blog/welcome-to-cloud-neutral.md b/dashboard/src/content/blog/welcome-to-cloud-neutral.md new file mode 100644 index 0000000..30d67e2 --- /dev/null +++ b/dashboard/src/content/blog/welcome-to-cloud-neutral.md @@ -0,0 +1,32 @@ +--- +title: Welcome to Cloud-Neutral +author: Cloud-Neutral Team +date: 2025-01-15 +tags: [announcement, cloud-native, platform] +excerpt: Introducing Cloud-Neutral - your unified platform for managing complex multi-cloud operations. +--- + +Welcome to Cloud-Neutral, the platform that unifies governance, automation, and observability for modern cloud-native environments. + +## What is Cloud-Neutral? + +Cloud-Neutral is designed to help platform teams manage complex multi-cloud estates with clarity. We provide a unified interface for: + +- **Unified multi-cloud governance** - Manage resources across AWS, Azure, GCP, and more +- **Automated security & compliance** - Policy-as-code guardrails with global acceleration +- **Observability with intelligent workflows** - Unified metrics, logs, and traces + +## Key Features + +### XCloudFlow +Multi-cloud automation & GitOps orchestration that connects Terraform, Pulumi, and GitOps pipelines. + +### XScopeHub +Observability & intelligent collaboration that unifies metrics, logs, and traces with AI-guided incident response. + +### XStream +Security & compliance automation with policy-as-code guardrails. + +## Getting Started + +Visit our [documentation](/docs) to learn more about how Cloud-Neutral can help your team. diff --git a/dashboard/src/lib/cms/content/homepage.ts b/dashboard/src/lib/cms/content/homepage.ts index b961fa1..08b1328 100644 --- a/dashboard/src/lib/cms/content/homepage.ts +++ b/dashboard/src/lib/cms/content/homepage.ts @@ -198,35 +198,39 @@ export async function getHeroSolutions(): Promise { } export async function getHomepagePosts(): Promise { - if (!isCmsHomepageEnabled()) { - return [] + const blogContentRoot = path.join(process.cwd(), 'src', 'content', 'blog') + + let posts: HomepagePost[] = [] + try { + const files = await readMarkdownDirectory('', { baseDir: blogContentRoot }) + + posts = files.map((file) => { + const title = ensureString(file.metadata.title) ?? file.slug + const author = ensureString(file.metadata.author) + const date = ensureString(file.metadata.date) + const readingTime = ensureString(file.metadata.readingTime) + const tags = ensureStringArray(file.metadata.tags) + const excerptMetadata = ensureString(file.metadata.excerpt) + const excerpt = excerptMetadata ?? extractExcerpt(file.content) + + return { + slug: file.slug, + title, + author, + date, + readingTime, + tags, + excerpt, + contentHtml: file.html, + } + }) + } catch (error) { + if ((error as NodeJS.ErrnoException).code !== 'ENOENT') { + throw error + } } - const postsDir = path.join('posts') - const posts = await readMarkdownDirectory(postsDir, { baseDir: HOMEPAGE_CONTENT_ROOT }) - - const enriched = posts.map((post) => { - const title = ensureString(post.metadata.title) ?? post.slug - const author = ensureString(post.metadata.author) - const date = ensureString(post.metadata.date) - const readingTime = ensureString(post.metadata.readingTime) - const tags = ensureStringArray(post.metadata.tags) - const excerptMetadata = ensureString(post.metadata.excerpt) - const excerpt = excerptMetadata ?? extractExcerpt(post.content) - - return { - slug: post.slug, - title, - author, - date, - readingTime, - tags, - excerpt, - contentHtml: post.html, - } - }) - - const withParsedDates = enriched.map((post) => ({ + const withParsedDates = posts.map((post) => ({ ...post, dateValue: post.date ? new Date(post.date) : undefined, }))