Skip to content

Commit

Permalink
Merge pull request #35 from akamai/release/0.4.0
Browse files Browse the repository at this point in the history
release 0.4.0
  • Loading branch information
humanshield314 authored Mar 12, 2019
2 parents f0f8572 + ad5d3cd commit 2348c49
Show file tree
Hide file tree
Showing 59 changed files with 2,604 additions and 141 deletions.
51 changes: 42 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@

* [Retrieving a specific rule from Property Manager](#retrieving-a-specific-rule-from-property-manager)

* [Using Property Manager user variables with Akamai Pipeline
](#using-property-manager-user-variables-with-akamai-pipeline)
* [Using Property Manager user variables](#using-property-manager-user-variables)

* [Using attributes that vary across environments with Akamai Pipeline](#using-attributes-that-vary-across-environments-with-akamai-pipeline)

Expand Down Expand Up @@ -458,17 +457,20 @@ You may want to manually retrieve the new rules from the Property Manager UI wit
To get the JSON syntax for these rules, open the property version in the Property Manager application, select a rule, and click **View Rule JSON** to display the syntax. You can then copy the JSON and [create a new snippet](#add-a-new-snippet) for the rule.
## Using Property Manager user variables with Akamai Pipeline
## Using Property Manager user variables
Some Property Manager behaviors, like Origin Server ([`origin`](https://developer.akamai.com/api/core_features/property_manager/v2018-02-27.html#origin)), let you define custom user variables for certain settings.
Some Property Manager behaviors, like Origin Server [`origin`](https://developer.akamai.com/api/core_features/property_manager/v2018-02-27.html#origin), let you define custom user variables for certain settings.
If you have an existing property that includes user variables, Akamai Pipeline recognizes these variables and automatically populates the `variabledefinitions.json` and the environment-specific `variables.json` files to support these variables.
Before using a property as a template for a pipeline or a local property configuration, see whether it contains custom variables. If it does, review these custom variables in the Property Manager application and adjust as needed.
When you’re finally ready to run the command to create the pipeline or local configuration, use the `--variable-mode user-var-value` option with one of these values:
As a best practice, review your property's custom variables in the Property Manager application before creating a new pipeline and adjust as needed. If you’re creating a pipeline from an existing property, you can use the `--variable-mode user-var-value` option with a value of `user-var-value` when running the `akamai new-pipeline` command.
* `user-var-value`. Creates local versions of the custom variables that the CLI can use.
See the Property Manager help system for more information about setting user variables in the GUI application.
* `no-var`. Does not create local versions of the custom variables.
If you need to declare new user variables after you create your pipeline, you'll need to revise the `../environments/variableDefinitions.json` and `../environments/{environment}/variables.json` files using the [syntax for Property Manager API variables](https://developer.akamai.com/api/core_features/property_manager/v1.html#declaringvariables).
If you’re creating a new property from scratch, you can also use the `default` value, which replaces parts of the template configuration, like the `origin` behavior, with Property Manager’s default settings.
If you've already created a pipeline and want declare a new user variable, you can revise the `../environments/variableDefinitions.json` and `../environments/{environment}/variables.json` files using the [syntax for Property Manager API variables](https://developer.akamai.com/api/core_features/property_manager/v1.html#declaringvariables).
## Using attributes that vary across environments with Akamai Pipeline
Expand Down Expand Up @@ -552,18 +554,49 @@ If you want to use multiple edge hostnames with any environment in your pipeline
[
{
"cnameFrom": "www.example.com",
"cnameTo": "www.example.edgekey.net",
"cnameTo": "www.example.edgesuite.net",
"cnameType": "EDGE_HOSTNAME",
"edgeHostnameId": null
},
{
"cnameFrom": "www.example-1.com",
"cnameTo": "www.example-1.edgekey.net",
"certEnrollmentId": "12356666",
"cnameType": "EDGE_HOSTNAME",
"edgeHostnameId": null
}
]
When entering the `cnameTo` value, remember that the domain suffix is different for each type of edge hostname:
<table>
<tr>
<th>Edge hostname type</th>
<th>Domain suffix</th>
<th>Additional tasks</th>
</tr>
<tr>
<td>enhanced TLS</td>
<td>edgekey.net</td>
<td><p>Include the enrollment ID:</p>
<ol>
<li>Retrieve the <code>enrollment-id</code> from the <a href="https://github.com/akamai/cli-cps">CPS CLI</a></li>
<li>Enter the ID as the <code>certEnrollmentId</code> value.</li>
</ol>
</td>
</tr>
<tr>
<td>standard Transport Layer Security (TLS)</td>
<td>edgesuite.net</td>
<td>Not applicable.</td>
</tr>
<tr>
<td>shared certificate</td>
<td>akamaized.net</td>
<td>Not applicable.</td>
</tr>
</table>
When you run the `akamai pipeline save` command, the CLI will create edge hostnames for each block, or find the right block if the edge hostname already exists for the environment.
## Working with advanced behaviors
Expand Down
4 changes: 2 additions & 2 deletions cli.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
{
"name": "snippets",
"aliases": ["pm", "property-manager"],
"version": "0.3.6",
"version": "0.4.0",
"description": "Property Manager CLI for DevOps"
},
{
"name": "pipeline",
"aliases": ["pl", "pipeline", "pd", "proddeploy"],
"version": "0.3.6",
"version": "0.4.0",
"description": "Akamai Pipeline for DevOps"
}
]
Expand Down
17 changes: 10 additions & 7 deletions docs/cli_pm_commands_help.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ In order to create a new property you also need to specify a group Id, product I
-d, --productId [productId] Product ID, optional if -e propertyId/Name is used
-e, --propertyId [propertyId/propertyName] Use existing property as blue print for PM CLI property. Either pass property ID or exact property name. PM CLI will lookup account information like group id, contract id and product id of the existing property and use the information for creating PM CLI properties
-n, --version [version] Can be used only if option '-e' is being used. Specify version of existing property being used as blue print, if omitted, use latest
--variable-mode [variableMode] Choose how your new property will pull in variable. Allowed values are 'default', 'no-var', and 'user-var-value'. Only works when creating a property from an existing property
--secure Make new property secure
--insecure Make new property not secure
-h, --help output usage information
Expand All @@ -68,9 +69,10 @@ In order to create a new property you also need to specify a group Id, product I
Import a property from Property Manager.

Options:
-p, --property [propertyName] PM CLI property name
--dry-run Just parse the parameters and print out the json generated that would normally call the create property funtion.
-h, --help output usage information
-p, --property [propertyName] PM CLI property name
--dry-run Just parse the parameters and print out the json generated that would normally call the create property funtion.
--variable-mode [variableMode] Choose how your import will pull in variables. Allowed values are 'no-var' and 'user-var-value'. Default functionality is no-var
-h, --help output usage information


## <a name="pull"></a>Update property
Expand All @@ -81,10 +83,11 @@ Update local property with the latest from papi.
Update local property with the latest from Property Manager.

Options:
-p, --property [propertyName] PM CLI property name
--dry-run Just parse the parameters and print out the json generated that would normally call the create property funtion.
--force-update WARNING: This option will bypass the confirmation prompt and will overwrite your local files
-h, --help output usage information
-p, --property [propertyName] PM CLI property name
--dry-run Just parse the parameters and print out the json generated that would normally call the create property funtion.
--variable-mode [variableMode] Choose how your update-local will pull in variables. Allowed values are 'no-var' and 'user-var-value'. Default functionality is no-var
--force-update WARNING: This option will bypass the confirmation prompt and will overwrite your local files
-h, --help output usage information


## <a name="merge"></a>Merge
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cli-promotional-deployment",
"version": "0.3.6",
"version": "0.4.0",
"engines": {
"node": ">=8.0.0"
},
Expand Down
17 changes: 6 additions & 11 deletions src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@ module.exports = function(cmdArgs = process.argv, procEnv = process.env,
const showDefaults = commonCli.showDefaults.bind(commonCli);
const search = commonCli.search.bind(commonCli);


const printAllowedModes = commonCli.printAllowedModes;

const checkVariableModeOptions = commonCli.checkVariableModeOptions;

/**
* Constructs a new DevOps instances based on command line options.
* This allows for customizations of dependencies like the record to file, replay from file open client.
Expand Down Expand Up @@ -175,16 +180,6 @@ module.exports = function(cmdArgs = process.argv, procEnv = process.env,
showDefaults(devops);
};

const allowedModes = helpers.allowedModes;

const printAllowedModes = function() {
return `'${allowedModes.slice(0, allowedModes.length - 1).join(`', '`)}', and '${allowedModes.slice(-1)}'`;
};

const checkVariableModeOptions = function(mode) {
const allowedVarModes = new Set(allowedModes);
return allowedVarModes.has(mode);
};
/**
* Creates a new devops pipeline (devops pipeline)
* @type {Function}
Expand Down Expand Up @@ -219,7 +214,7 @@ module.exports = function(cmdArgs = process.argv, procEnv = process.env,

let environmentGroupIds = associateEnvironmentsGroupIds(environments, groupIds);

let variableMode = options.variableMode || allowedModes[0];
let variableMode = options.variableMode || helpers.allowedModes[0];
if (options.variableMode && !(propertyId || propertyName)) {
throw new errors.ArgumentError(`Variable Mode usable only with an existing property.`,
"variable_mode_needs_existing_property");
Expand Down
4 changes: 4 additions & 0 deletions src/command.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,10 @@ class DevOpsCommand extends Command {
}
}

// Trying to remove "executeSubCommand" calls so it doesn't try to do that when it "detects" an alias
// The way the original author write it is that it will call a subcommand seperately from the framework
executeSubCommand() {}

/**
* Variadic argument with `name` is not the last argument as required.
*
Expand Down
21 changes: 21 additions & 0 deletions src/common/common_cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -452,5 +452,26 @@ class CommonCli {
});
}

printAllowedModes() {
let allowedModes = helpers.allowedModes;
return `'${allowedModes.slice(0, allowedModes.length - 1).join(`', '`)}', and '${allowedModes.slice(-1)}'`;
}

printAllowedModesUpdateOrImport() {
let allowedModesImportUpdateLocal = helpers.allowedModesImportUpdateLocal;
return `'${allowedModesImportUpdateLocal.slice(0, allowedModesImportUpdateLocal.length - 1).join(`', '`)}' and '${allowedModesImportUpdateLocal.slice(-1)}'`;
}

checkVariableModeOptions(mode) {
let allowedModes = helpers.allowedModes;
const allowedVarModes = new Set(allowedModes);
return allowedVarModes.has(mode);
}
checkVariableModeOptionsImportUpdateLocal(mode) {
let allowedModesImportUpdateLocal = helpers.allowedModesImportUpdateLocal;
const allowedVarModes = new Set(allowedModesImportUpdateLocal);
return allowedVarModes.has(mode);
}

}
module.exports = CommonCli;
65 changes: 30 additions & 35 deletions src/edgehostname_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,49 +94,44 @@ class EdgeHostnameManager {
});
return;
}

//currently papi doesn't support creation of edgekey.net hostnames. So there is some dead code ahead.
let edgeDomain;
let createReq = {
productId: this.projectInfo.productId,
ipVersionBehavior: "IPV6_COMPLIANCE",
};
if (hostname.cnameTo.endsWith(EdgeDomains.EDGE_SUITE)) {
let edgeDomain;
if (hostname.cnameTo.endsWith(EdgeDomains.EDGE_SUITE)) {
edgeDomain = "edgesuite.net";
} else {
edgeDomain = "edgekey.net";
}
let prefix = hostname.cnameTo.slice(0, hostname.cnameTo.length - (edgeDomain.length + 1));

let createReq = {
productId: this.projectInfo.productId,
ipVersionBehavior: "IPV6_COMPLIANCE",
domainPrefix: prefix,
domainSuffix: edgeDomain //TODO: allow creation of other domains as well.
};
if (edgeDomain === "edgekey.net") {
createReq.secure = true;
if (!hostname.slotNumber) {
this.errors.push({
message: `Need 'slotNumber' of hostname in order to create secure edge hostname`,
messageId: "missing_slot_number",
edgehostname: hostname.cnameTo
});
return;
}
createReq.slotNumber = hostname.slotNumber;
edgeDomain = "edgesuite.net";
} else if (hostname.cnameTo.endsWith(EdgeDomains.EDGE_KEY)) {
if (!hostname.certEnrollmentId) {
this.errors.push({
message: `Need 'certEnrollmentId' of hostname in order to create secure edge hostname`,
messageId: "missing_certEnrollmentId",
edgehostname: hostname.cnameTo
});
return;
}
let result = await this.papi.createEdgeHostname(this.projectInfo.contractId, envInfo.groupId, createReq);
logger.info("Got create edgehostname result:", result);
hostname.edgeHostnameId = EdgeHostnameManager._extractEdgeHostnameId(result);
this.hostnamesCreated.push({
name: hostname.cnameTo,
id: hostname.edgeHostnameId
});
edgeDomain = "edgekey.net";
createReq.secure = true;
createReq.certEnrollmentId = hostname.certEnrollmentId
} else {
this.errors.push({
message: `'${hostname.cnameTo}' is not a supported edge hostname for creation, only edge hostnames under 'edgesuite.net' domain can be created. Please create manually`,
message: `'${hostname.cnameTo}' is not a supported edge hostname for creation, only edge hostnames under 'edgesuite.net' or 'edgekey.net' domains can be created. Please create manually`,
messageId: "unsupported_edgehostname",
edgehostname: hostname.cnameTo
});
return;
}
let prefix = hostname.cnameTo.slice(0, hostname.cnameTo.length - (edgeDomain.length + 1));
createReq.domainPrefix = prefix;
createReq.domainSuffix = edgeDomain //TODO: allow creation of other domains as well.

let result = await this.papi.createEdgeHostname(this.projectInfo.contractId, envInfo.groupId, createReq);
logger.info("Got create edgehostname result:", result);
hostname.edgeHostnameId = EdgeHostnameManager._extractEdgeHostnameId(result);
this.hostnamesCreated.push({
name: hostname.cnameTo,
id: hostname.edgeHostnameId
});
}

cleanHostnameIds(hostnames) {
Expand Down
7 changes: 4 additions & 3 deletions src/environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ class Environment {
this.processValidationResults(envInfo, validationResult, results);
this.storeEnvironmentInfo(envInfo);
} catch (error) {
if (error instanceof errors.RestApiError) {
if (error instanceof errors.RestApiError && error.args[1]["type"] !== undefined && error.args[1]["type"].includes("json-schema-invalid")) {
results.validationPerformed = true;
this.processValidationResults(envInfo, error.args[1], results);
this.storeEnvironmentInfo(envInfo);
Expand Down Expand Up @@ -499,7 +499,7 @@ class Environment {
this.processValidationResults(envInfo, response, results);
this.storeEnvironmentInfo(envInfo);
} catch (error) {
if (error instanceof errors.RestApiError) {
if (error instanceof errors.RestApiError && error.args[1]["type"] !== undefined && error.args[1]["type"].includes("json-schema-invalid")) {
this.processValidationResults(envInfo, error.args[1], results);
this.storeEnvironmentInfo(envInfo);
} else {
Expand All @@ -513,8 +513,9 @@ class Environment {
results.edgeHostnames = await this.createEdgeHostnames(hostnames);
this.checkForLastSavedHostnameErrors(envInfo, results);
if (results.edgeHostnames.errors.length === 0) {
await papi.storePropertyVersionHostnames(envInfo.propertyId,
let versionHostnamesResponse = await papi.storePropertyVersionHostnames(envInfo.propertyId,
envInfo.latestVersionInfo.propertyVersion, hostnames, this.project.getProjectInfo().contractId, envInfo.groupId);
envInfo.latestVersionInfo.etag = versionHostnamesResponse.etag;
results.storedHostnames = true;
}
hostnamesHash = helpers.createHash(hostnames);
Expand Down
4 changes: 4 additions & 0 deletions src/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ class HashMaker {
}

const allowedModes = ["default", "no-var", "user-var-value"];
const allowedModesImportUpdateLocal = ["no-var", "user-var-value"];



const INTEGER = /^(0|[1-9][0-9]*)$/;
Expand Down Expand Up @@ -98,6 +100,8 @@ module.exports = {

allowedModes: allowedModes,

allowedModesImportUpdateLocal: allowedModesImportUpdateLocal,

repeatable: function(parseFunction) {
return function(value, memo) {
memo.push(parseFunction(value));
Expand Down
8 changes: 4 additions & 4 deletions src/merger.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class Merger {
this.project = project;
this.environment = environment;
this.getEL = dependencies.getEL;
this.errorString = `Can't load template include: `;
this.errorId = "cannot_load_template";
}

__createEL(variables, variableDefinitions, loadFunction) {
Expand Down Expand Up @@ -69,8 +71,7 @@ class Merger {
hashMaker.update(include.resource);
return include
} catch (error) {
throw new errors.DependencyError(`Can't load template include: '${name}'`,
"cannot_load_template", name);
throw new errors.DependencyError(this.errorString + `'${name}'`, this.errorId, name);
}
});

Expand All @@ -91,8 +92,7 @@ class Merger {
try {
return this.project.loadTemplate(name);
} catch (error) {
throw new errors.DependencyError(`Can't load template include: '${name}'`,
"cannot_load_template", name);
throw new errors.DependencyError(this.errorString + `'${name}'`, this.errorId, name);
}
});

Expand Down
Loading

0 comments on commit 2348c49

Please sign in to comment.