Untangle the requests a bit with help from async

This commit is contained in:
Ray Schamp 2016-04-16 12:49:48 -04:00
parent 87da93f9ea
commit 0aa9b7c587
3 changed files with 137 additions and 141 deletions

View file

@ -1,3 +1,4 @@
var async = require('async');
var defaults = require('lodash.defaults');
var glob = require('glob');
var path = require('path');
@ -73,16 +74,84 @@ var getPassCacheConditionName = function () {
return 'Cache ' + getPassRequestConditionName();
};
var getRouteHeaderConditionPairs = function (routes) {
return routes.map(function (route, id) {
return {
condition: {
var getBucketNameHeaderName = function () {
return 'Bucket name';
}
var notPassCondition = {
name: getNotPassRequestConditionName(),
statement: getAppRouteCondition('../static/*', routes, extraAppRoutes),
type: 'REQUEST',
priority: 10
};
var passCondition = {
name: getPassRequestConditionName(),
statement: fastly.negateConditionStatement(notPassCondition.statement),
type: 'REQUEST',
priority: 10
};
var passCacheCondition = defaults({name: getPassCacheConditionName(), type: 'CACHE'}, passCondition);
var bucketNameHeader = {
name: getBucketNameHeaderName(),
action: 'set',
ignore_if_set: 0,
type: 'REQUEST',
dst: 'http.host',
src: '"' + s3Bucket + '"',
request_condition: notPassCondition.name,
priority: 1
};
async.waterfall([
fastly.getLatestVersion.bind(fastly),
function (version, next) {
if (version.active) return next('Latest version is active. Will not modify.');
if (version.locked) return next('Latest version is locked. Cannot modify.');
async.parallel([
function (cb) {
async.series([
async.apply(fastly.setCondition.bind(fastly), version.number, notPassCondition),
async.apply(fastly.setFastlyHeader.bind(fastly), version.number, bucketNameHeader)
], cb)
},
function (cb) {
async.series([
async.apply(fastly.setCondition.bind(fastly), version.number, passCondition),
function (cb) {
async.parallel([
async.apply(
fastly.request.bind(fastly), 'PUT',
fastly.getFastlyAPIPrefix(serviceId, version.number) + '/request_settings/Pass',
{request_condition: passCondition.name}
),
async.apply(
fastly.request.bind(fastly), 'PUT',
fastly.getFastlyAPIPrefix(serviceId, version.number) + '/backend/femto',
{request_condition: passCondition.name}
)
], cb)
}
], cb)
},
function (cb) {
async.series([
async.apply(fastly.setCondition.bind(fastly), version.number, passCacheCondition),
async.apply(
fastly.request.bind(fastly), 'PUT',
fastly.getFastlyAPIPrefix(serviceId, version.number) + '/cache_settings/Pass',
{request_condition: passCacheCondition.name}
),
], cb)
},
function (cb) {
async.forEachOf(routes, function (route, id, cb) {
var condition = {
name: getConditionNameForView(route.view),
statement: 'req.url ~ "' + route.pattern + '"',
type: 'REQUEST',
priority: 10
},
header: {
};
var header = {
name: getHeaderNameForView(route.view),
action: 'set',
ignore_if_set: 0,
@ -91,132 +160,18 @@ var getRouteHeaderConditionPairs = function (routes) {
src: '"/' + route.view + '.html"',
request_condition: getConditionNameForView(route.view),
priority: id
},
};
async.series([
async.apply(fastly.setCondition.bind(fastly), version.number, condition),
async.apply(fastly.setFastlyHeader.bind(fastly), version.number, header)
], cb);
}, cb)
}
});
};
var notPassCondition = {
name: getNotPassRequestConditionName(),
statement: getAppRouteCondition('../static/*', routes, extraAppRoutes),
type: 'REQUEST',
priority: 10
};
var passCondition = {
name: getPassRequestConditionName(),
statement: fastly.negateConditionStatement(notPassCondition.statement),
type: 'REQUEST',
priority: 10
};
var routeHeaderConditionPairs = getRouteHeaderConditionPairs(routes);
fastly.getLatestVersion(function (err, version) {
if (err) return console.error(err);
if (version.active) return console.error('Latest version is active. Will not modify.');
if (version.locked) return console.error('Latest version is locked. Cannot modify.');
fastly.setCondition(
version.number, notPassCondition.name, notPassCondition,
function (err) {
], next);
}], function (err, responses) {
if (err) {
console.error('Failed to set !(Pass) request condition:');
console.dir(err);
console.error('Could not set bucket header without setting !(Pass) condition');
process.exit(1);
}
var bucketNameHeaderName = 'Bucket name';
fastly.setHeader(
version.number, bucketNameHeaderName,
{
name: bucketNameHeaderName,
action: 'set',
ignore_if_set: 0,
type: 'REQUEST',
dst: 'http.host',
src: '"' + s3Bucket + '"',
request_condition: notPassCondition.name,
priority: 1
},
function (err) {
if (err) {
console.error('Failed to set Bucket name header:', err);
console.log(err);
process.exit(1);
}
}
);
}
);
fastly.setCondition(
version.number, passCondition.name, passCondition,
function (err) {
if (err) return console.error('Failed to set Pass condition:', err);
fastly.request(
'PUT',
fastly.getFastlyAPIPrefix(serviceId, version.number) + '/backend/femto',
{request_condition: passCondition.name},
function (err) {
if (err) {
console.error('Failed to set femto backend to use Pass condition.', err);
process.exit(1);
}
}
);
fastly.request(
'PUT',
fastly.getFastlyAPIPrefix(serviceId, version.number) + '/request_settings/Pass',
{request_condition: passCondition.name},
function (err) {
if (err) {
console.error('Failed to set Pass request setting to use Pass condition.', err);
process.exit(1);
}
}
);
}
);
var passCacheCondition = defaults({name: getPassCacheConditionName(), type: 'CACHE'}, passCondition);
fastly.setCondition(
version.number, getPassCacheConditionName(), passCacheCondition,
function (err) {
if (err) {
console.error('Failed to set Cache Pass condition:', err, passCacheCondition);
process.exit(1);
}
fastly.request(
'PUT',
fastly.getFastlyAPIPrefix(serviceId, version.number),
{cache_condition: getPassCacheConditionName()},
function (err) {
if (err) {
console.error('Failed to set Pass cache setting to use Cache Pass condition', err);
process.exit(1);
}
}
);
}
);
routeHeaderConditionPairs.forEach(function (pair) {
var condition = pair.condition;
var header = pair.header;
fastly.setCondition(
version.number, condition.name, condition,
function (err, response) {
if (err) {
console.error('Failed to set route condition', condition.name, err);
process.exit(1);
}
fastly.setHeader(
version.number, header.name, header,
function (err) {
if (err) {
console.error('Failed to set route rewrite header', header.name, err);
process.exit(1);
}
}
)
}
);
});
});
);

View file

@ -13,10 +13,16 @@ module.exports = function (apiKey, serviceId) {
};
fastly.getLatestVersion = function (cb) {
if (!this.serviceId) return cb('No serviceId configured');
if (!this.serviceId) {
console.error('Failed to get latest version.');
return cb('No serviceId configured');
}
var url = '/service/'+ encodeURIComponent(this.serviceId) +'/version';
this.request('GET', url, function (err, versions) {
if (err) return cb(err);
if (err) {
console.error('Failed to get versions', err);
return cb(err);
}
var latestVersion = versions.reduce(function (latestVersion, version) {
if (!latestVersion) return version;
if (version.number > latestVersion.number) return version;
@ -26,24 +32,58 @@ module.exports = function (apiKey, serviceId) {
});
};
fastly.setCondition = function (version, name, condition, cb) {
if (!this.serviceId) return callback('No serviceId configured');
fastly.setCondition = function (version, condition, cb) {
if (!this.serviceId) {
console.error('Failed to set condition', condition);
return cb('No serviceId configured');
}
var name = condition.name;
var putUrl = this.getFastlyAPIPrefix(this.serviceId, version) + '/condition/' + encodeURIComponent(name);
var postUrl = this.getFastlyAPIPrefix(this.serviceId, version) + '/condition';
return this.request('PUT', putUrl, condition, function (err, response) {
if (err && err.statusCode === 404) return this.request('POST', postUrl, condition, cb);
return cb(err, response);
if (err && err.statusCode === 404) {
this.request('POST', postUrl, condition, function (err, response) {
if (err) {
console.log('Failed to POST header', header);
return cb(err);
}
return cb(null, response);
});
return;
}
if (err) {
console.error('Failed to PUT condition', condition);
return cb(err);
}
return cb(null, response);
}.bind(this));
};
fastly.setHeader = function (version, name, header, cb) {
fastly.setFastlyHeader = function (version, header, cb) {
if (!this.serviceId) {
console.error('Failed to set header', header);
cb('No serviceId configured');
}
var name = header.name;
var putUrl = this.getFastlyAPIPrefix(this.serviceId, version) + '/header/' + encodeURIComponent(name);
var postUrl = this.getFastlyAPIPrefix(this.serviceId, version) + '/header';
return this.request('PUT', putUrl, header, function (err, response) {
if (err && err.statusCode === 404) return this.request('POST', postUrl, header, cb);
return cb(err, response);
if (err && err.statusCode === 404) {
this.request('POST', postUrl, header, function (err, response) {
if (err) {
console.error('Failed to POST header', header);
return cb(err);
}
return cb(null, response);
});
return;
}
if (err) {
console.error('Failed to PUT header', header);
return cb(err);
}
return cb(null, response);
}.bind(this));
};
return fastly;
};

View file

@ -31,6 +31,7 @@
"raven": "0.10.0"
},
"devDependencies": {
"async": "1.5.2",
"autoprefixer": "6.3.6",
"classnames": "2.1.3",
"cookie": "0.2.2",