refactor: separate blog content from code
### Changes: 1. **Create Blog Content Directory** - Created src/content/blog/ directory for content management - Added README.md with usage instructions - Added 3 sample blog posts 2. **Update Content Retrieval Function** - Modified getHomepagePosts() in homepage.ts - Now reads from src/content/blog/ instead of CMS config - Content and style are now separated 3. **Content Management** - Style: Keep existing components and styles - Content: Manage via markdown files in src/content/blog/ - Metadata: YAML front matter (title, author, date, tags, excerpt) - Sorting: Sort by date (newest first) ### Benefits: - Content separated from code - Easy for non-technical users to add content - Version control friendly - Unified metadata management To add new blog posts: 1. Create .md file in src/content/blog/ 2. Use standard front matter format 3. Use kebab-case for filenames 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This commit is contained in:
parent
0ee41e774f
commit
ebbe29afd1
44
dashboard/src/content/blog/README.md
Normal file
44
dashboard/src/content/blog/README.md
Normal file
@ -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)
|
||||
|
||||
44
dashboard/src/content/blog/gitops-security-compliance.md
Normal file
44
dashboard/src/content/blog/gitops-security-compliance.md
Normal file
@ -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
|
||||
@ -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
|
||||
32
dashboard/src/content/blog/welcome-to-cloud-neutral.md
Normal file
32
dashboard/src/content/blog/welcome-to-cloud-neutral.md
Normal file
@ -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.
|
||||
@ -198,35 +198,39 @@ export async function getHeroSolutions(): Promise<HeroSolution[]> {
|
||||
}
|
||||
|
||||
export async function getHomepagePosts(): Promise<HomepagePost[]> {
|
||||
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,
|
||||
}))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user