1+ #!/usr/bin/env node
2+
3+ /**
4+ * OIDC Command Implementation
5+ * Provides GitHub Actions OIDC configuration with AWS through the toolkit's CLI framework
6+ */
7+
8+ const BaseCommand = require ( './base/base-command' ) ;
9+ const DependencyValidator = require ( './dependency-validator' ) ;
10+ const ErrorHandlerUtils = require ( './error-handler-utils' ) ;
11+
12+ class OidcCommand extends BaseCommand {
13+ constructor ( ) {
14+ super ( ) ;
15+ this . dependencyValidator = new DependencyValidator ( ) ;
16+ this . errorHandlerUtils = new ErrorHandlerUtils ( ) ;
17+ }
18+
19+ /**
20+ * Get required tools for OIDC functionality
21+ */
22+ getRequiredTools ( ) {
23+ return [
24+ {
25+ name : 'aws' ,
26+ description : 'AWS CLI for AWS operations' ,
27+ required : true
28+ } ,
29+ {
30+ name : 'git' ,
31+ description : 'Git for repository operations' ,
32+ required : true
33+ } ,
34+ {
35+ name : 'gh' ,
36+ description : 'GitHub CLI for GitHub operations' ,
37+ required : true
38+ }
39+ ] ;
40+ }
41+
42+ /**
43+ * Validate required dependencies
44+ */
45+ async validateDependencies ( options = { } ) {
46+ const requiredTools = this . getRequiredTools ( ) ;
47+ const result = this . dependencyValidator . checkDependencies ( requiredTools ) ;
48+
49+ return result ;
50+ }
51+
52+ /**
53+ * Handle dependency errors with enhanced error information
54+ */
55+ handleDependencyError ( error , context = { } ) {
56+ const enhancedError = this . errorHandlerUtils . createEnhancedError ( error , {
57+ operation : 'dependency validation' ,
58+ component : 'OIDC command' ,
59+ ...context
60+ } ) ;
61+
62+ const suggestions = this . errorHandlerUtils . generateRecoverySuggestions ( enhancedError ) ;
63+
64+ return {
65+ ...enhancedError ,
66+ suggestions
67+ } ;
68+ }
69+
70+ /**
71+ * Create context-aware error with operation details
72+ */
73+ createContextAwareError ( error , context = { } ) {
74+ return this . errorHandlerUtils . createEnhancedError ( error , context ) ;
75+ }
76+
77+ /**
78+ * Process command arguments with defaults and validation
79+ */
80+ processArguments ( options = { } ) {
81+ const processed = {
82+ // Default values for common options
83+ region : options . region || 'us-east-1' ,
84+ dryRun : options . dryRun || false ,
85+ verbose : options . verbose || false ,
86+ help : options . help || false ,
87+
88+ // OIDC-specific options with defaults
89+ repositoryPath : options . repositoryPath || process . cwd ( ) ,
90+ stackName : options . stackName || 'github-oidc-stack' ,
91+ roleName : options . roleName || 'GitHubActionsRole' ,
92+
93+ // Copy other options as-is
94+ ...options
95+ } ;
96+
97+ // Special handling for help option
98+ if ( processed . help ) {
99+ processed . shouldShowHelp = true ;
100+ }
101+
102+ return processed ;
103+ }
104+
105+ /**
106+ * Validate argument constraints and requirements
107+ */
108+ validateArguments ( options = { } ) {
109+ const errors = [ ] ;
110+ const result = {
111+ valid : true ,
112+ errors,
113+ warnings : [ ]
114+ } ;
115+
116+ // Validate region format
117+ if ( options . region && ! / ^ [ a - z 0 - 9 - ] + $ / . test ( options . region ) ) {
118+ errors . push ( 'Region must contain only lowercase letters, numbers, and hyphens' ) ;
119+ }
120+
121+ // Validate repository path if provided
122+ if ( options . repositoryPath && typeof options . repositoryPath !== 'string' ) {
123+ errors . push ( 'Repository path must be a string' ) ;
124+ }
125+
126+ // Validate stack name format
127+ if ( options . stackName && ! / ^ [ a - z A - Z 0 - 9 - ] + $ / . test ( options . stackName ) ) {
128+ errors . push ( 'Stack name must contain only letters, numbers, and hyphens' ) ;
129+ }
130+
131+ // Update validation status
132+ result . valid = errors . length === 0 ;
133+
134+ return result ;
135+ }
136+
137+ /**
138+ * Pre-execution validation
139+ */
140+ async preValidate ( options = { } ) {
141+ try {
142+ // Process and validate arguments first
143+ const processedOptions = this . processArguments ( options ) ;
144+ const argumentValidation = this . validateArguments ( processedOptions ) ;
145+
146+ if ( ! argumentValidation . valid ) {
147+ const error = new Error ( `Invalid arguments: ${ argumentValidation . errors . join ( ', ' ) } ` ) ;
148+ error . code = 'VALIDATION_ERROR' ;
149+
150+ const enhancedError = this . createContextAwareError ( error , {
151+ operation : 'OIDC argument validation' ,
152+ component : 'argument processor' ,
153+ validationErrors : argumentValidation . errors
154+ } ) ;
155+
156+ return {
157+ success : false ,
158+ error : enhancedError . message ,
159+ enhancedError,
160+ argumentValidation
161+ } ;
162+ }
163+
164+ this . showProgress ( 'Validating dependencies...' , processedOptions ) ;
165+
166+ // Validate required tools are available
167+ const dependencyResult = await this . validateDependencies ( processedOptions ) ;
168+
169+ if ( ! dependencyResult . valid ) {
170+ const missingTools = dependencyResult . missing . map ( tool => tool . name ) . join ( ', ' ) ;
171+
172+ // Create enhanced error with context and recovery suggestions
173+ const error = new Error ( `Missing required tools: ${ missingTools } ` ) ;
174+ error . code = 'NOT_FOUND' ;
175+
176+ const enhancedError = this . handleDependencyError ( error , {
177+ operation : 'OIDC pre-validation' ,
178+ component : 'dependency check' ,
179+ missingTools : dependencyResult . missing
180+ } ) ;
181+
182+ return {
183+ success : false ,
184+ error : enhancedError . message ,
185+ enhancedError,
186+ dependencyResult
187+ } ;
188+ }
189+
190+ this . showProgress ( 'Dependencies validated successfully' , processedOptions ) ;
191+ return {
192+ success : true ,
193+ processedOptions,
194+ argumentValidation,
195+ dependencyResult
196+ } ;
197+
198+ } catch ( error ) {
199+ // Handle unexpected validation errors
200+ const enhancedError = this . createContextAwareError ( error , {
201+ operation : 'OIDC pre-validation' ,
202+ component : 'validation system'
203+ } ) ;
204+
205+ return {
206+ success : false ,
207+ error : enhancedError . message ,
208+ enhancedError
209+ } ;
210+ }
211+ }
212+
213+ /**
214+ * Main command execution logic
215+ */
216+ async run ( options = { } ) {
217+ const { dryRun = false } = options ;
218+
219+ if ( dryRun ) {
220+ return this . showDryRun ( options ) ;
221+ }
222+
223+ // Minimal implementation for current phase
224+ this . showProgress ( 'Initializing OIDC command...' , options ) ;
225+
226+ return {
227+ message : 'OIDC command executed successfully'
228+ } ;
229+ }
230+
231+ /**
232+ * Show dry run preview
233+ */
234+ showDryRun ( options ) {
235+ console . log ( '🔍 Dry Run - Preview of OIDC configuration actions:\n' ) ;
236+ console . log ( '📋 OIDC Setup:' ) ;
237+ console . log ( ' • Detect GitHub repository context' ) ;
238+ console . log ( ' • Validate AWS credentials and permissions' ) ;
239+ console . log ( ' • Generate IAM policies and trust relationships' ) ;
240+ console . log ( '\n💡 This was a dry run - no changes were made' ) ;
241+ console . log ( ' Run without --dry-run to execute OIDC setup' ) ;
242+
243+ return { dryRun : true , message : 'Dry run completed' } ;
244+ }
245+
246+ /**
247+ * Get help text for OIDC command
248+ */
249+ getHelpText ( ) {
250+ return `
251+ Configure GitHub Actions OIDC integration with AWS.
252+
253+ This command provides comprehensive GitHub Actions OIDC configuration
254+ with AWS through the toolkit's CLI framework.
255+
256+ Usage:
257+ claude-commands oidc [options]
258+
259+ Options:
260+ --help Show this help message
261+
262+ Examples:
263+ claude-commands oidc --help
264+
265+ This command enables secure GitHub Actions to AWS authentication using OIDC.
266+ ` . trim ( ) ;
267+ }
268+ }
269+
270+ module . exports = OidcCommand ;
0 commit comments