@robinmordasiewicz/f5xc-cloudstatus-mcp 1.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +196 -0
- package/dist/cache/cache-service.d.ts +60 -0
- package/dist/cache/cache-service.d.ts.map +1 -0
- package/dist/cache/cache-service.js +162 -0
- package/dist/cache/cache-service.js.map +1 -0
- package/dist/cache/index.d.ts +6 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +6 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/data-access/api-client.d.ts +71 -0
- package/dist/data-access/api-client.d.ts.map +1 -0
- package/dist/data-access/api-client.js +188 -0
- package/dist/data-access/api-client.js.map +1 -0
- package/dist/data-access/data-access-layer.d.ts +72 -0
- package/dist/data-access/data-access-layer.d.ts.map +1 -0
- package/dist/data-access/data-access-layer.js +171 -0
- package/dist/data-access/data-access-layer.js.map +1 -0
- package/dist/data-access/index.d.ts +9 -0
- package/dist/data-access/index.d.ts.map +1 -0
- package/dist/data-access/index.js +8 -0
- package/dist/data-access/index.js.map +1 -0
- package/dist/data-access/web-scraper.d.ts +60 -0
- package/dist/data-access/web-scraper.d.ts.map +1 -0
- package/dist/data-access/web-scraper.js +281 -0
- package/dist/data-access/web-scraper.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/server/index.d.ts +6 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +6 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/mcp-server.d.ts +35 -0
- package/dist/server/mcp-server.d.ts.map +1 -0
- package/dist/server/mcp-server.js +143 -0
- package/dist/server/mcp-server.js.map +1 -0
- package/dist/services/component-service.d.ts +80 -0
- package/dist/services/component-service.d.ts.map +1 -0
- package/dist/services/component-service.js +187 -0
- package/dist/services/component-service.js.map +1 -0
- package/dist/services/incident-service.d.ts +96 -0
- package/dist/services/incident-service.d.ts.map +1 -0
- package/dist/services/incident-service.js +219 -0
- package/dist/services/incident-service.js.map +1 -0
- package/dist/services/index.d.ts +8 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +8 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/status-service.d.ts +56 -0
- package/dist/services/status-service.d.ts.map +1 -0
- package/dist/services/status-service.js +105 -0
- package/dist/services/status-service.js.map +1 -0
- package/dist/tools/index.d.ts +8 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +7 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/tool-definitions.d.ts +257 -0
- package/dist/tools/tool-definitions.d.ts.map +1 -0
- package/dist/tools/tool-definitions.js +192 -0
- package/dist/tools/tool-definitions.js.map +1 -0
- package/dist/tools/tool-handler.d.ts +49 -0
- package/dist/tools/tool-handler.d.ts.map +1 -0
- package/dist/tools/tool-handler.js +264 -0
- package/dist/tools/tool-handler.js.map +1 -0
- package/dist/types/api.d.ts +215 -0
- package/dist/types/api.d.ts.map +1 -0
- package/dist/types/api.js +6 -0
- package/dist/types/api.js.map +1 -0
- package/dist/types/domain.d.ts +115 -0
- package/dist/types/domain.d.ts.map +1 -0
- package/dist/types/domain.js +6 -0
- package/dist/types/domain.js.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/config.d.ts +38 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +113 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/errors.d.ts +77 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +130 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/index.d.ts +9 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +48 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +90 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +76 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 robinmordasiewicz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# F5 Cloud Status MCP Server
|
|
2
|
+
|
|
3
|
+
A Model Context Protocol (MCP) server for monitoring F5 Cloud service status, providing real-time status information, component health, incidents, and scheduled maintenance.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Real-time Status Monitoring**: Get current operational status of F5 Cloud services
|
|
8
|
+
- **Component Tracking**: Monitor 148+ individual service components across multiple categories
|
|
9
|
+
- **Incident Management**: Track active and historical incidents with detailed updates
|
|
10
|
+
- **Maintenance Windows**: Access scheduled, active, and upcoming maintenance information
|
|
11
|
+
- **Dual Data Sources**: API-first with automatic web scraper fallback for reliability
|
|
12
|
+
- **Intelligent Caching**: TTL-based caching with configurable durations per data type
|
|
13
|
+
- **Comprehensive Search**: Search across components, incidents, and maintenance by keyword
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
### Base Configuration
|
|
18
|
+
|
|
19
|
+
The standard configuration for all MCP clients:
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"mcpServers": {
|
|
24
|
+
"f5xc-cloudstatus": {
|
|
25
|
+
"command": "npx",
|
|
26
|
+
"args": ["-y", "@robinmordasiewicz/f5xc-cloudstatus-mcp@latest"]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
This uses `npx` to automatically download and run the latest version. No manual installation required.
|
|
33
|
+
|
|
34
|
+
### Claude Desktop
|
|
35
|
+
|
|
36
|
+
1. **Locate your configuration file:**
|
|
37
|
+
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
38
|
+
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
39
|
+
- **Linux**: `~/.config/Claude/claude_desktop_config.json`
|
|
40
|
+
|
|
41
|
+
2. **Add the base configuration** (see above)
|
|
42
|
+
|
|
43
|
+
3. **Restart Claude Desktop**
|
|
44
|
+
|
|
45
|
+
4. **Verify**: Look for the 🔌 MCP icon showing "f5xc-cloudstatus" connected
|
|
46
|
+
|
|
47
|
+
### Claude Code
|
|
48
|
+
|
|
49
|
+
**CLI installation:**
|
|
50
|
+
```bash
|
|
51
|
+
claude mcp add f5xc-cloudstatus npx @robinmordasiewicz/f5xc-cloudstatus-mcp@latest
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### VS Code (with GitHub Copilot)
|
|
55
|
+
|
|
56
|
+
**Requirements**: VS Code 1.102 or later
|
|
57
|
+
|
|
58
|
+
**CLI installation:**
|
|
59
|
+
```bash
|
|
60
|
+
code --add-mcp '{"name":"f5xc-cloudstatus","command":"npx","args":["@robinmordasiewicz/f5xc-cloudstatus-mcp@latest"]}'
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Or enable auto-discovery:**
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"chat.mcp.discovery.enabled": true
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Or manual configuration** in `settings.json`:
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"chat.mcp.servers": {
|
|
74
|
+
"f5xc-cloudstatus": {
|
|
75
|
+
"command": "npx",
|
|
76
|
+
"args": ["-y", "@robinmordasiewicz/f5xc-cloudstatus-mcp@latest"]
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Cursor IDE
|
|
83
|
+
|
|
84
|
+
**One-click install:**
|
|
85
|
+
1. Open **Command Palette** (`Ctrl+Shift+P` / `Cmd+Shift+P`)
|
|
86
|
+
2. Type **"Cursor Settings"** → **MCP**
|
|
87
|
+
3. Browse and click **Install** for F5 Cloud Status
|
|
88
|
+
|
|
89
|
+
**Or manual configuration:**
|
|
90
|
+
- **Project**: Create `.cursor/mcp.json` with base configuration
|
|
91
|
+
- **Global**: Create `~/.cursor/mcp.json` with base configuration
|
|
92
|
+
|
|
93
|
+
### Windsurf
|
|
94
|
+
|
|
95
|
+
**Plugin Store:**
|
|
96
|
+
1. Click **Plugins** in Cascade panel → Search **"F5 Cloud Status"** → **Install**
|
|
97
|
+
|
|
98
|
+
**Or manual:**
|
|
99
|
+
1. **Windsurf Settings** → **Cascade** → **MCP Servers** → **Add Custom Server**
|
|
100
|
+
2. Add base configuration
|
|
101
|
+
|
|
102
|
+
### Cline (VS Code Extension)
|
|
103
|
+
|
|
104
|
+
1. Install **Cline** extension in VS Code
|
|
105
|
+
2. Add base configuration to Cline's MCP settings or VS Code `settings.json`:
|
|
106
|
+
```json
|
|
107
|
+
{
|
|
108
|
+
"cline.mcpServers": {
|
|
109
|
+
"f5xc-cloudstatus": {
|
|
110
|
+
"command": "npx",
|
|
111
|
+
"args": ["-y", "@robinmordasiewicz/f5xc-cloudstatus-mcp@latest"]
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
3. Restart VS Code
|
|
117
|
+
|
|
118
|
+
See [Cline MCP docs](https://docs.cline.bot/mcp/configuring-mcp-servers) for more details.
|
|
119
|
+
|
|
120
|
+
### Alternative Installation: Global NPM
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
npm install -g @robinmordasiewicz/f5xc-cloudstatus-mcp
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Configuration:
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"mcpServers": {
|
|
130
|
+
"f5xc-cloudstatus": {
|
|
131
|
+
"command": "f5xc-cloudstatus-mcp"
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Example Queries
|
|
138
|
+
|
|
139
|
+
Once configured, ask your AI assistant:
|
|
140
|
+
|
|
141
|
+
> **📖 See [USAGE_EXAMPLES.md](USAGE_EXAMPLES.md) for 14 detailed real-world examples with expected responses.**
|
|
142
|
+
|
|
143
|
+
### Quick Examples
|
|
144
|
+
|
|
145
|
+
**Check overall status:**
|
|
146
|
+
```
|
|
147
|
+
What is the current status of F5 Cloud services?
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**List all components:**
|
|
151
|
+
```
|
|
152
|
+
Show me all F5 Cloud components and their current operational status
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Check for issues:**
|
|
156
|
+
```
|
|
157
|
+
Are there any F5 Cloud components that are degraded or having issues?
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
**Find specific component:**
|
|
161
|
+
```
|
|
162
|
+
What is the status of the F5 Distributed Cloud Services API Gateway?
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**Check for incidents:**
|
|
166
|
+
```
|
|
167
|
+
Are there any active incidents affecting F5 Cloud services?
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**Search for maintenance:**
|
|
171
|
+
```
|
|
172
|
+
Are there any upcoming maintenance windows for F5 Cloud services?
|
|
173
|
+
```
|
|
174
|
+
## Available Tools
|
|
175
|
+
|
|
176
|
+
The server provides six MCP tools for interacting with F5 Cloud status:
|
|
177
|
+
|
|
178
|
+
1. **`f5-status-get-overall`** - Get the current overall status of F5 Cloud services
|
|
179
|
+
2. **`f5-status-get-components`** - Get all service components with current status
|
|
180
|
+
3. **`f5-status-get-component`** - Get detailed information about a specific component
|
|
181
|
+
4. **`f5-status-get-incidents`** - Get current and recent incidents
|
|
182
|
+
5. **`f5-status-get-maintenance`** - Get scheduled maintenance windows
|
|
183
|
+
6. **`f5-status-search`** - Search for components, incidents, or maintenance by keyword
|
|
184
|
+
|
|
185
|
+
## Development
|
|
186
|
+
|
|
187
|
+
This project uses **fully automated CI/CD** with version bumping. See [docs/CICD.md](docs/CICD.md) for details.
|
|
188
|
+
|
|
189
|
+
## License
|
|
190
|
+
|
|
191
|
+
MIT - See [LICENSE](LICENSE) file for details
|
|
192
|
+
|
|
193
|
+
## Support
|
|
194
|
+
|
|
195
|
+
- **GitHub Issues**: [GitHub Issues](https://github.com/robinmordasiewicz/f5xc-cloudstatus-mcp/issues)
|
|
196
|
+
- **NPM Package**: https://www.npmjs.com/package/@robinmordasiewicz/f5xc-cloudstatus-mcp
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache service for F5 Status MCP Server
|
|
3
|
+
* Implements TTL-based caching with type safety
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Cache service class
|
|
7
|
+
*/
|
|
8
|
+
export declare class CacheService {
|
|
9
|
+
private cache;
|
|
10
|
+
private readonly name;
|
|
11
|
+
constructor(name?: string);
|
|
12
|
+
/**
|
|
13
|
+
* Get value from cache or fetch if missing/expired
|
|
14
|
+
*/
|
|
15
|
+
get<T>(key: string, ttl: number, fetcher: () => Promise<T>): Promise<T>;
|
|
16
|
+
/**
|
|
17
|
+
* Set value in cache with TTL
|
|
18
|
+
*/
|
|
19
|
+
set<T>(key: string, data: T, ttl: number): void;
|
|
20
|
+
/**
|
|
21
|
+
* Check if key exists and is not expired
|
|
22
|
+
*/
|
|
23
|
+
has(key: string): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Get value directly from cache (without fetcher)
|
|
26
|
+
*/
|
|
27
|
+
getDirect<T>(key: string): T | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* Delete entry from cache
|
|
30
|
+
*/
|
|
31
|
+
delete(key: string): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Clear all cache entries
|
|
34
|
+
*/
|
|
35
|
+
clear(): void;
|
|
36
|
+
/**
|
|
37
|
+
* Get cache statistics
|
|
38
|
+
*/
|
|
39
|
+
getStats(): {
|
|
40
|
+
size: number;
|
|
41
|
+
entries: Array<{
|
|
42
|
+
key: string;
|
|
43
|
+
expiresIn: number;
|
|
44
|
+
expiresAt: string;
|
|
45
|
+
}>;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Clean expired entries
|
|
49
|
+
*/
|
|
50
|
+
cleanExpired(): number;
|
|
51
|
+
/**
|
|
52
|
+
* Invalidate cache entries matching pattern
|
|
53
|
+
*/
|
|
54
|
+
invalidatePattern(pattern: RegExp): number;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Create a cache service instance
|
|
58
|
+
*/
|
|
59
|
+
export declare function createCacheService(name?: string): CacheService;
|
|
60
|
+
//# sourceMappingURL=cache-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-service.d.ts","sourceRoot":"","sources":["../../src/cache/cache-service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAaH;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAmC;IAChD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;gBAElB,IAAI,GAAE,MAAkB;IAKpC;;OAEG;IACG,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAwB7E;;OAEG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAe/C;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAYzB;;OAEG;IACH,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAaxC;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAQ5B;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;OAEG;IACH,QAAQ,IAAI;QACV,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,KAAK,CAAC;YACb,GAAG,EAAE,MAAM,CAAC;YACZ,SAAS,EAAE,MAAM,CAAC;YAClB,SAAS,EAAE,MAAM,CAAC;SACnB,CAAC,CAAC;KACJ;IAcD;;OAEG;IACH,YAAY,IAAI,MAAM;IAqBtB;;OAEG;IACH,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;CAoB3C;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,YAAY,CAE9D"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache service for F5 Status MCP Server
|
|
3
|
+
* Implements TTL-based caching with type safety
|
|
4
|
+
*/
|
|
5
|
+
import { CacheError } from '../utils/errors.js';
|
|
6
|
+
import { logger } from '../utils/logger.js';
|
|
7
|
+
/**
|
|
8
|
+
* Cache service class
|
|
9
|
+
*/
|
|
10
|
+
export class CacheService {
|
|
11
|
+
constructor(name = 'default') {
|
|
12
|
+
this.cache = new Map();
|
|
13
|
+
this.name = name;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Get value from cache or fetch if missing/expired
|
|
17
|
+
*/
|
|
18
|
+
async get(key, ttl, fetcher) {
|
|
19
|
+
try {
|
|
20
|
+
// Check cache
|
|
21
|
+
const cached = this.cache.get(key);
|
|
22
|
+
if (cached && cached.expiry > Date.now()) {
|
|
23
|
+
logger.debug(`Cache hit for key: ${key}`, { name: this.name });
|
|
24
|
+
return cached.data;
|
|
25
|
+
}
|
|
26
|
+
// Cache miss or expired
|
|
27
|
+
logger.debug(`Cache miss for key: ${key}`, { name: this.name });
|
|
28
|
+
const data = await fetcher();
|
|
29
|
+
// Store in cache
|
|
30
|
+
this.set(key, data, ttl);
|
|
31
|
+
return data;
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
logger.error(`Cache get error for key: ${key}`, error);
|
|
35
|
+
throw new CacheError(`Failed to get cache entry: ${key}`, error);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Set value in cache with TTL
|
|
40
|
+
*/
|
|
41
|
+
set(key, data, ttl) {
|
|
42
|
+
try {
|
|
43
|
+
const expiry = Date.now() + ttl;
|
|
44
|
+
this.cache.set(key, { data, expiry });
|
|
45
|
+
logger.debug(`Cache set for key: ${key}`, {
|
|
46
|
+
name: this.name,
|
|
47
|
+
ttl,
|
|
48
|
+
expiry: new Date(expiry).toISOString(),
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
logger.error(`Cache set error for key: ${key}`, error);
|
|
53
|
+
throw new CacheError(`Failed to set cache entry: ${key}`, error);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Check if key exists and is not expired
|
|
58
|
+
*/
|
|
59
|
+
has(key) {
|
|
60
|
+
const cached = this.cache.get(key);
|
|
61
|
+
if (!cached)
|
|
62
|
+
return false;
|
|
63
|
+
if (cached.expiry <= Date.now()) {
|
|
64
|
+
this.delete(key);
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Get value directly from cache (without fetcher)
|
|
71
|
+
*/
|
|
72
|
+
getDirect(key) {
|
|
73
|
+
const cached = this.cache.get(key);
|
|
74
|
+
if (!cached)
|
|
75
|
+
return undefined;
|
|
76
|
+
if (cached.expiry <= Date.now()) {
|
|
77
|
+
this.delete(key);
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
return cached.data;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Delete entry from cache
|
|
84
|
+
*/
|
|
85
|
+
delete(key) {
|
|
86
|
+
const deleted = this.cache.delete(key);
|
|
87
|
+
if (deleted) {
|
|
88
|
+
logger.debug(`Cache delete for key: ${key}`, { name: this.name });
|
|
89
|
+
}
|
|
90
|
+
return deleted;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Clear all cache entries
|
|
94
|
+
*/
|
|
95
|
+
clear() {
|
|
96
|
+
const size = this.cache.size;
|
|
97
|
+
this.cache.clear();
|
|
98
|
+
logger.info(`Cache cleared`, { name: this.name, entriesCleared: size });
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Get cache statistics
|
|
102
|
+
*/
|
|
103
|
+
getStats() {
|
|
104
|
+
const now = Date.now();
|
|
105
|
+
const entries = Array.from(this.cache.entries()).map(([key, entry]) => ({
|
|
106
|
+
key,
|
|
107
|
+
expiresIn: Math.max(0, entry.expiry - now),
|
|
108
|
+
expiresAt: new Date(entry.expiry).toISOString(),
|
|
109
|
+
}));
|
|
110
|
+
return {
|
|
111
|
+
size: this.cache.size,
|
|
112
|
+
entries,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Clean expired entries
|
|
117
|
+
*/
|
|
118
|
+
cleanExpired() {
|
|
119
|
+
const now = Date.now();
|
|
120
|
+
let cleaned = 0;
|
|
121
|
+
for (const [key, entry] of this.cache.entries()) {
|
|
122
|
+
if (entry.expiry <= now) {
|
|
123
|
+
this.cache.delete(key);
|
|
124
|
+
cleaned++;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (cleaned > 0) {
|
|
128
|
+
logger.debug(`Cleaned expired cache entries`, {
|
|
129
|
+
name: this.name,
|
|
130
|
+
count: cleaned,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
return cleaned;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Invalidate cache entries matching pattern
|
|
137
|
+
*/
|
|
138
|
+
invalidatePattern(pattern) {
|
|
139
|
+
let invalidated = 0;
|
|
140
|
+
for (const key of this.cache.keys()) {
|
|
141
|
+
if (pattern.test(key)) {
|
|
142
|
+
this.cache.delete(key);
|
|
143
|
+
invalidated++;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (invalidated > 0) {
|
|
147
|
+
logger.info(`Invalidated cache entries by pattern`, {
|
|
148
|
+
name: this.name,
|
|
149
|
+
pattern: pattern.toString(),
|
|
150
|
+
count: invalidated,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
return invalidated;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Create a cache service instance
|
|
158
|
+
*/
|
|
159
|
+
export function createCacheService(name) {
|
|
160
|
+
return new CacheService(name);
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=cache-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-service.js","sourceRoot":"","sources":["../../src/cache/cache-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API client for F5 Cloud Status
|
|
3
|
+
* Implements retry logic with exponential backoff
|
|
4
|
+
*/
|
|
5
|
+
import type { RawStatusResponse, RawSummaryResponse, RawIncidentsResponse, RawUnresolvedIncidentsResponse, RawScheduledMaintenancesResponse, RawActiveMaintenancesResponse, RawUpcomingMaintenancesResponse, RawComponentsResponse } from '../types/api.js';
|
|
6
|
+
/**
|
|
7
|
+
* API Client class
|
|
8
|
+
*/
|
|
9
|
+
export declare class APIClient {
|
|
10
|
+
private client;
|
|
11
|
+
private readonly retryAttempts;
|
|
12
|
+
private readonly retryDelay;
|
|
13
|
+
constructor();
|
|
14
|
+
/**
|
|
15
|
+
* Fetch overall status
|
|
16
|
+
*/
|
|
17
|
+
fetchStatus(): Promise<RawStatusResponse>;
|
|
18
|
+
/**
|
|
19
|
+
* Fetch summary (status, components, incidents, maintenance)
|
|
20
|
+
*/
|
|
21
|
+
fetchSummary(): Promise<RawSummaryResponse>;
|
|
22
|
+
/**
|
|
23
|
+
* Fetch all components
|
|
24
|
+
*/
|
|
25
|
+
fetchComponents(): Promise<RawComponentsResponse>;
|
|
26
|
+
/**
|
|
27
|
+
* Fetch all incidents
|
|
28
|
+
*/
|
|
29
|
+
fetchIncidents(): Promise<RawIncidentsResponse>;
|
|
30
|
+
/**
|
|
31
|
+
* Fetch unresolved incidents
|
|
32
|
+
*/
|
|
33
|
+
fetchUnresolvedIncidents(): Promise<RawUnresolvedIncidentsResponse>;
|
|
34
|
+
/**
|
|
35
|
+
* Fetch all scheduled maintenances
|
|
36
|
+
*/
|
|
37
|
+
fetchScheduledMaintenances(): Promise<RawScheduledMaintenancesResponse>;
|
|
38
|
+
/**
|
|
39
|
+
* Fetch active scheduled maintenances
|
|
40
|
+
*/
|
|
41
|
+
fetchActiveMaintenances(): Promise<RawActiveMaintenancesResponse>;
|
|
42
|
+
/**
|
|
43
|
+
* Fetch upcoming scheduled maintenances
|
|
44
|
+
*/
|
|
45
|
+
fetchUpcomingMaintenances(): Promise<RawUpcomingMaintenancesResponse>;
|
|
46
|
+
/**
|
|
47
|
+
* Make HTTP request with retry logic
|
|
48
|
+
*/
|
|
49
|
+
private request;
|
|
50
|
+
/**
|
|
51
|
+
* Retry function with exponential backoff
|
|
52
|
+
*/
|
|
53
|
+
private retry;
|
|
54
|
+
/**
|
|
55
|
+
* Handle API errors
|
|
56
|
+
*/
|
|
57
|
+
private handleError;
|
|
58
|
+
/**
|
|
59
|
+
* Get error message from unknown error
|
|
60
|
+
*/
|
|
61
|
+
private getErrorMessage;
|
|
62
|
+
/**
|
|
63
|
+
* Sleep helper for retry delay
|
|
64
|
+
*/
|
|
65
|
+
private sleep;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Create API client instance
|
|
69
|
+
*/
|
|
70
|
+
export declare function createAPIClient(): APIClient;
|
|
71
|
+
//# sourceMappingURL=api-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../../src/data-access/api-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,8BAA8B,EAC9B,gCAAgC,EAChC,6BAA6B,EAC7B,+BAA+B,EAC/B,qBAAqB,EACtB,MAAM,iBAAiB,CAAC;AAEzB;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;;IAwCpC;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAI/C;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAIjD;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,qBAAqB,CAAC;IAIvD;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,oBAAoB,CAAC;IAIrD;;OAEG;IACG,wBAAwB,IAAI,OAAO,CAAC,8BAA8B,CAAC;IAIzE;;OAEG;IACG,0BAA0B,IAAI,OAAO,CAAC,gCAAgC,CAAC;IAI7E;;OAEG;IACG,uBAAuB,IAAI,OAAO,CAAC,6BAA6B,CAAC;IAIvE;;OAEG;IACG,yBAAyB,IAAI,OAAO,CAAC,+BAA+B,CAAC;IAI3E;;OAEG;YACW,OAAO;IAYrB;;OAEG;YACW,KAAK;IAmBnB;;OAEG;IACH,OAAO,CAAC,WAAW;IA6CnB;;OAEG;IACH,OAAO,CAAC,eAAe;IAOvB;;OAEG;IACH,OAAO,CAAC,KAAK;CAGd;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,SAAS,CAE3C"}
|