1// Code generated by smithy-go-codegen DO NOT EDIT. 2 3package ec2 4 5import ( 6 "context" 7 "fmt" 8 awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" 9 "github.com/aws/aws-sdk-go-v2/aws/signer/v4" 10 "github.com/aws/smithy-go/middleware" 11 smithytime "github.com/aws/smithy-go/time" 12 smithyhttp "github.com/aws/smithy-go/transport/http" 13 smithywaiter "github.com/aws/smithy-go/waiter" 14 "github.com/jmespath/go-jmespath" 15 "strconv" 16 "time" 17) 18 19// Retrieves the encrypted administrator password for a running Windows instance. 20// The Windows password is generated at boot by the EC2Config service or EC2Launch 21// scripts (Windows Server 2016 and later). This usually only happens the first 22// time an instance is launched. For more information, see EC2Config 23// (https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/UsingConfig_WinAMI.html) 24// and EC2Launch 25// (https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2launch.html) in the 26// Amazon EC2 User Guide. For the EC2Config service, the password is not generated 27// for rebundled AMIs unless Ec2SetPassword is enabled before bundling. The 28// password is encrypted using the key pair that you specified when you launched 29// the instance. You must provide the corresponding key pair file. When you launch 30// an instance, password generation and encryption may take a few minutes. If you 31// try to retrieve the password before it's available, the output returns an empty 32// string. We recommend that you wait up to 15 minutes after launching an instance 33// before trying to retrieve the generated password. 34func (c *Client) GetPasswordData(ctx context.Context, params *GetPasswordDataInput, optFns ...func(*Options)) (*GetPasswordDataOutput, error) { 35 if params == nil { 36 params = &GetPasswordDataInput{} 37 } 38 39 result, metadata, err := c.invokeOperation(ctx, "GetPasswordData", params, optFns, addOperationGetPasswordDataMiddlewares) 40 if err != nil { 41 return nil, err 42 } 43 44 out := result.(*GetPasswordDataOutput) 45 out.ResultMetadata = metadata 46 return out, nil 47} 48 49type GetPasswordDataInput struct { 50 51 // The ID of the Windows instance. 52 // 53 // This member is required. 54 InstanceId *string 55 56 // Checks whether you have the required permissions for the action, without 57 // actually making the request, and provides an error response. If you have the 58 // required permissions, the error response is DryRunOperation. Otherwise, it is 59 // UnauthorizedOperation. 60 DryRun bool 61} 62 63type GetPasswordDataOutput struct { 64 65 // The ID of the Windows instance. 66 InstanceId *string 67 68 // The password of the instance. Returns an empty string if the password is not 69 // available. 70 PasswordData *string 71 72 // The time the data was last updated. 73 Timestamp *time.Time 74 75 // Metadata pertaining to the operation's result. 76 ResultMetadata middleware.Metadata 77} 78 79func addOperationGetPasswordDataMiddlewares(stack *middleware.Stack, options Options) (err error) { 80 err = stack.Serialize.Add(&awsEc2query_serializeOpGetPasswordData{}, middleware.After) 81 if err != nil { 82 return err 83 } 84 err = stack.Deserialize.Add(&awsEc2query_deserializeOpGetPasswordData{}, middleware.After) 85 if err != nil { 86 return err 87 } 88 if err = addSetLoggerMiddleware(stack, options); err != nil { 89 return err 90 } 91 if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { 92 return err 93 } 94 if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { 95 return err 96 } 97 if err = addResolveEndpointMiddleware(stack, options); err != nil { 98 return err 99 } 100 if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { 101 return err 102 } 103 if err = addRetryMiddlewares(stack, options); err != nil { 104 return err 105 } 106 if err = addHTTPSignerV4Middleware(stack, options); err != nil { 107 return err 108 } 109 if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { 110 return err 111 } 112 if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { 113 return err 114 } 115 if err = addClientUserAgent(stack); err != nil { 116 return err 117 } 118 if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { 119 return err 120 } 121 if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { 122 return err 123 } 124 if err = addOpGetPasswordDataValidationMiddleware(stack); err != nil { 125 return err 126 } 127 if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetPasswordData(options.Region), middleware.Before); err != nil { 128 return err 129 } 130 if err = addRequestIDRetrieverMiddleware(stack); err != nil { 131 return err 132 } 133 if err = addResponseErrorMiddleware(stack); err != nil { 134 return err 135 } 136 if err = addRequestResponseLogging(stack, options); err != nil { 137 return err 138 } 139 return nil 140} 141 142// GetPasswordDataAPIClient is a client that implements the GetPasswordData 143// operation. 144type GetPasswordDataAPIClient interface { 145 GetPasswordData(context.Context, *GetPasswordDataInput, ...func(*Options)) (*GetPasswordDataOutput, error) 146} 147 148var _ GetPasswordDataAPIClient = (*Client)(nil) 149 150// PasswordDataAvailableWaiterOptions are waiter options for 151// PasswordDataAvailableWaiter 152type PasswordDataAvailableWaiterOptions struct { 153 154 // Set of options to modify how an operation is invoked. These apply to all 155 // operations invoked for this client. Use functional options on operation call to 156 // modify this list for per operation behavior. 157 APIOptions []func(*middleware.Stack) error 158 159 // MinDelay is the minimum amount of time to delay between retries. If unset, 160 // PasswordDataAvailableWaiter will use default minimum delay of 15 seconds. Note 161 // that MinDelay must resolve to a value lesser than or equal to the MaxDelay. 162 MinDelay time.Duration 163 164 // MaxDelay is the maximum amount of time to delay between retries. If unset or set 165 // to zero, PasswordDataAvailableWaiter will use default max delay of 120 seconds. 166 // Note that MaxDelay must resolve to value greater than or equal to the MinDelay. 167 MaxDelay time.Duration 168 169 // LogWaitAttempts is used to enable logging for waiter retry attempts 170 LogWaitAttempts bool 171 172 // Retryable is function that can be used to override the service defined 173 // waiter-behavior based on operation output, or returned error. This function is 174 // used by the waiter to decide if a state is retryable or a terminal state. By 175 // default service-modeled logic will populate this option. This option can thus be 176 // used to define a custom waiter state with fall-back to service-modeled waiter 177 // state mutators.The function returns an error in case of a failure state. In case 178 // of retry state, this function returns a bool value of true and nil error, while 179 // in case of success it returns a bool value of false and nil error. 180 Retryable func(context.Context, *GetPasswordDataInput, *GetPasswordDataOutput, error) (bool, error) 181} 182 183// PasswordDataAvailableWaiter defines the waiters for PasswordDataAvailable 184type PasswordDataAvailableWaiter struct { 185 client GetPasswordDataAPIClient 186 187 options PasswordDataAvailableWaiterOptions 188} 189 190// NewPasswordDataAvailableWaiter constructs a PasswordDataAvailableWaiter. 191func NewPasswordDataAvailableWaiter(client GetPasswordDataAPIClient, optFns ...func(*PasswordDataAvailableWaiterOptions)) *PasswordDataAvailableWaiter { 192 options := PasswordDataAvailableWaiterOptions{} 193 options.MinDelay = 15 * time.Second 194 options.MaxDelay = 120 * time.Second 195 options.Retryable = passwordDataAvailableStateRetryable 196 197 for _, fn := range optFns { 198 fn(&options) 199 } 200 return &PasswordDataAvailableWaiter{ 201 client: client, 202 options: options, 203 } 204} 205 206// Wait calls the waiter function for PasswordDataAvailable waiter. The maxWaitDur 207// is the maximum wait duration the waiter will wait. The maxWaitDur is required 208// and must be greater than zero. 209func (w *PasswordDataAvailableWaiter) Wait(ctx context.Context, params *GetPasswordDataInput, maxWaitDur time.Duration, optFns ...func(*PasswordDataAvailableWaiterOptions)) error { 210 if maxWaitDur <= 0 { 211 return fmt.Errorf("maximum wait time for waiter must be greater than zero") 212 } 213 214 options := w.options 215 for _, fn := range optFns { 216 fn(&options) 217 } 218 219 if options.MaxDelay <= 0 { 220 options.MaxDelay = 120 * time.Second 221 } 222 223 if options.MinDelay > options.MaxDelay { 224 return fmt.Errorf("minimum waiter delay %v must be lesser than or equal to maximum waiter delay of %v.", options.MinDelay, options.MaxDelay) 225 } 226 227 ctx, cancelFn := context.WithTimeout(ctx, maxWaitDur) 228 defer cancelFn() 229 230 logger := smithywaiter.Logger{} 231 remainingTime := maxWaitDur 232 233 var attempt int64 234 for { 235 236 attempt++ 237 apiOptions := options.APIOptions 238 start := time.Now() 239 240 if options.LogWaitAttempts { 241 logger.Attempt = attempt 242 apiOptions = append([]func(*middleware.Stack) error{}, options.APIOptions...) 243 apiOptions = append(apiOptions, logger.AddLogger) 244 } 245 246 out, err := w.client.GetPasswordData(ctx, params, func(o *Options) { 247 o.APIOptions = append(o.APIOptions, apiOptions...) 248 }) 249 250 retryable, err := options.Retryable(ctx, params, out, err) 251 if err != nil { 252 return err 253 } 254 if !retryable { 255 return nil 256 } 257 258 remainingTime -= time.Since(start) 259 if remainingTime < options.MinDelay || remainingTime <= 0 { 260 break 261 } 262 263 // compute exponential backoff between waiter retries 264 delay, err := smithywaiter.ComputeDelay( 265 attempt, options.MinDelay, options.MaxDelay, remainingTime, 266 ) 267 if err != nil { 268 return fmt.Errorf("error computing waiter delay, %w", err) 269 } 270 271 remainingTime -= delay 272 // sleep for the delay amount before invoking a request 273 if err := smithytime.SleepWithContext(ctx, delay); err != nil { 274 return fmt.Errorf("request cancelled while waiting, %w", err) 275 } 276 } 277 return fmt.Errorf("exceeded max wait time for PasswordDataAvailable waiter") 278} 279 280func passwordDataAvailableStateRetryable(ctx context.Context, input *GetPasswordDataInput, output *GetPasswordDataOutput, err error) (bool, error) { 281 282 if err == nil { 283 pathValue, err := jmespath.Search("length(PasswordData) > `0`", output) 284 if err != nil { 285 return false, fmt.Errorf("error evaluating waiter state: %w", err) 286 } 287 288 expectedValue := "true" 289 bv, err := strconv.ParseBool(expectedValue) 290 if err != nil { 291 return false, fmt.Errorf("error parsing boolean from string %w", err) 292 } 293 value, ok := pathValue.(bool) 294 if !ok { 295 return false, fmt.Errorf("waiter comparator expected bool value got %T", pathValue) 296 } 297 298 if value == bv { 299 return false, nil 300 } 301 } 302 303 return true, nil 304} 305 306func newServiceMetadataMiddleware_opGetPasswordData(region string) *awsmiddleware.RegisterServiceMetadata { 307 return &awsmiddleware.RegisterServiceMetadata{ 308 Region: region, 309 ServiceID: ServiceID, 310 SigningName: "ec2", 311 OperationName: "GetPasswordData", 312 } 313} 314