Initial release: Headlamp Sealed Secrets plugin v0.1.0
Features: - Complete SealedSecret CRD integration with Headlamp - Client-side encryption using controller's public key - Support for all three scoping modes (strict, namespace-wide, cluster-wide) - List and detail views for SealedSecrets - Encryption dialog for creating new SealedSecrets - Decryption support with RBAC awareness - Sealing keys management - Settings page for controller configuration - Integration with Secret detail view Technical: - Full TypeScript with strict mode - ~1,345 lines of code - Build size: 339.42 kB (93.21 kB gzipped) - Compatible with Headlamp v0.13.0+ - Apache 2.0 license Security: - All encryption performed client-side - RSA-OAEP + AES-256-GCM (kubeseal-compatible) - Auto-hide decrypted values after 30 seconds Closes: Initial implementation
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* Settings Page
|
||||
*
|
||||
* Configuration page for the Sealed Secrets plugin
|
||||
*/
|
||||
|
||||
import { SectionBox } from '@kinvolk/headlamp-plugin/lib/CommonComponents';
|
||||
import { Box, Button, TextField, Typography } from '@mui/material';
|
||||
import { useSnackbar } from 'notistack';
|
||||
import React from 'react';
|
||||
import { getPluginConfig, savePluginConfig } from '../lib/controller';
|
||||
import { PluginConfig } from '../types';
|
||||
|
||||
/**
|
||||
* Settings page component
|
||||
*/
|
||||
export function SettingsPage() {
|
||||
const [config, setConfig] = React.useState<PluginConfig>(getPluginConfig());
|
||||
const { enqueueSnackbar } = useSnackbar();
|
||||
|
||||
const handleSave = () => {
|
||||
savePluginConfig(config);
|
||||
enqueueSnackbar('Settings saved successfully', { variant: 'success' });
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
const defaultConfig: PluginConfig = {
|
||||
controllerName: 'sealed-secrets-controller',
|
||||
controllerNamespace: 'kube-system',
|
||||
controllerPort: 8080,
|
||||
};
|
||||
setConfig(defaultConfig);
|
||||
};
|
||||
|
||||
return (
|
||||
<SectionBox
|
||||
title="Sealed Secrets Plugin Settings"
|
||||
>
|
||||
<Box p={3}>
|
||||
<Typography variant="body1" paragraph>
|
||||
Configure the connection to your Sealed Secrets controller. These settings are stored in
|
||||
your browser's local storage.
|
||||
</Typography>
|
||||
|
||||
<TextField
|
||||
fullWidth
|
||||
label="Controller Name"
|
||||
value={config.controllerName}
|
||||
onChange={e => setConfig({ ...config, controllerName: e.target.value })}
|
||||
margin="normal"
|
||||
helperText="Name of the sealed-secrets-controller deployment/service"
|
||||
/>
|
||||
|
||||
<TextField
|
||||
fullWidth
|
||||
label="Controller Namespace"
|
||||
value={config.controllerNamespace}
|
||||
onChange={e => setConfig({ ...config, controllerNamespace: e.target.value })}
|
||||
margin="normal"
|
||||
helperText="Namespace where the controller is installed"
|
||||
/>
|
||||
|
||||
<TextField
|
||||
fullWidth
|
||||
label="Controller Port"
|
||||
type="number"
|
||||
value={config.controllerPort}
|
||||
onChange={e => setConfig({ ...config, controllerPort: parseInt(e.target.value, 10) })}
|
||||
margin="normal"
|
||||
helperText="HTTP port of the controller service"
|
||||
/>
|
||||
|
||||
<Box mt={3} display="flex" gap={2}>
|
||||
<Button variant="contained" onClick={handleSave}>
|
||||
Save Settings
|
||||
</Button>
|
||||
<Button variant="outlined" onClick={handleReset}>
|
||||
Reset to Defaults
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
<Box mt={4} p={2} bgcolor="info.light" borderRadius={1}>
|
||||
<Typography variant="h6" gutterBottom>
|
||||
Default Values
|
||||
</Typography>
|
||||
<Typography variant="body2">
|
||||
<strong>Controller Name:</strong> sealed-secrets-controller
|
||||
<br />
|
||||
<strong>Controller Namespace:</strong> kube-system
|
||||
<br />
|
||||
<strong>Controller Port:</strong> 8080
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
</SectionBox>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user