Deploy refactor (#1370)
* Change lambda function to recognize clean URLs * More bug fixes to CF template and function * Add redirect for root to /v2.0 * Fix lambda rewrite logic * Switch to using multiple cache behaviors * Experiment with deleting lambda@edge functions * Change lambda function to recognize clean URLs * More bug fixes to CF template and function * Add redirect for root to /v2.0 * Fix lambda rewrite logic * Switch to using multiple cache behaviors * Experiment with deleting lambda@edge functions * Update nodejs version in redirect lambda * Use edge lambda function and remove path redirects. * updated edge.js and cloudformation template * revamped lambda edge function, made other template adjustments Co-authored-by: Gunnar Aasen <gunnar.r.aasen@gmail.com>pull/1387/head
parent
cdc16ec8ab
commit
3d918af7b8
|
@ -94,13 +94,6 @@ $('.expand-label').click(function() {
|
||||||
$(this).next('.expand-content').slideToggle(200)
|
$(this).next('.expand-content').slideToggle(200)
|
||||||
})
|
})
|
||||||
|
|
||||||
//////////////////// Replace Missing Images with Placeholder ///////////////////
|
|
||||||
|
|
||||||
$(".article--content img").on("error", function() {
|
|
||||||
$(this).attr("src", "/img/coming-soon.svg");
|
|
||||||
$(this).attr("style", "max-width:500px;");
|
|
||||||
});
|
|
||||||
|
|
||||||
////////////////////////// Inject tooltips on load //////////////////////////////
|
////////////////////////// Inject tooltips on load //////////////////////////////
|
||||||
|
|
||||||
$('.tooltip').each( function(){
|
$('.tooltip').each( function(){
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
baseURL = "https://v2.docs.influxdata.com/"
|
baseURL = "https://docs.influxdata.com/"
|
||||||
languageCode = "en-us"
|
languageCode = "en-us"
|
||||||
title = "InfluxDB Documentation"
|
title = "InfluxDB Documentation"
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ title: Installation options (⏰ Please Read!)
|
||||||
aliases:
|
aliases:
|
||||||
- /enterprise_influxdb/v1.5/introduction/meta_node_installation/
|
- /enterprise_influxdb/v1.5/introduction/meta_node_installation/
|
||||||
- /enterprise_influxdb/v1.5/introduction/data_node_installation/
|
- /enterprise_influxdb/v1.5/introduction/data_node_installation/
|
||||||
- /{{< latest "chronograf" >}}/introduction/installation
|
|
||||||
- /enterprise/v1.5/introduction/installation_guidelines/
|
- /enterprise/v1.5/introduction/installation_guidelines/
|
||||||
menu:
|
menu:
|
||||||
enterprise_influxdb_1_5:
|
enterprise_influxdb_1_5:
|
||||||
|
|
|
@ -3,7 +3,6 @@ title: Installation options (⏰ Please Read!)
|
||||||
aliases:
|
aliases:
|
||||||
- /enterprise_influxdb/v1.6/introduction/meta_node_installation/
|
- /enterprise_influxdb/v1.6/introduction/meta_node_installation/
|
||||||
- /enterprise_influxdb/v1.6/introduction/data_node_installation/
|
- /enterprise_influxdb/v1.6/introduction/data_node_installation/
|
||||||
- /{{< latest "chronograf" >}}/introduction/installation
|
|
||||||
- /enterprise/v1.6/introduction/installation_guidelines/
|
- /enterprise/v1.6/introduction/installation_guidelines/
|
||||||
menu:
|
menu:
|
||||||
enterprise_influxdb_1_6:
|
enterprise_influxdb_1_6:
|
||||||
|
|
|
@ -3,7 +3,6 @@ title: Installation requirements
|
||||||
aliases:
|
aliases:
|
||||||
- /enterprise_influxdb/v1.7/introduction/meta_node_installation/
|
- /enterprise_influxdb/v1.7/introduction/meta_node_installation/
|
||||||
- /enterprise_influxdb/v1.7/introduction/data_node_installation/
|
- /enterprise_influxdb/v1.7/introduction/data_node_installation/
|
||||||
- /{{< latest "chronograf" >}}/introduction/installation
|
|
||||||
- /enterprise/v1.7/introduction/installation_guidelines/
|
- /enterprise/v1.7/introduction/installation_guidelines/
|
||||||
menu:
|
menu:
|
||||||
enterprise_influxdb_1_7:
|
enterprise_influxdb_1_7:
|
||||||
|
|
|
@ -4,7 +4,6 @@ description: Requirements for installing and deploying InfluxDB Enterprise.
|
||||||
aliases:
|
aliases:
|
||||||
- /enterprise_influxdb/v1.8/introduction/meta_node_installation/
|
- /enterprise_influxdb/v1.8/introduction/meta_node_installation/
|
||||||
- /enterprise_influxdb/v1.8/introduction/data_node_installation/
|
- /enterprise_influxdb/v1.8/introduction/data_node_installation/
|
||||||
- /{{< latest "chronograf" >}}/introduction/installation
|
|
||||||
- /enterprise/v1.8/introduction/installation_guidelines/
|
- /enterprise/v1.8/introduction/installation_guidelines/
|
||||||
menu:
|
menu:
|
||||||
enterprise_influxdb_1_8:
|
enterprise_influxdb_1_8:
|
||||||
|
|
|
@ -4,7 +4,7 @@ Use the following command to deploy a CloudFormation stack using the template in
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
aws cloudformation deploy \
|
aws cloudformation deploy \
|
||||||
--template-file docs-website.yml \
|
--template-file deploy/docs-website.yml \
|
||||||
--stack-name="${STACK_NAME}" \
|
--stack-name="${STACK_NAME}" \
|
||||||
--capabilities CAPABILITY_IAM \
|
--capabilities CAPABILITY_IAM \
|
||||||
--no-execute-changeset \
|
--no-execute-changeset \
|
||||||
|
|
|
@ -33,7 +33,7 @@ Outputs:
|
||||||
|
|
||||||
DocsProdBucketArn:
|
DocsProdBucketArn:
|
||||||
Description: The ARN of the S3 bucket hosting the static content.
|
Description: The ARN of the S3 bucket hosting the static content.
|
||||||
Value: !GetAtt DocsV2Bucket.Arn
|
Value: !GetAtt DocsBucket.Arn
|
||||||
|
|
||||||
DocsCircleCIDeployAccessKeyId:
|
DocsCircleCIDeployAccessKeyId:
|
||||||
Description: The access key ID for CircleCI deployment to S3.
|
Description: The access key ID for CircleCI deployment to S3.
|
||||||
|
@ -49,21 +49,21 @@ Resources:
|
||||||
|
|
||||||
DocsCloudFrontDistribution:
|
DocsCloudFrontDistribution:
|
||||||
Type: AWS::CloudFront::Distribution
|
Type: AWS::CloudFront::Distribution
|
||||||
Description: The CDN for both V1 and V2 docs.
|
|
||||||
Properties:
|
Properties:
|
||||||
DistributionConfig:
|
DistributionConfig:
|
||||||
Aliases:
|
Aliases:
|
||||||
- !Ref DomainName
|
- !Ref DomainName
|
||||||
DefaultCacheBehavior:
|
DefaultCacheBehavior:
|
||||||
|
TargetOriginId: !Ref DocsBucket
|
||||||
|
ViewerProtocolPolicy: redirect-to-https
|
||||||
|
DefaultTTL: 2592000
|
||||||
Compress: true
|
Compress: true
|
||||||
ForwardedValues:
|
ForwardedValues:
|
||||||
QueryString: false
|
QueryString: false
|
||||||
TargetOriginId: !Ref DocsV2Bucket
|
|
||||||
ViewerProtocolPolicy: redirect-to-https
|
|
||||||
LambdaFunctionAssociations:
|
LambdaFunctionAssociations:
|
||||||
- EventType: origin-request
|
- EventType: origin-request
|
||||||
LambdaFunctionARN: !Ref DocsOriginRequestRewriteLambdaVersion
|
LambdaFunctionARN: !Ref DocsOriginRequestRewriteLambdaVersion
|
||||||
DefaultRootObject: index.html
|
DefaultRootObject: '/'
|
||||||
CustomErrorResponses:
|
CustomErrorResponses:
|
||||||
- ErrorCachingMinTTL: 300
|
- ErrorCachingMinTTL: 300
|
||||||
ErrorCode: 403
|
ErrorCode: 403
|
||||||
|
@ -72,15 +72,8 @@ Resources:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
HttpVersion: http2
|
HttpVersion: http2
|
||||||
Origins:
|
Origins:
|
||||||
- DomainName:
|
- Id: !Ref DocsBucket
|
||||||
!Sub "${DocsV2Bucket}.s3.amazonaws.com"
|
DomainName: !Join [ "", [ !Ref DocsBucket, ".s3.amazonaws.com" ] ]
|
||||||
Id: !Ref DocsV2Bucket
|
|
||||||
S3OriginConfig:
|
|
||||||
OriginAccessIdentity:
|
|
||||||
!Sub "origin-access-identity/cloudfront/${DocsCloudFrontOriginAccessIdentity}"
|
|
||||||
- DomainName:
|
|
||||||
!Sub "${DocsV1Bucket}.s3.amazonaws.com"
|
|
||||||
Id: !Ref DocsV1Bucket
|
|
||||||
S3OriginConfig:
|
S3OriginConfig:
|
||||||
OriginAccessIdentity:
|
OriginAccessIdentity:
|
||||||
!Sub "origin-access-identity/cloudfront/${DocsCloudFrontOriginAccessIdentity}"
|
!Sub "origin-access-identity/cloudfront/${DocsCloudFrontOriginAccessIdentity}"
|
||||||
|
@ -99,7 +92,7 @@ Resources:
|
||||||
CloudFrontOriginAccessIdentityConfig:
|
CloudFrontOriginAccessIdentityConfig:
|
||||||
Comment: !Sub 'CloudFront Origin Access Identity for ${DomainName}'
|
Comment: !Sub 'CloudFront Origin Access Identity for ${DomainName}'
|
||||||
|
|
||||||
DocsV2Bucket:
|
DocsBucket:
|
||||||
Type: AWS::S3::Bucket
|
Type: AWS::S3::Bucket
|
||||||
Properties:
|
Properties:
|
||||||
BucketEncryption:
|
BucketEncryption:
|
||||||
|
@ -111,42 +104,17 @@ Resources:
|
||||||
- Key: Domain
|
- Key: Domain
|
||||||
Value: !Ref DomainName
|
Value: !Ref DomainName
|
||||||
|
|
||||||
DocsV2BucketPolicy:
|
DocsBucketPolicy:
|
||||||
Type: AWS::S3::BucketPolicy
|
Type: AWS::S3::BucketPolicy
|
||||||
Properties:
|
Properties:
|
||||||
Bucket: !Ref DocsV2Bucket
|
Bucket: !Ref DocsBucket
|
||||||
PolicyDocument:
|
PolicyDocument:
|
||||||
Statement:
|
Statement:
|
||||||
-
|
-
|
||||||
Effect: Allow
|
Effect: Allow
|
||||||
Action:
|
Action:
|
||||||
- s3:GetObject
|
- s3:GetObject
|
||||||
Resource: !Sub "arn:aws:s3:::${DocsV2Bucket}/*"
|
Resource: !Sub "arn:aws:s3:::${DocsBucket}/*"
|
||||||
Principal:
|
|
||||||
CanonicalUser: !GetAtt DocsCloudFrontOriginAccessIdentity.S3CanonicalUserId
|
|
||||||
|
|
||||||
DocsV1Bucket:
|
|
||||||
Type: AWS::S3::Bucket
|
|
||||||
Properties:
|
|
||||||
BucketEncryption:
|
|
||||||
ServerSideEncryptionConfiguration:
|
|
||||||
-
|
|
||||||
ServerSideEncryptionByDefault:
|
|
||||||
SSEAlgorithm: AES256
|
|
||||||
Tags:
|
|
||||||
- Key: Domain
|
|
||||||
Value: !Ref DomainName
|
|
||||||
|
|
||||||
DocsV1BucketPolicy:
|
|
||||||
Type: AWS::S3::BucketPolicy
|
|
||||||
Properties:
|
|
||||||
Bucket: !Ref DocsV1Bucket
|
|
||||||
PolicyDocument:
|
|
||||||
Statement:
|
|
||||||
- Effect: Allow
|
|
||||||
Action:
|
|
||||||
- s3:GetObject
|
|
||||||
Resource: !Sub "arn:aws:s3:::${DocsV1Bucket}/*"
|
|
||||||
Principal:
|
Principal:
|
||||||
CanonicalUser: !GetAtt DocsCloudFrontOriginAccessIdentity.S3CanonicalUserId
|
CanonicalUser: !GetAtt DocsCloudFrontOriginAccessIdentity.S3CanonicalUserId
|
||||||
|
|
||||||
|
@ -158,71 +126,159 @@ Resources:
|
||||||
ZipFile: |
|
ZipFile: |
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const latestVersions = {
|
||||||
|
'influxdb': 'v1.8',
|
||||||
|
'influxdbv2': 'v2.0',
|
||||||
|
'telegraf': 'v1.15',
|
||||||
|
'chronograf': 'v1.8',
|
||||||
|
'kapacitor': 'v1.5',
|
||||||
|
'enterprise': 'v1.8',
|
||||||
|
};
|
||||||
|
|
||||||
|
const archiveDomain = 'http://archive.docs.influxdata.com'
|
||||||
|
|
||||||
exports.handler = (event, context, callback) => {
|
exports.handler = (event, context, callback) => {
|
||||||
|
|
||||||
|
function temporaryRedirect(condition, newUri) {
|
||||||
|
if (condition) {
|
||||||
|
return callback(null, {
|
||||||
|
status: '302',
|
||||||
|
statusDescription: 'Found',
|
||||||
|
headers: {
|
||||||
|
location: [{
|
||||||
|
key: 'Location',
|
||||||
|
value: newUri,
|
||||||
|
}],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function permanantRedirect(condition, newUri) {
|
||||||
|
if (condition) {
|
||||||
|
return callback(null, {
|
||||||
|
status: '301',
|
||||||
|
statusDescription: 'Moved Permanently',
|
||||||
|
headers: {
|
||||||
|
'location': [{
|
||||||
|
key: 'Location',
|
||||||
|
value: newUri,
|
||||||
|
}],
|
||||||
|
'cache-control': [{
|
||||||
|
key: 'Cache-Control',
|
||||||
|
value: "max-age=3600"
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const { request } = event.Records[0].cf;
|
const { request } = event.Records[0].cf;
|
||||||
const { uri, headers, origin } = request;
|
const parsedPath = path.parse(request.uri);
|
||||||
const extension = uri.substr(uri.lastIndexOf('.') + 1);
|
|
||||||
|
|
||||||
const validExtensions = ['.html', '.css', '.js', '.xml', '.png', '.jpg', '.svg', '.json', '.csv', '.rb', '.otf', '.eot', '.ttf', '.woff'];
|
|
||||||
const indexPath = 'index.html';
|
const indexPath = 'index.html';
|
||||||
const defaultPath = '/v2.0/'
|
const validExtensions = {
|
||||||
|
'.html': true,
|
||||||
|
'.css': true,
|
||||||
|
'.js': true,
|
||||||
|
'.xml': true,
|
||||||
|
'.png': true,
|
||||||
|
'.gif': true,
|
||||||
|
'.jpg': true,
|
||||||
|
'.ico': true,
|
||||||
|
'.svg': true,
|
||||||
|
'.csv': true,
|
||||||
|
'.txt': true,
|
||||||
|
'.lp': true,
|
||||||
|
'.json': true,
|
||||||
|
'.rb': true,
|
||||||
|
'.eot': true,
|
||||||
|
'.ttf': true,
|
||||||
|
'.woff': true,
|
||||||
|
'.otf': true,
|
||||||
|
};
|
||||||
|
|
||||||
// If path ends with '/', then append 'index.html', otherwise redirect to a
|
// Remove index.html from path
|
||||||
// path with '/' or ignore if the path ends with a valid file extension.
|
temporaryRedirect(request.uri.endsWith('index.html'), request.uri.substr(0, request.uri.length - indexPath.length));
|
||||||
if ((uri == '/') || (uri.length < defaultPath.length)) {
|
|
||||||
callback(null, {
|
// If file has a valid extension, return the request unchanged
|
||||||
status: '302',
|
if (validExtensions[parsedPath.ext]) {
|
||||||
statusDescription: 'Found',
|
callback(null, request);
|
||||||
headers: {
|
|
||||||
location: [{
|
|
||||||
key: 'Location',
|
|
||||||
value: defaultPath,
|
|
||||||
}],
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (uri.endsWith('/')) {
|
|
||||||
request.uri = uri + indexPath;
|
|
||||||
} else if (uri.endsWith('/index.html')) {
|
|
||||||
callback(null, {
|
|
||||||
status: '302',
|
|
||||||
statusDescription: 'Found',
|
|
||||||
headers: {
|
|
||||||
location: [{
|
|
||||||
key: 'Location',
|
|
||||||
value: uri.substr(0, uri.length - indexPath.length),
|
|
||||||
}],
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (validExtensions.filter((ext) => uri.endsWith(ext)) == 0) {
|
|
||||||
callback(null, {
|
|
||||||
status: '302',
|
|
||||||
statusDescription: 'Found',
|
|
||||||
headers: {
|
|
||||||
location: [{
|
|
||||||
key: 'Location',
|
|
||||||
value: uri + '/',
|
|
||||||
}],
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const pathsV1 = ['/influxdb', '/telegraf', '/chronograf', '/kapacitor', '/enterprise_influxdb', '/enterprise_kapacitor'];
|
////////////////////// START PRODUCT-SPECIFIC REDIRECTS //////////////////////
|
||||||
const originV1 = process.env.ORIGIN_V1;
|
|
||||||
|
|
||||||
// Send to v1 origin if start of path matches
|
//////////////////////////// v2 subdomain redirect ///////////////////////////
|
||||||
if (pathsV1.filter((path) => uri.startsWith(path)) > 0) {
|
temporaryRedirect(request.headers.host[0].value === 'v2.docs.influxdata.com', `https://docs.influxdata.com${request.uri}`);
|
||||||
headers['host'] = [{key: 'host', value: originV1}];
|
|
||||||
origin.s3.domainName = originV1;
|
////////////////////////// Latest version redirects //////////////////////////
|
||||||
|
temporaryRedirect(/\/influxdb\/latest/.test(request.uri), request.uri.replace(/\/latest/, `/${latestVersions['influxdb']}`));
|
||||||
|
temporaryRedirect(/\/telegraf\/latest/.test(request.uri), request.uri.replace(/\/latest/, `/${latestVersions['telegraf']}`));
|
||||||
|
temporaryRedirect(/\/chronograf\/latest/.test(request.uri), request.uri.replace(/\/latest/, `/${latestVersions['chronograf']}`));
|
||||||
|
temporaryRedirect(/\/kapacitor\/latest/.test(request.uri), request.uri.replace(/\/latest/, `/${latestVersions['kapacitor']}`));
|
||||||
|
temporaryRedirect(/\/enterprise_influxdb\/latest/.test(request.uri), request.uri.replace(/\/latest/, `/${latestVersions['enterprise']}`));
|
||||||
|
|
||||||
|
////////////////////////// Versionless URL redirects /////////////////////////
|
||||||
|
temporaryRedirect(request.uri === '/influxdb/', `/influxdb/${latestVersions['influxdb']}/`);
|
||||||
|
temporaryRedirect(request.uri === '/telegraf/', `/telegraf/${latestVersions['telegraf']}/`);
|
||||||
|
temporaryRedirect(request.uri === '/chronograf/', `/chronograf/${latestVersions['chronograf']}/`);
|
||||||
|
temporaryRedirect(request.uri === '/kapacitor/', `/kapacitor/${latestVersions['kapacitor']}/`);
|
||||||
|
temporaryRedirect(request.uri === '/enterprise_influxdb/', `/enterprise_influxdb/${latestVersions['enterprise']}/`);
|
||||||
|
|
||||||
|
/////////////////////////////// Flux redirects ///////////////////////////////
|
||||||
|
// Redirect flux guides and introduction based on latest InfluxDB version
|
||||||
|
if (/v2/.test(latestVersions['influxdb'])) {
|
||||||
|
temporaryRedirect(/\/flux\/v0\.[0-9]{1,2}\/guides\//.test(request.uri), request.uri.replace(/\/flux\/v0\.[0-9]{1,2}\/guides\//, `/influxdb/${latestVersions['influxdb']}/query-data/flux/`));
|
||||||
|
temporaryRedirect(/\/flux\/v0\.[0-9]{1,2}\/guides\//.test(request.uri), request.uri.replace(/\/flux\/v0\.[0-9]{1,2}\/introduction\//, `/influxdb/${latestVersions['influxdb']}/query-data/get-started/`));
|
||||||
|
} else {
|
||||||
|
temporaryRedirect(/\/flux\/v0\.[0-9]{1,2}\/guides\//.test(request.uri), request.uri.replace(/\/flux\/v0\.[0-9]{1,2}\/guides\//, `/influxdb/${latestVersions['influxdb']}/flux/guides/`));
|
||||||
|
temporaryRedirect(/\/flux\/v0\.[0-9]{1,2}\/guides\//.test(request.uri), request.uri.replace(/\/flux\/v0\.[0-9]{1,2}\/introduction\//, `/influxdb/${latestVersions['influxdb']}/flux/introduction/`));
|
||||||
|
}
|
||||||
|
// Redirect Flux stdlib and language sections to v2 Flux docs
|
||||||
|
temporaryRedirect(/\/flux\/v0\.[0-9]{1,2}\/(?:functions|stdlib|language)\//.test(request.uri), request.uri.replace(/\/flux\/v0\.[0-9]{1,2}\//, `/influxdb/${latestVersions['influxdbv2']}/reference/flux/`));
|
||||||
|
|
||||||
|
// Redirect versionless and base version to v2 Flux docs
|
||||||
|
temporaryRedirect(/^\/flux\/(?:v0\.[0-9]{1,2}\/|)$/.test(request.uri), `/influxdb/${latestVersions['influxdbv2']}/reference/flux/`);
|
||||||
|
|
||||||
|
////////////////////////////// v2 path redirect //////////////////////////////
|
||||||
|
temporaryRedirect(/^\/v2\.0\//.test(request.uri), request.uri.replace(/^\/v2\.0\//, `/influxdb/${latestVersions['influxdbv2']}/`));
|
||||||
|
|
||||||
|
////////////////////////// Archive version redirects /////////////////////////
|
||||||
|
temporaryRedirect(/\/influxdb\/(?:v0\.[0-9]{1,2}|v1\.[0-2])\//.test(request.uri), `${archiveDomain}${request.uri}`);
|
||||||
|
temporaryRedirect(/\/telegraf\/(?:v0\.[0-9]{1,2}|v1\.[0-8])\//.test(request.uri), `${archiveDomain}${request.uri}`);
|
||||||
|
temporaryRedirect(/\/chronograf\/(?:v0\.[0-9]{1,2}|v1\.[0-5])\//.test(request.uri), `${archiveDomain}${request.uri}`);
|
||||||
|
temporaryRedirect(/\/kapacitor\/(?:v0\.[0-9]{1,2}|v1\.[0-3])\//.test(request.uri), `${archiveDomain}${request.uri}`);
|
||||||
|
temporaryRedirect(/\/enterprise_influxdb\/v1\.[0-3]\//.test(request.uri), `${archiveDomain}${request.uri}`);
|
||||||
|
temporaryRedirect(/\/enterprise_kapacitor\//.test(request.uri), `${archiveDomain}${request.uri}`);
|
||||||
|
|
||||||
|
/////////////////////// END PRODUCT-SPECIFIC REDIRECTS ///////////////////////
|
||||||
|
|
||||||
|
// Redirect to the a trailing slash
|
||||||
|
temporaryRedirect(!request.uri.endsWith('/'), request.uri + '/');
|
||||||
|
|
||||||
|
// Use index.html if the path doesn't have an extension
|
||||||
|
// or if the version number is parsed as an extension.
|
||||||
|
let newUri;
|
||||||
|
|
||||||
|
if (parsedPath.ext === '' || /\.\d*/.test(parsedPath.ext)) {
|
||||||
|
newUri = path.join(parsedPath.dir, parsedPath.base, indexPath);
|
||||||
|
} else {
|
||||||
|
newUri = request.uri;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If nothing matches, return request unchanged
|
// Replace the received URI with the URI that includes the index page
|
||||||
|
request.uri = newUri;
|
||||||
|
|
||||||
|
// Return to CloudFront
|
||||||
|
// request.uri = request.uri + indexPath;
|
||||||
callback(null, request);
|
callback(null, request);
|
||||||
};
|
};
|
||||||
|
|
||||||
Handler: index.handler
|
Handler: index.handler
|
||||||
MemorySize: 128
|
MemorySize: 128
|
||||||
Role: !Sub ${DocsOriginRequestRewriteLambdaRole.Arn}
|
Role: !Sub ${DocsOriginRequestRewriteLambdaRole.Arn}
|
||||||
Runtime: nodejs8.10
|
Runtime: nodejs12.x
|
||||||
Tags:
|
Tags:
|
||||||
- Key: Domain
|
- Key: Domain
|
||||||
Value: !Ref DomainName
|
Value: !Ref DomainName
|
||||||
|
@ -261,16 +317,14 @@ Resources:
|
||||||
- s3:ListBucket
|
- s3:ListBucket
|
||||||
- s3:GetBucketLocation
|
- s3:GetBucketLocation
|
||||||
Resource:
|
Resource:
|
||||||
- !Sub "arn:aws:s3:::${DocsV2Bucket}"
|
- !Sub "arn:aws:s3:::${DocsBucket}"
|
||||||
- !Sub "arn:aws:s3:::${DocsV1Bucket}"
|
|
||||||
- Effect: Allow
|
- Effect: Allow
|
||||||
Action:
|
Action:
|
||||||
- s3:PutObject
|
- s3:PutObject
|
||||||
- s3:PutObjectAcl
|
- s3:PutObjectAcl
|
||||||
- s3:DeleteObject
|
- s3:DeleteObject
|
||||||
Resource:
|
Resource:
|
||||||
- !Sub "arn:aws:s3:::${DocsV2Bucket}/*"
|
- !Sub "arn:aws:s3:::${DocsBucket}/*"
|
||||||
- !Sub "arn:aws:s3:::${DocsV1Bucket}/*"
|
|
||||||
- Effect: Allow
|
- Effect: Allow
|
||||||
Action:
|
Action:
|
||||||
- cloudfront:GetDistribution
|
- cloudfront:GetDistribution
|
||||||
|
|
|
@ -0,0 +1,150 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const latestVersions = {
|
||||||
|
'influxdb': 'v1.8',
|
||||||
|
'influxdbv2': 'v2.0',
|
||||||
|
'telegraf': 'v1.15',
|
||||||
|
'chronograf': 'v1.8',
|
||||||
|
'kapacitor': 'v1.5',
|
||||||
|
'enterprise': 'v1.8',
|
||||||
|
};
|
||||||
|
|
||||||
|
const archiveDomain = 'http://archive.docs.influxdata.com'
|
||||||
|
|
||||||
|
exports.handler = (event, context, callback) => {
|
||||||
|
|
||||||
|
function temporaryRedirect(condition, newUri) {
|
||||||
|
if (condition) {
|
||||||
|
return callback(null, {
|
||||||
|
status: '302',
|
||||||
|
statusDescription: 'Found',
|
||||||
|
headers: {
|
||||||
|
location: [{
|
||||||
|
key: 'Location',
|
||||||
|
value: newUri,
|
||||||
|
}],
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function permanantRedirect(condition, newUri) {
|
||||||
|
if (condition) {
|
||||||
|
return callback(null, {
|
||||||
|
status: '301',
|
||||||
|
statusDescription: 'Moved Permanently',
|
||||||
|
headers: {
|
||||||
|
'location': [{
|
||||||
|
key: 'Location',
|
||||||
|
value: newUri,
|
||||||
|
}],
|
||||||
|
'cache-control': [{
|
||||||
|
key: 'Cache-Control',
|
||||||
|
value: "max-age=3600"
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const { request } = event.Records[0].cf;
|
||||||
|
const parsedPath = path.parse(request.uri);
|
||||||
|
const indexPath = 'index.html';
|
||||||
|
const validExtensions = {
|
||||||
|
'.html': true,
|
||||||
|
'.css': true,
|
||||||
|
'.js': true,
|
||||||
|
'.xml': true,
|
||||||
|
'.png': true,
|
||||||
|
'.gif': true,
|
||||||
|
'.jpg': true,
|
||||||
|
'.ico': true,
|
||||||
|
'.svg': true,
|
||||||
|
'.csv': true,
|
||||||
|
'.txt': true,
|
||||||
|
'.lp': true,
|
||||||
|
'.json': true,
|
||||||
|
'.rb': true,
|
||||||
|
'.eot': true,
|
||||||
|
'.ttf': true,
|
||||||
|
'.woff': true,
|
||||||
|
'.otf': true,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Remove index.html from path
|
||||||
|
temporaryRedirect(request.uri.endsWith('index.html'), request.uri.substr(0, request.uri.length - indexPath.length));
|
||||||
|
|
||||||
|
// If file has a valid extension, return the request unchanged
|
||||||
|
if (validExtensions[parsedPath.ext]) {
|
||||||
|
callback(null, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////// START PRODUCT-SPECIFIC REDIRECTS //////////////////////
|
||||||
|
|
||||||
|
//////////////////////////// v2 subdomain redirect ///////////////////////////
|
||||||
|
temporaryRedirect(request.headers.host[0].value === 'v2.docs.influxdata.com', `https://docs.influxdata.com${request.uri}`);
|
||||||
|
|
||||||
|
////////////////////////// Latest version redirects //////////////////////////
|
||||||
|
temporaryRedirect(/\/influxdb\/latest/.test(request.uri), request.uri.replace(/\/latest/, `/${latestVersions['influxdb']}`));
|
||||||
|
temporaryRedirect(/\/telegraf\/latest/.test(request.uri), request.uri.replace(/\/latest/, `/${latestVersions['telegraf']}`));
|
||||||
|
temporaryRedirect(/\/chronograf\/latest/.test(request.uri), request.uri.replace(/\/latest/, `/${latestVersions['chronograf']}`));
|
||||||
|
temporaryRedirect(/\/kapacitor\/latest/.test(request.uri), request.uri.replace(/\/latest/, `/${latestVersions['kapacitor']}`));
|
||||||
|
temporaryRedirect(/\/enterprise_influxdb\/latest/.test(request.uri), request.uri.replace(/\/latest/, `/${latestVersions['enterprise']}`));
|
||||||
|
|
||||||
|
////////////////////////// Versionless URL redirects /////////////////////////
|
||||||
|
temporaryRedirect(request.uri === '/influxdb/', `/influxdb/${latestVersions['influxdb']}/`);
|
||||||
|
temporaryRedirect(request.uri === '/telegraf/', `/telegraf/${latestVersions['telegraf']}/`);
|
||||||
|
temporaryRedirect(request.uri === '/chronograf/', `/chronograf/${latestVersions['chronograf']}/`);
|
||||||
|
temporaryRedirect(request.uri === '/kapacitor/', `/kapacitor/${latestVersions['kapacitor']}/`);
|
||||||
|
temporaryRedirect(request.uri === '/enterprise_influxdb/', `/enterprise_influxdb/${latestVersions['enterprise']}/`);
|
||||||
|
|
||||||
|
/////////////////////////////// Flux redirects ///////////////////////////////
|
||||||
|
// Redirect flux guides and introduction based on latest InfluxDB version
|
||||||
|
if (/v2/.test(latestVersions['influxdb'])) {
|
||||||
|
temporaryRedirect(/\/flux\/v0\.[0-9]{1,2}\/guides\//.test(request.uri), request.uri.replace(/\/flux\/v0\.[0-9]{1,2}\/guides\//, `/influxdb/${latestVersions['influxdb']}/query-data/flux/`));
|
||||||
|
temporaryRedirect(/\/flux\/v0\.[0-9]{1,2}\/guides\//.test(request.uri), request.uri.replace(/\/flux\/v0\.[0-9]{1,2}\/introduction\//, `/influxdb/${latestVersions['influxdb']}/query-data/get-started/`));
|
||||||
|
} else {
|
||||||
|
temporaryRedirect(/\/flux\/v0\.[0-9]{1,2}\/guides\//.test(request.uri), request.uri.replace(/\/flux\/v0\.[0-9]{1,2}\/guides\//, `/influxdb/${latestVersions['influxdb']}/flux/guides/`));
|
||||||
|
temporaryRedirect(/\/flux\/v0\.[0-9]{1,2}\/guides\//.test(request.uri), request.uri.replace(/\/flux\/v0\.[0-9]{1,2}\/introduction\//, `/influxdb/${latestVersions['influxdb']}/flux/introduction/`));
|
||||||
|
}
|
||||||
|
// Redirect Flux stdlib and language sections to v2 Flux docs
|
||||||
|
temporaryRedirect(/\/flux\/v0\.[0-9]{1,2}\/(?:functions|stdlib|language)\//.test(request.uri), request.uri.replace(/\/flux\/v0\.[0-9]{1,2}\//, `/influxdb/${latestVersions['influxdbv2']}/reference/flux/`));
|
||||||
|
|
||||||
|
// Redirect versionless and base version to v2 Flux docs
|
||||||
|
temporaryRedirect(/^\/flux\/(?:v0\.[0-9]{1,2}\/|)$/.test(request.uri), `/influxdb/${latestVersions['influxdbv2']}/reference/flux/`);
|
||||||
|
|
||||||
|
////////////////////////////// v2 path redirect //////////////////////////////
|
||||||
|
temporaryRedirect(/^\/v2\.0\//.test(request.uri), request.uri.replace(/^\/v2\.0\//, `/influxdb/${latestVersions['influxdbv2']}/`));
|
||||||
|
|
||||||
|
////////////////////////// Archive version redirects /////////////////////////
|
||||||
|
temporaryRedirect(/\/influxdb\/(?:v0\.[0-9]{1,2}|v1\.[0-2])\//.test(request.uri), `${archiveDomain}${request.uri}`);
|
||||||
|
temporaryRedirect(/\/telegraf\/(?:v0\.[0-9]{1,2}|v1\.[0-8])\//.test(request.uri), `${archiveDomain}${request.uri}`);
|
||||||
|
temporaryRedirect(/\/chronograf\/(?:v0\.[0-9]{1,2}|v1\.[0-5])\//.test(request.uri), `${archiveDomain}${request.uri}`);
|
||||||
|
temporaryRedirect(/\/kapacitor\/(?:v0\.[0-9]{1,2}|v1\.[0-3])\//.test(request.uri), `${archiveDomain}${request.uri}`);
|
||||||
|
temporaryRedirect(/\/enterprise_influxdb\/v1\.[0-3]\//.test(request.uri), `${archiveDomain}${request.uri}`);
|
||||||
|
temporaryRedirect(/\/enterprise_kapacitor\//.test(request.uri), `${archiveDomain}${request.uri}`);
|
||||||
|
|
||||||
|
/////////////////////// END PRODUCT-SPECIFIC REDIRECTS ///////////////////////
|
||||||
|
|
||||||
|
// Redirect to the a trailing slash
|
||||||
|
temporaryRedirect(!request.uri.endsWith('/'), request.uri + '/');
|
||||||
|
|
||||||
|
// Use index.html if the path doesn't have an extension
|
||||||
|
// or if the version number is parsed as an extension.
|
||||||
|
let newUri;
|
||||||
|
|
||||||
|
if (parsedPath.ext === '' || /\.\d*/.test(parsedPath.ext)) {
|
||||||
|
newUri = path.join(parsedPath.dir, parsedPath.base, indexPath);
|
||||||
|
} else {
|
||||||
|
newUri = request.uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace the received URI with the URI that includes the index page
|
||||||
|
request.uri = newUri;
|
||||||
|
|
||||||
|
// Return to CloudFront
|
||||||
|
// request.uri = request.uri + indexPath;
|
||||||
|
callback(null, request);
|
||||||
|
};
|
|
@ -0,0 +1,23 @@
|
||||||
|
###############################################################################
|
||||||
|
### AWS Cloudformation Template
|
||||||
|
### InfluxData Documentation Website Hosting and Deployment
|
||||||
|
###############################################################################
|
||||||
|
AWSTemplateFormatVersion: 2010-09-09
|
||||||
|
###############################################################################
|
||||||
|
Resources:
|
||||||
|
###############################################################################
|
||||||
|
DocsOriginRequestRewriteLambdaRole:
|
||||||
|
Type: AWS::IAM::Role
|
||||||
|
Properties:
|
||||||
|
RoleName: test1-DocsOriginRequestRewriteLambdaRole-10RT8O6PQO2ZE
|
||||||
|
AssumeRolePolicyDocument:
|
||||||
|
Version: 2012-10-17
|
||||||
|
Statement:
|
||||||
|
- Effect: Allow
|
||||||
|
Action: sts:AssumeRole
|
||||||
|
Principal:
|
||||||
|
Service:
|
||||||
|
- edgelambda.amazonaws.com
|
||||||
|
- lambda.amazonaws.com
|
||||||
|
ManagedPolicyArns:
|
||||||
|
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
|
|
@ -13,7 +13,7 @@
|
||||||
<ul class="item-list">
|
<ul class="item-list">
|
||||||
{{ range sort .Site.Data.products "list_order" "desc" }}
|
{{ range sort .Site.Data.products "list_order" "desc" }}
|
||||||
<li>
|
<li>
|
||||||
<a href='/{{ .namespace }}/{{ cond (isset . "latest_override") .latest_override .latest }}' {{ if eq .namespace $product }}class="active"{{ end }}>{{ cond (ne .altname nil) .altname .name }}</a>
|
<a href='/{{ .namespace }}/{{ cond (isset . "latest_override") .latest_override .latest }}/' {{ if eq .namespace $product }}class="active"{{ end }}>{{ cond (ne .altname nil) .altname .name }}</a>
|
||||||
</li>
|
</li>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<li><a href="https://github.com/influxdata/docs.influxdata.com" class="legacy" target="_blank">older</a></li>
|
<li><a href="https://github.com/influxdata/docs.influxdata.com" class="legacy" target="_blank">older</a></li>
|
||||||
{{ range (index .Site.Data.products $product).versions }}
|
{{ range (index .Site.Data.products $product).versions }}
|
||||||
<li>
|
<li>
|
||||||
<a href="/{{ $product }}/{{ . }}" {{ if eq . $currentVersion }}class="active"{{ end }}>{{ . }}</a>
|
<a href="/{{ $product }}/{{ . }}/" {{ if eq . $currentVersion }}class="active"{{ end }}>{{ . }}</a>
|
||||||
</li>
|
</li>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
|
||||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
||||||
viewBox="0 0 300 100" style="enable-background:new 0 0 300 100;" xml:space="preserve">
|
|
||||||
<style type="text/css">
|
|
||||||
.st0{fill:url(#SVGID_1_);}
|
|
||||||
.st1{fill:#FFFFFF;}
|
|
||||||
</style>
|
|
||||||
<g>
|
|
||||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="-9.105" y1="129.0257" x2="297.1224" y2="-23.0741">
|
|
||||||
<stop offset="0" style="stop-color:#9394FF"/>
|
|
||||||
<stop offset="0.1837" style="stop-color:#8F95FF"/>
|
|
||||||
<stop offset="0.3732" style="stop-color:#8298FE"/>
|
|
||||||
<stop offset="0.5655" style="stop-color:#6E9CFC"/>
|
|
||||||
<stop offset="0.7596" style="stop-color:#51A3FA"/>
|
|
||||||
<stop offset="0.9535" style="stop-color:#2CABF7"/>
|
|
||||||
<stop offset="1" style="stop-color:#22ADF6"/>
|
|
||||||
</linearGradient>
|
|
||||||
<rect x="-1" y="-1" class="st0" width="302" height="102"/>
|
|
||||||
</g>
|
|
||||||
<g>
|
|
||||||
<path class="st1" d="M94.8,43.4H96l-1.6,9.3h-1.2L94.8,43.4z"/>
|
|
||||||
<path class="st1" d="M105.8,47.5c0-0.1,0-0.2,0-0.2c0-0.3-0.1-0.4-0.5-0.4c-0.7,0-1.8,0.5-2.6,1l-0.8,4.8h-1.2l0.9-5.2
|
|
||||||
c0-0.1,0-0.2,0-0.2c0-0.3-0.1-0.4-0.5-0.4c-0.7,0-1.7,0.5-2.6,1l-0.8,4.8h-1.2l1.2-6.7l1-0.2l-0.1,1c0.7-0.5,2.1-1,2.9-1
|
|
||||||
c0.8,0,1.2,0.4,1.2,1c0.7-0.5,2.1-1,2.9-1c0.8,0,1.2,0.5,1.2,1.2c0,0.2,0,0.4-0.1,0.6l-0.9,5.2h-1.2L105.8,47.5z"/>
|
|
||||||
<path class="st1" d="M113.2,52.7h-0.9l0-0.8c-0.8,0.7-1.7,1-2.6,1c-1.1,0-1.4-0.6-1.4-1.4c0-0.2,0-0.3,0.1-0.5l0.5-2.7
|
|
||||||
c0.3-1.7,0.9-2.5,3.1-2.5c0.8,0,1.8,0.2,2.4,0.5L113.2,52.7z M113.1,46.9c-0.4-0.1-0.8-0.2-1.3-0.2c-1.1,0-1.6,0.3-1.8,1.7
|
|
||||||
l-0.4,2.5c0,0.2-0.1,0.3-0.1,0.5c0,0.3,0.1,0.5,0.6,0.5c0.8,0,1.6-0.5,2.4-1.2L113.1,46.9z"/>
|
|
||||||
<path class="st1" d="M120.2,53.8c-0.2,1.4-0.8,1.9-2.4,1.9c-0.9,0-2.1-0.3-2.8-0.6l0.2-0.9c0.9,0.3,1.8,0.5,2.6,0.5
|
|
||||||
c0.9,0,1.1-0.3,1.2-1l0.3-2c-0.8,0.6-1.6,0.9-2.5,0.9c-1.1,0-1.4-0.6-1.4-1.4c0-0.2,0-0.3,0.1-0.5l0.4-2.4c0.3-1.7,1-2.5,3.1-2.5
|
|
||||||
c0.7,0,1.7,0.2,2.4,0.5L120.2,53.8z M120.3,47c-0.4-0.1-0.9-0.2-1.4-0.2c-1.1,0-1.6,0.3-1.8,1.7l-0.4,2.2c0,0.2-0.1,0.3-0.1,0.5
|
|
||||||
c0,0.3,0.1,0.5,0.6,0.5c0.7,0,1.7-0.5,2.4-1.1L120.3,47z"/>
|
|
||||||
<path class="st1" d="M123.9,50.9c0,0.2,0,0.2,0,0.3c0,0.4,0.2,0.7,0.9,0.7c0.7,0,1.6-0.3,2.5-0.7l0.2,0.8c-0.9,0.5-1.8,0.8-2.9,0.8
|
|
||||||
c-1.4,0-1.9-0.6-1.9-1.6c0-0.2,0-0.4,0.1-0.6l0.4-2.3c0.3-1.7,1.1-2.6,3-2.6c1.1,0,2,0.5,2,1.5c0,1.2-0.5,1.7-2.4,2.4
|
|
||||||
c-0.8,0.3-1.1,0.3-1.7,0.5L123.9,50.9z M127.1,47.4c0-0.5-0.3-0.7-0.9-0.7c-1.1,0-1.6,0.4-1.8,1.5l-0.2,0.9
|
|
||||||
c0.4-0.1,0.6-0.2,1.3-0.4C126.6,48.4,127.1,48,127.1,47.4z"/>
|
|
||||||
<path class="st1" d="M132.3,50.7c0-0.2,0-0.4,0.1-0.7l0.7-4c0.4-2,1.4-2.7,3.6-2.7c0.7,0,1.6,0.1,2.3,0.3l-0.2,1
|
|
||||||
c-0.7-0.2-1.6-0.2-2.2-0.2c-1.5,0-2.1,0.4-2.4,1.8l-0.7,3.9c0,0.2-0.1,0.4-0.1,0.6c0,0.8,0.5,1.2,1.8,1.2c0.6,0,1.5-0.1,2.2-0.2
|
|
||||||
l0,1c-0.7,0.2-1.7,0.3-2.5,0.3C133.1,52.9,132.3,52,132.3,50.7z"/>
|
|
||||||
<path class="st1" d="M139.3,50.3l0.4-2c0.3-1.7,1.2-2.5,3.2-2.5c1.6,0,2.4,0.9,2.4,2c0,0.1,0,0.2,0,0.5l-0.4,2.1
|
|
||||||
c-0.3,1.5-1.1,2.5-3.2,2.5C139.7,52.9,139.1,51.8,139.3,50.3z M144.1,48.3c0-0.2,0-0.3,0-0.4c0-0.7-0.4-1.1-1.4-1.1
|
|
||||||
c-1.1,0-1.7,0.5-1.9,1.6l-0.4,2c-0.1,0.9,0.1,1.5,1.3,1.5c1.2,0,1.7-0.5,1.9-1.5L144.1,48.3z"/>
|
|
||||||
<path class="st1" d="M155.4,47.5c0-0.1,0-0.2,0-0.2c0-0.3-0.1-0.4-0.5-0.4c-0.7,0-1.8,0.5-2.6,1l-0.9,4.8h-1.1l0.9-5.2
|
|
||||||
c0-0.1,0-0.2,0-0.2c0-0.3-0.1-0.4-0.5-0.4c-0.7,0-1.7,0.5-2.6,1l-0.9,4.8h-1.1l1.2-6.7l1-0.2l-0.1,1c0.7-0.5,2.1-1,2.9-1
|
|
||||||
c0.8,0,1.1,0.4,1.2,1c0.7-0.5,2.1-1,2.9-1c0.9,0,1.2,0.5,1.2,1.2c0,0.2,0,0.4-0.1,0.6l-0.9,5.2h-1.1L155.4,47.5z"/>
|
|
||||||
<path class="st1" d="M159,46l1.2-0.2l-1.2,6.9h-1.1L159,46z M159.5,43.1l1.2-0.2l-0.3,1.8l-1.2,0.2L159.5,43.1z"/>
|
|
||||||
<path class="st1" d="M167.4,47c0,0.2,0,0.4-0.1,0.6l-0.9,5.2h-1.1l0.9-5.2c0-0.1,0-0.2,0-0.2c0-0.3-0.1-0.4-0.5-0.4
|
|
||||||
c-0.7,0-1.7,0.5-2.6,1l-0.9,4.8h-1.1l1.2-6.7l1-0.2l-0.1,1c0.7-0.5,2.1-1,2.9-1C167.1,45.8,167.4,46.2,167.4,47z"/>
|
|
||||||
<path class="st1" d="M173.4,53.8c-0.2,1.4-0.8,1.9-2.4,1.9c-0.9,0-2.1-0.3-2.8-0.6l0.2-0.9c0.9,0.3,1.8,0.5,2.6,0.5
|
|
||||||
c0.9,0,1.1-0.3,1.2-1l0.4-2c-0.8,0.6-1.6,0.9-2.5,0.9c-1.1,0-1.4-0.6-1.4-1.4c0-0.2,0-0.3,0.1-0.5l0.4-2.4c0.3-1.7,1-2.5,3.1-2.5
|
|
||||||
c0.7,0,1.7,0.2,2.4,0.5L173.4,53.8z M173.5,47c-0.4-0.1-0.9-0.2-1.4-0.2c-1.1,0-1.6,0.3-1.8,1.7l-0.4,2.2c0,0.2-0.1,0.3-0.1,0.5
|
|
||||||
c0,0.3,0.1,0.5,0.6,0.5c0.7,0,1.7-0.5,2.4-1.1L173.5,47z"/>
|
|
||||||
<path class="st1" d="M178.7,52.4l0.3-0.9c0.9,0.3,1.7,0.4,2.5,0.4c1.5,0,1.9-0.4,2.1-1.5c0.1-0.3,0.1-0.5,0.1-0.7
|
|
||||||
c0-0.6-0.4-0.7-1.7-1.1c-1.6-0.4-2.1-0.9-2.1-1.9c0-0.3,0-0.6,0.1-0.9c0.3-1.9,1.1-2.4,3.3-2.4c0.7,0,1.7,0.1,2.4,0.3l-0.2,1
|
|
||||||
c-0.8-0.2-1.7-0.3-2.3-0.3c-1.6,0-1.9,0.2-2.1,1.4c-0.1,0.3-0.1,0.6-0.1,0.8c0,0.6,0.4,0.8,1.6,1.1c1.7,0.5,2.2,0.9,2.2,1.8
|
|
||||||
c0,0.2,0,0.6-0.1,1c-0.3,1.7-0.8,2.5-3.4,2.5C180.6,52.9,179.5,52.7,178.7,52.4z"/>
|
|
||||||
<path class="st1" d="M186.4,50.3l0.4-2c0.3-1.7,1.2-2.5,3.2-2.5c1.6,0,2.4,0.9,2.4,2c0,0.1,0,0.2,0,0.5l-0.4,2.1
|
|
||||||
c-0.3,1.5-1.1,2.5-3.2,2.5C186.8,52.9,186.2,51.8,186.4,50.3z M191.2,48.3c0-0.2,0-0.3,0-0.4c0-0.7-0.4-1.1-1.4-1.1
|
|
||||||
c-1.1,0-1.7,0.5-1.9,1.6l-0.4,2c-0.1,0.9,0.1,1.5,1.4,1.5c1.2,0,1.7-0.5,1.9-1.5L191.2,48.3z"/>
|
|
||||||
<path class="st1" d="M193.5,50.3l0.4-2c0.3-1.7,1.2-2.5,3.2-2.5c1.6,0,2.4,0.9,2.4,2c0,0.1,0,0.2,0,0.5l-0.4,2.1
|
|
||||||
c-0.3,1.5-1.1,2.5-3.2,2.5C193.9,52.9,193.3,51.8,193.5,50.3z M198.3,48.3c0-0.2,0-0.3,0-0.4c0-0.7-0.4-1.1-1.4-1.1
|
|
||||||
c-1.1,0-1.7,0.5-1.9,1.6l-0.4,2c-0.1,0.9,0.1,1.5,1.4,1.5c1.2,0,1.7-0.5,1.9-1.5L198.3,48.3z"/>
|
|
||||||
<path class="st1" d="M206.8,47c0,0.2,0,0.4-0.1,0.6l-0.9,5.2h-1.1l0.9-5.2c0-0.1,0-0.2,0-0.2c0-0.3-0.1-0.4-0.5-0.4
|
|
||||||
c-0.7,0-1.7,0.5-2.6,1l-0.9,4.8h-1.1l1.2-6.7l1-0.2l-0.1,1c0.7-0.5,2.1-1,2.9-1C206.4,45.8,206.8,46.2,206.8,47z"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 5.5 KiB |
Loading…
Reference in New Issue