import * as s3 from "../../aws-s3";
import * as s3_assets from "../../aws-s3-assets";
import { Duration } from "../../core";
import { InitBindOptions, InitElementConfig, InitPlatform } from './private/cfn-init-internal';
/**
 * (experimental) An object that represents reasons to restart an InitService.
 *
 * Pass an instance of this object to the `InitFile`, `InitCommand`,
 * `InitSource` and `InitPackage` objects, and finally to an `InitService`
 * itself to cause the actions (files, commands, sources, and packages)
 * to trigger a restart of the service.
 *
 * For example, the following will run a custom command to install Nginx,
 * and trigger the nginx service to be restarted after the command has run.
 *
 * ```ts
 * const handle = new ec2.InitServiceRestartHandle();
 * ec2.CloudFormationInit.fromElements(
 *    ec2.InitCommand.shellCommand('/usr/bin/custom-nginx-install.sh', { serviceRestartHandles: [handle] }),
 *    ec2.InitService.enable('nginx', { serviceRestartHandle: handle }),
 * );
 * ```
 *
 * @experimental
 */
export declare class InitServiceRestartHandle {
    private readonly commands;
    private readonly files;
    private readonly sources;
    private readonly packages;
    /**
     * Add a command key to the restart set
     * @internal
     */
    _addCommand(key: string): number;
    /**
     * Add a file key to the restart set
     * @internal
     */
    _addFile(key: string): number;
    /**
     * Add a source key to the restart set
     * @internal
     */
    _addSource(key: string): number;
    /**
     * Add a package key to the restart set
     * @internal
     */
    _addPackage(packageType: string, key: string): void;
    /**
     * Render the restart handles for use in an InitService declaration
     * @internal
     */
    _renderRestartHandles(): any;
}
/**
 * (experimental) Base class for all CloudFormation Init elements.
 *
 * @experimental
 */
export declare abstract class InitElement {
    /**
     * (experimental) Returns the init element type for this element.
     *
     * @experimental
     */
    abstract readonly elementType: string;
    /**
     * Called when the Init config is being consumed. Renders the CloudFormation
     * representation of this init element, and calculates any authentication
     * properties needed, if any.
     *
     * @param options bind options for the element.
     * @internal
     */
    abstract _bind(options: InitBindOptions): InitElementConfig;
}
/**
 * (experimental) Options for InitCommand.
 *
 * @experimental
 */
export interface InitCommandOptions {
    /**
     * (experimental) Identifier key for this command.
     *
     * Commands are executed in lexicographical order of their key names.
     *
     * @default - Automatically generated based on index
     * @experimental
     */
    readonly key?: string;
    /**
     * (experimental) Sets environment variables for the command.
     *
     * This property overwrites, rather than appends, the existing environment.
     *
     * @default - Use current environment
     * @experimental
     */
    readonly env?: Record<string, string>;
    /**
     * (experimental) The working directory.
     *
     * @default - Use default working directory
     * @experimental
     */
    readonly cwd?: string;
    /**
     * (experimental) Command to determine whether this command should be run.
     *
     * If the test passes (exits with error code of 0), the command is run.
     *
     * @default - Always run the command
     * @experimental
     */
    readonly testCmd?: string;
    /**
     * (experimental) Continue running if this command fails.
     *
     * @default false
     * @experimental
     */
    readonly ignoreErrors?: boolean;
    /**
     * (experimental) The duration to wait after a command has finished in case the command causes a reboot.
     *
     * Set this value to `InitCommandWaitDuration.none()` if you do not want to wait for every command;
     * `InitCommandWaitDuration.forever()` directs cfn-init to exit and resume only after the reboot is complete.
     *
     * For Windows systems only.
     *
     * @default - 60 seconds
     * @experimental
     */
    readonly waitAfterCompletion?: InitCommandWaitDuration;
    /**
     * (experimental) Restart the given service(s) after this command has run.
     *
     * @default - Do not restart any service
     * @experimental
     */
    readonly serviceRestartHandles?: InitServiceRestartHandle[];
}
/**
 * (experimental) Represents a duration to wait after a command has finished, in case of a reboot (Windows only).
 *
 * @experimental
 */
export declare abstract class InitCommandWaitDuration {
    /**
     * (experimental) Wait for a specified duration after a command.
     *
     * @experimental
     */
    static of(duration: Duration): InitCommandWaitDuration;
    /**
     * (experimental) Do not wait for this command.
     *
     * @experimental
     */
    static none(): InitCommandWaitDuration;
    /**
     * (experimental) cfn-init will exit and resume only after a reboot.
     *
     * @experimental
     */
    static forever(): InitCommandWaitDuration;
    /**
     * Render to a CloudFormation value.
     * @internal
     */
    abstract _render(): any;
}
/**
 * (experimental) Command to execute on the instance.
 *
 * @experimental
 */
export declare class InitCommand extends InitElement {
    private readonly command;
    private readonly options;
    /**
     * (experimental) Run a shell command.
     *
     * Remember that some characters like `&`, `|`, `;`, `>` etc. have special meaning in a shell and
     * need to be preceded by a `\` if you want to treat them as part of a filename.
     *
     * @experimental
     */
    static shellCommand(shellCommand: string, options?: InitCommandOptions): InitCommand;
    /**
     * (experimental) Run a command from an argv array.
     *
     * You do not need to escape space characters or enclose command parameters in quotes.
     *
     * @experimental
     */
    static argvCommand(argv: string[], options?: InitCommandOptions): InitCommand;
    /**
     * (experimental) Returns the init element type for this element.
     *
     * @experimental
     */
    readonly elementType: string;
    private constructor();
    /** @internal */
    _bind(options: InitBindOptions): InitElementConfig;
}
/**
 * (experimental) Options for InitFile.
 *
 * @experimental
 */
export interface InitFileOptions {
    /**
     * (experimental) The name of the owning group for this file.
     *
     * Not supported for Windows systems.
     *
     * @default 'root'
     * @experimental
     */
    readonly group?: string;
    /**
     * (experimental) The name of the owning user for this file.
     *
     * Not supported for Windows systems.
     *
     * @default 'root'
     * @experimental
     */
    readonly owner?: string;
    /**
     * (experimental) A six-digit octal value representing the mode for this file.
     *
     * Use the first three digits for symlinks and the last three digits for
     * setting permissions. To create a symlink, specify 120xxx, where xxx
     * defines the permissions of the target file. To specify permissions for a
     * file, use the last three digits, such as 000644.
     *
     * Not supported for Windows systems.
     *
     * @default '000644'
     * @experimental
     */
    readonly mode?: string;
    /**
     * (experimental) True if the inlined content (from a string or file) should be treated as base64 encoded.
     *
     * Only applicable for inlined string and file content.
     *
     * @default false
     * @experimental
     */
    readonly base64Encoded?: boolean;
    /**
     * (experimental) Restart the given service after this file has been written.
     *
     * @default - Do not restart any service
     * @experimental
     */
    readonly serviceRestartHandles?: InitServiceRestartHandle[];
}
/**
 * (experimental) Additional options for creating an InitFile from an asset.
 *
 * @experimental
 */
export interface InitFileAssetOptions extends InitFileOptions, s3_assets.AssetOptions {
}
/**
 * (experimental) Create files on the EC2 instance.
 *
 * @experimental
 */
export declare abstract class InitFile extends InitElement {
    private readonly fileName;
    private readonly options;
    /**
     * (experimental) Use a literal string as the file content.
     *
     * @experimental
     */
    static fromString(fileName: string, content: string, options?: InitFileOptions): InitFile;
    /**
     * (experimental) Write a symlink with the given symlink target.
     *
     * @experimental
     */
    static symlink(fileName: string, target: string, options?: InitFileOptions): InitFile;
    /**
     * (experimental) Use a JSON-compatible object as the file content, write it to a JSON file.
     *
     * May contain tokens.
     *
     * @experimental
     */
    static fromObject(fileName: string, obj: Record<string, any>, options?: InitFileOptions): InitFile;
    /**
     * (experimental) Read a file from disk and use its contents.
     *
     * The file will be embedded in the template, so care should be taken to not
     * exceed the template size.
     *
     * If options.base64encoded is set to true, this will base64-encode the file's contents.
     *
     * @experimental
     */
    static fromFileInline(targetFileName: string, sourceFileName: string, options?: InitFileOptions): InitFile;
    /**
     * (experimental) Download from a URL at instance startup time.
     *
     * @experimental
     */
    static fromUrl(fileName: string, url: string, options?: InitFileOptions): InitFile;
    /**
     * (experimental) Download a file from an S3 bucket at instance startup time.
     *
     * @experimental
     */
    static fromS3Object(fileName: string, bucket: s3.IBucket, key: string, options?: InitFileOptions): InitFile;
    /**
     * (experimental) Create an asset from the given file.
     *
     * This is appropriate for files that are too large to embed into the template.
     *
     * @experimental
     */
    static fromAsset(targetFileName: string, path: string, options?: InitFileAssetOptions): InitFile;
    /**
     * (experimental) Use a file from an asset at instance startup time.
     *
     * @experimental
     */
    static fromExistingAsset(targetFileName: string, asset: s3_assets.Asset, options?: InitFileOptions): InitFile;
    /**
     * (experimental) Returns the init element type for this element.
     *
     * @experimental
     */
    readonly elementType: string;
    /**
     * @experimental
     */
    protected constructor(fileName: string, options: InitFileOptions);
    /** @internal */
    _bind(bindOptions: InitBindOptions): InitElementConfig;
    /**
     * Perform the actual bind and render
     *
     * This is in a second method so the superclass can guarantee that
     * the common work of registering into serviceHandles cannot be forgotten.
     * @internal
     */
    protected abstract _doBind(options: InitBindOptions): InitElementConfig;
    /**
     * Render the standard config block, given content vars
     * @internal
     */
    protected _standardConfig(fileOptions: InitFileOptions, platform: InitPlatform, contentVars: Record<string, any>): Record<string, any>;
}
/**
 * (experimental) Create Linux/UNIX groups and assign group IDs.
 *
 * Not supported for Windows systems.
 *
 * @experimental
 */
export declare class InitGroup extends InitElement {
    private groupName;
    private groupId?;
    /**
     * (experimental) Create a group from its name, and optionally, group id.
     *
     * @experimental
     */
    static fromName(groupName: string, groupId?: number): InitGroup;
    /**
     * (experimental) Returns the init element type for this element.
     *
     * @experimental
     */
    readonly elementType: string;
    /**
     * @experimental
     */
    protected constructor(groupName: string, groupId?: number | undefined);
    /** @internal */
    _bind(options: InitBindOptions): InitElementConfig;
}
/**
 * (experimental) Optional parameters used when creating a user.
 *
 * @experimental
 */
export interface InitUserOptions {
    /**
     * (experimental) The user's home directory.
     *
     * @default assigned by the OS
     * @experimental
     */
    readonly homeDir?: string;
    /**
     * (experimental) A user ID.
     *
     * The creation process fails if the user name exists with a different user ID.
     * If the user ID is already assigned to an existing user the operating system may
     * reject the creation request.
     *
     * @default assigned by the OS
     * @experimental
     */
    readonly userId?: number;
    /**
     * (experimental) A list of group names.
     *
     * The user will be added to each group in the list.
     *
     * @default the user is not associated with any groups.
     * @experimental
     */
    readonly groups?: string[];
}
/**
 * (experimental) Create Linux/UNIX users and to assign user IDs.
 *
 * Users are created as non-interactive system users with a shell of
 * /sbin/nologin. This is by design and cannot be modified.
 *
 * Not supported for Windows systems.
 *
 * @experimental
 */
export declare class InitUser extends InitElement {
    private readonly userName;
    private readonly userOptions;
    /**
     * (experimental) Create a user from user name.
     *
     * @experimental
     */
    static fromName(userName: string, options?: InitUserOptions): InitUser;
    /**
     * (experimental) Returns the init element type for this element.
     *
     * @experimental
     */
    readonly elementType: string;
    /**
     * @experimental
     */
    protected constructor(userName: string, userOptions: InitUserOptions);
    /** @internal */
    _bind(options: InitBindOptions): InitElementConfig;
}
/**
 * (experimental) Options for InitPackage.rpm/InitPackage.msi.
 *
 * @experimental
 */
export interface LocationPackageOptions {
    /**
     * (experimental) Identifier key for this package.
     *
     * You can use this to order package installs.
     *
     * @default - Automatically generated
     * @experimental
     */
    readonly key?: string;
    /**
     * (experimental) Restart the given service after this command has run.
     *
     * @default - Do not restart any service
     * @experimental
     */
    readonly serviceRestartHandles?: InitServiceRestartHandle[];
}
/**
 * (experimental) Options for InitPackage.yum/apt/rubyGem/python.
 *
 * @experimental
 */
export interface NamedPackageOptions {
    /**
     * (experimental) Specify the versions to install.
     *
     * @default - Install the latest version
     * @experimental
     */
    readonly version?: string[];
    /**
     * (experimental) Restart the given services after this command has run.
     *
     * @default - Do not restart any service
     * @experimental
     */
    readonly serviceRestartHandles?: InitServiceRestartHandle[];
}
/**
 * (experimental) A package to be installed during cfn-init time.
 *
 * @experimental
 */
export declare class InitPackage extends InitElement {
    private readonly type;
    private readonly versions;
    private readonly packageName?;
    private readonly serviceHandles?;
    /**
     * (experimental) Install an RPM from an HTTP URL or a location on disk.
     *
     * @experimental
     */
    static rpm(location: string, options?: LocationPackageOptions): InitPackage;
    /**
     * (experimental) Install a package using Yum.
     *
     * @experimental
     */
    static yum(packageName: string, options?: NamedPackageOptions): InitPackage;
    /**
     * (experimental) Install a package from RubyGems.
     *
     * @experimental
     */
    static rubyGem(gemName: string, options?: NamedPackageOptions): InitPackage;
    /**
     * (experimental) Install a package from PyPI.
     *
     * @experimental
     */
    static python(packageName: string, options?: NamedPackageOptions): InitPackage;
    /**
     * (experimental) Install a package using APT.
     *
     * @experimental
     */
    static apt(packageName: string, options?: NamedPackageOptions): InitPackage;
    /**
     * (experimental) Install an MSI package from an HTTP URL or a location on disk.
     *
     * @experimental
     */
    static msi(location: string, options?: LocationPackageOptions): InitPackage;
    /**
     * (experimental) Returns the init element type for this element.
     *
     * @experimental
     */
    readonly elementType: string;
    /**
     * @experimental
     */
    protected constructor(type: string, versions: string[], packageName?: string | undefined, serviceHandles?: InitServiceRestartHandle[] | undefined);
    /** @internal */
    _bind(options: InitBindOptions): InitElementConfig;
    /**
     * @experimental
     */
    protected renderPackageVersions(): any;
}
/**
 * (experimental) Options for an InitService.
 *
 * @experimental
 */
export interface InitServiceOptions {
    /**
     * (experimental) Enable or disable this service.
     *
     * Set to true to ensure that the service will be started automatically upon boot.
     *
     * Set to false to ensure that the service will not be started automatically upon boot.
     *
     * @default - true if used in `InitService.enable()`, no change to service
     * state if used in `InitService.fromOptions()`.
     * @experimental
     */
    readonly enabled?: boolean;
    /**
     * (experimental) Make sure this service is running or not running after cfn-init finishes.
     *
     * Set to true to ensure that the service is running after cfn-init finishes.
     *
     * Set to false to ensure that the service is not running after cfn-init finishes.
     *
     * @default - same value as `enabled`.
     * @experimental
     */
    readonly ensureRunning?: boolean;
    /**
     * (experimental) Restart service when the actions registered into the restartHandle have been performed.
     *
     * Register actions into the restartHandle by passing it to `InitFile`, `InitCommand`,
     * `InitPackage` and `InitSource` objects.
     *
     * @default - No files trigger restart
     * @experimental
     */
    readonly serviceRestartHandle?: InitServiceRestartHandle;
}
/**
 * (experimental) A services that be enabled, disabled or restarted when the instance is launched.
 *
 * @experimental
 */
export declare class InitService extends InitElement {
    private readonly serviceName;
    private readonly serviceOptions;
    /**
     * (experimental) Enable and start the given service, optionally restarting it.
     *
     * @experimental
     */
    static enable(serviceName: string, options?: InitServiceOptions): InitService;
    /**
     * (experimental) Disable and stop the given service.
     *
     * @experimental
     */
    static disable(serviceName: string): InitService;
    /**
     * (experimental) Returns the init element type for this element.
     *
     * @experimental
     */
    readonly elementType: string;
    private constructor();
    /** @internal */
    _bind(options: InitBindOptions): InitElementConfig;
}
/**
 * (experimental) Additional options for an InitSource.
 *
 * @experimental
 */
export interface InitSourceOptions {
    /**
     * (experimental) Restart the given services after this archive has been extracted.
     *
     * @default - Do not restart any service
     * @experimental
     */
    readonly serviceRestartHandles?: InitServiceRestartHandle[];
}
/**
 * (experimental) Additional options for an InitSource that builds an asset from local files.
 *
 * @experimental
 */
export interface InitSourceAssetOptions extends InitSourceOptions, s3_assets.AssetOptions {
}
/**
 * (experimental) Extract an archive into a directory.
 *
 * @experimental
 */
export declare abstract class InitSource extends InitElement {
    private readonly targetDirectory;
    private readonly serviceHandles?;
    /**
     * (experimental) Retrieve a URL and extract it into the given directory.
     *
     * @experimental
     */
    static fromUrl(targetDirectory: string, url: string, options?: InitSourceOptions): InitSource;
    /**
     * (experimental) Extract a GitHub branch into a given directory.
     *
     * @experimental
     */
    static fromGitHub(targetDirectory: string, owner: string, repo: string, refSpec?: string, options?: InitSourceOptions): InitSource;
    /**
     * (experimental) Extract an archive stored in an S3 bucket into the given directory.
     *
     * @experimental
     */
    static fromS3Object(targetDirectory: string, bucket: s3.IBucket, key: string, options?: InitSourceOptions): InitSource;
    /**
     * (experimental) Create an InitSource from an asset created from the given path.
     *
     * @experimental
     */
    static fromAsset(targetDirectory: string, path: string, options?: InitSourceAssetOptions): InitSource;
    /**
     * (experimental) Extract a directory from an existing directory asset.
     *
     * @experimental
     */
    static fromExistingAsset(targetDirectory: string, asset: s3_assets.Asset, options?: InitSourceOptions): InitSource;
    /**
     * (experimental) Returns the init element type for this element.
     *
     * @experimental
     */
    readonly elementType: string;
    /**
     * @experimental
     */
    protected constructor(targetDirectory: string, serviceHandles?: InitServiceRestartHandle[] | undefined);
    /** @internal */
    _bind(options: InitBindOptions): InitElementConfig;
    /**
     * Perform the actual bind and render
     *
     * This is in a second method so the superclass can guarantee that
     * the common work of registering into serviceHandles cannot be forgotten.
     * @internal
     */
    protected abstract _doBind(options: InitBindOptions): InitElementConfig;
}
