Skip to content

Commit

Permalink
Add the task « Tool - Create a File »
Browse files Browse the repository at this point in the history
  • Loading branch information
Fizcko committed Oct 16, 2020
1 parent fa9ea9b commit 9ca1c89
Show file tree
Hide file tree
Showing 15 changed files with 338 additions and 10 deletions.
10 changes: 7 additions & 3 deletions build_job.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ catch{
# Get sub projects
$subProjects = $jsonVssConfigFile.contributions
Foreach ($subProject in $subProjects){
$currentProjectName = $subProject.properties.name
$subProjectPath = Join-Path -Path $rootPath -ChildPath $subProject.properties.name
$subCommunFolderPath = Join-Path -Path $subProjectPath -ChildPath $commonFolderName
$pathTaskConfigFile = Join-Path -Path $subProjectPath -ChildPath "task.json"
Expand Down Expand Up @@ -89,10 +90,13 @@ Foreach ($subProject in $subProjects){
}

# Copy common functions
if(Test-Path $subCommunFolderPath){
Remove-Item -Path "$subCommunFolderPath" -Recurse | Out-Null
$excludeFolders = ("dist/tool_create_file")
if($currentProjectName -NotIn $excludeFolders){
if(Test-Path $subCommunFolderPath){
Remove-Item -Path "$subCommunFolderPath" -Recurse | Out-Null
}
Copy-Item -Path "$pathCommon" -Destination "$subProjectPath" -Recurse -Force
}
Copy-Item -Path "$pathCommon" -Destination "$subProjectPath" -Recurse -Force
}

# Delete common folder
Expand Down
2 changes: 1 addition & 1 deletion dist/kv_read/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"author": "Fizcko",
"version": {
"Major": 2,
"Minor": 4,
"Minor": 5,
"Patch": 0
},
"instanceNameFormat": "Vault - Read KV secrets",
Expand Down
Binary file added dist/tool_create_file/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions dist/tool_create_file/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "CreateFile",
"dependencies": {
"azure-pipelines-task-lib": "2.8.0"
},
"engines": {
"node": ">=6"
}
}
118 changes: 118 additions & 0 deletions dist/tool_create_file/task.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
{
"id": "81152B68-7A9D-4471-8579-4CDA672AC509",
"name": "ToolCreateFile",
"friendlyName": "Tool - Create a File",
"description": "Provide the ability to create a file and perform an action on his content.",
"helpMarkDown": "",
"category": "Utility",
"visibility": [
"Build",
"Release"
],
"author": "Fizcko",
"version": {
"Major": 2,
"Minor": 5,
"Patch": 0
},
"instanceNameFormat": "Tool - Create a File",
"groups": [
{
"name": "groupSettings",
"displayName": "Settings",
"isExpanded": true
}
],
"inputs": [
{
"name": "targetDirectory",
"type": "filePath",
"label": "Target directory",
"defaultValue": "$(System.DefaultWorkingDirectory)",
"required": true,
"helpMarkDown": "Directory to save the file.",
"groupName": "groupSettings"
},
{
"name": "targetName",
"type": "string",
"label": "File name",
"defaultValue": "myCert.pem",
"required": true,
"helpMarkDown": "Enter the file name with the extension.",
"groupName": "groupSettings"
},
{
"name": "fileContent",
"type": "multiLine",
"label": "File Content",
"defaultValue": "",
"required": true,
"helpMarkDown": "Enter the content of the file.",
"groupName": "groupSettings"
},
{
"name": "fileEncoding",
"type": "pickList",
"label": "Encoding",
"defaultValue": "utf8",
"required": true,
"helpMarkDown": "Specifies the file encoding. More defails in NodeJS documentation (Buffers and Character Encodings).",
"groupName": "groupSettings",
"options": {
"ascii": "ASCII",
"utf8": "UTF8",
"utf16le": "BigEndianUTF32",
"ucs2": "UCS-2 (Alias of UTF-16LE)",
"base64": "Base64 encoding",
"latin1": "Latin-1",
"binary": "Binary (Latin-1)",
"hex": "HEX"
}
},
{
"name": "actionType",
"type": "pickList",
"label": "Action to perform",
"defaultValue": "none",
"required": true,
"helpMarkDown": "Choose an action to perform on the file content.",
"groupName": "groupSettings",
"options": {
"none": "No action",
"replaceToken": "Replace token by a new line",
"decodeBase64": "Decode from base64"
}
},
{
"name": "actionToken",
"type": "string",
"label": "Token to replace",
"defaultValue": "",
"required": true,
"helpMarkDown": "Enter the token to replace by a new line.",
"groupName": "groupSettings",
"visibleRule": "actionType = replaceToken"
},
{
"name": "actionNewLineType",
"type": "pickList",
"label": "New line type",
"defaultValue": "crlf",
"required": true,
"helpMarkDown": "Choose the new line type",
"groupName": "groupSettings",
"options": {
"cr": "Carriage Return (CR, \\r)",
"lf": "Line Feed (LF, \\n)",
"crlf": "CR followed by LF (CRLF, \\r\\n)"
},
"visibleRule": "actionType = replaceToken"
}
],
"execution": {
"Node": {
"target": "tool_create_file.js"
}
}
}
41 changes: 41 additions & 0 deletions overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,49 @@

There is now four variables called « APP1_DEV_key_1 », « APP1_DEV_key_2 », « APP2_DEV_key_1 », « APP2_DEV_key_2 » that you can used in your next tasks by using $(APP1_DEV_key_1), $(APP1_DEV_key_2), $(APP2_DEV_key_1), $(APP2_DEV_key_2).


- ### Tool - Create a File

Provide the ability to create a file and perform an action on his content.

Parameters :
- **Target directory**: Directory to save the file.
- **File name**: Name of the file to create (ended by the extension).
- **File Content**: Content of the file.
- **Encoding**: Output file encoding. More defails in NodeJS documentation (Buffers and Character Encodings).
- **Action to perform**: Action to perform on the file content.
- Replace token by a new line
- Decode from base64
- **Token to replace**: Define the token to replace by a new line.
- **New line type**: The type of the new line.
- Carriage Return (CR, \r)
- Line Feed (LF, \n)
- CR followed by LF (CRLF, \r\n)

## Use case 1

A variable loaded by the task « Vault - Read KV secrets » contains a multiline value where the carriage return have been replaced by a token.
This variable is named « $(APP2_DEV_key_3) ». The token is « #{rn}# ».

![Azure DevOps configuation 3](screenshots/tool_create_file_00.png)

A file called « myCert.pem » will be created and the token « #{rn}# » will be replaced by a Windows Carriage Return (CRLF).

## Use case 2

A variable loaded by the task « Vault - Read KV secrets » contains a base64 encoded value.
This variable is named « $(APP2_DEV_key_4) ».

![Azure DevOps configuation 4](screenshots/tool_create_file_01.png)

A file called « myCert.pem » will be created with the content of decoded from base64.


## Release note

### v2.5.0
- Add the task « Tool - Create a File ».

### v2.4.0
- Add possibility to use namespaces (Vault Enterprise).

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
"scripts": {
"build": "tsc",
"postbuild": "powershell -ExecutionPolicy ByPass -Command ./build_job.ps1",
"pretest": "",
"pretest": "tsc",
"test": "mocha ./test/run_all.js"
},
"dependencies": {
"azure-pipelines-task-lib": "2.8.0",
"typescript": "3.3.3333"
},
"devDependencies": {
"@types/node": "^8.10.42",
"@types/node": "10.17.39",
"@types/q": "^1.5.1",
"mocha": "^6.1.4"
}
Expand Down
Binary file added screenshots/tool_create_file_00.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/tool_create_file_01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
92 changes: 92 additions & 0 deletions src/tool_create_file/tool_create_file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import tl = require('azure-pipelines-task-lib/task');
import path = require('path');
import fs = require('fs');

async function run() {

try {

var targetDirectory = tl.getInput('targetDirectory', true);
var targetName = tl.getInput('targetName', true);
var fileContent = tl.getInput('fileContent', true);
var fileEncoding = tl.getInput('fileEncoding', true);
var actionType = tl.getInput('actionType', true);
if(actionType == "replaceToken"){
var actionToken = tl.getInput('actionToken', true);
var actionNewLineType = tl.getInput('actionNewLineType', true);
}

// Define output path
var outputFilePath = path.join(targetDirectory,targetName);

// Create ouptuf folder is needed
if(!fs.existsSync(targetDirectory)){

try{
fs.mkdirSync(targetDirectory,{ recursive: true });
} catch (err) {
throw new Error("Mkdir error. " + err);
}
}

var finalContent = null;
var actionToPerform = null;

// Perform actions
switch(actionType){
case "replaceToken":
// Create regex
var newLine = null;
var newLineType = null;
switch(actionNewLineType){
case "cr":
newLine = "\r";
newLineType = "Carriage Return (CR, \\r)";
break;
case "lf":
newLine = "\n";
newLineType = "Line Feed (LF, \\n)";
break;
default:
newLine = "\r\n";
newLineType = "CR followed by LF (CRLF, \\r\\n)";
break;
}
finalContent = fileContent.replace(new RegExp(actionToken,"g"),newLine);
actionToPerform = "Replace token";
break;
case "decodeBase64":
finalContent = new Buffer(fileContent, 'base64');
actionToPerform = "Decode from base64";
break;
default:
finalContent = fileContent;
actionToPerform = "None";
}

// Create file
try{
fs.writeFileSync(outputFilePath,finalContent,fileEncoding);
} catch (err) {
throw new Error("Write error. " + err);
}

// Display results
console.log("[INFO] The file saved in : '" + outputFilePath + "'");
console.log("[INFO] Encoding : '" + fileEncoding + "'");
console.log("[INFO] Action to perform : '" + actionToPerform + "'");
if(actionType == "replaceToken"){
console.log("[INFO] Token to replace : '" + actionToken + "'");
console.log("[INFO] New line type : '" + newLineType + "'");
}

tl.setResult(tl.TaskResult.Succeeded, "Wrapping successfull.");

} catch (err) {
tl.setResult(tl.TaskResult.Failed, err);
}


}

run();
15 changes: 12 additions & 3 deletions test/conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,16 @@
"strSecretPath": "/",
"strPrefixType": "folder",
"strVariablePrefix": "xxx",
"replaceCR": false,
"strCRPrefix": "<br>"
}
"replaceCR": true,
"strCRPrefix": "#{rn}#"
},
"tool_create_file": {
"targetDirectory": ".",
"targetName": "myCert.pem",
"fileContent": "-----BEGIN CERTIFICATE-----#{rn}#MIIF2zCCBMOgAwIBAgIQMj8HjgweXkbwMLVJON0bgTANBgkqhkiG9w0BAQsFADCB#{rn}#pDELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMR8w#{rn}#HQYDVQQLExZGT1IgVEVTVCBQVVJQT1NFUyBPTkxZMR8wHQYDVQQLExZTeW1hbnRl#{rn}#YyBUcnVzdCBOZXR3b3JrMTQwMgYDVQQDEytTeW1hbnRlYyBDbGFzcyAzIFNlY3Vy#{rn}#ZSBTZXJ2ZXIgVEVTVCBDQSAtIEc0MB4XDTE2MDYyODAwMDAwMFoXDTE4MDYyOTIz#{rn}#NTk1OVowgZIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYD#{rn}#VQQHDA1Nb3VudGlhbiBWaWV3MR0wGwYDVQQKDBRTeW1hbnRlYyBDb3Jwb3JhdGlv#{rn}#bjEgMB4GA1UECwwXV1NTIC0gVGVjaG5pY2FsIFN1cHBvcnQxFTATBgNVBAMMDCou#{rn}#YmJ0ZXN0Lm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANqBKkO6#{rn}#e/P7/PaWFX2dt+drAKhAn/LRDp62EF41aMU/XYnla18b5FzUc2dhEme17Vnv8tX5#{rn}#Brbo/3hr+dqPhJdfr6NbUvvlsBGUrlrpeg1ARHita2cPob7BDP2jQoWDtM36rwZB#{rn}#vkgz7+8BPvZqkiwqyZEe0h0l7dmNozMtt587pfLby86+tfR1rLZHnxw+DLe/+gpp#{rn}#XiHtTMvC6mvGmlouYmX98pb/i2PnyXmoiihSqknwM74oM3zDDG3Lu0w8xCBA9Z//#{rn}#N0rcRGSiebrne01KgfoFREXAMPLEyrC8S0ospuMq0ybMin5Fr07P6nnC+1KblzEM#{rn}#LlRoGP8p48Giw9ECAwEAAEXAMPLEggITMCwGA1UdEQQlMCOCE3d3dy5zdWIxLmJi#{rn}#dGVzdC5uZXSCDCouYmJ0ZEXAMPLEdDAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIF#{rn}#oDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwYQYDVR0gBFowWDBWBgZn#{rn}#gQwBAgIwTDAjBggrBgEFBQcCARYXaHR0cHM6Ly9kLnN5bWNiLmNvbS9jcHMwJQYI#{rn}#KwYBBQUHAgIwGQwXaHR0cHM6Ly9kLnN5bWNiLmNvbS9ycGEwHwYDVR0jBBgwFoAU#{rn}#NI9UtT8KH1K6nLJl7bqLCGcZ4AQwKwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL3Nz#{rn}#LnN5bWNiLmNvbS9zcy5jcmwwVwYIKwYBBQUHAQEESzBJMB8GCCsGAQUFBzABhhNo#{rn}#dHRwOi8vc3Muc3ltY2QuY29tMCYGCCsGAQUFBzAChhpodHRwOi8vc3Muc3ltY2Iu#{rn}#Y29tL3NzLmNydDASBgMrZU0ECzAJAgECAgEAAgEAMIGKBgorBgEEAdZ5AgQCBHwE#{rn}#egB4AHYAz3GACoQ0AjQYnozSWjcDUvuZ+2fYD8twB2c4YgBqrFkAAAFVl1jMRgAA#{rn}#BAMARzBFAiBctH4rg/vd5UCtnYOaFaXI4HJ6S6Bk8T9GPpHENDP0NAIhANeO/2+h#{rn}#/1aJqPOe5uGfDqipS5wWrUUOaJpU9fuHoDJQMA0GCSqGSIb3DQEBCwUAA4IBAQAu#{rn}#Q/MfYrDQP4PqnzEUoAm6waVZ2hm/3H80sQXDrN1O50ZNvjHNsjzwdCEu1bwFfa6b#{rn}#0b8P4y4nKa4aOl0/mJlq/Awfrx0uC81UIMLwmX2mZ5dbaXHKEZh2tHChnDwhZGPE#{rn}#KVZJ0KxOA12CTRMEOG5XHTe7Yl+wOQWm8h0ky0DY+FMT5AgcCo6IMxMbyyxotQtE#{rn}#/8DmwtZQytA2yqtZWq0765t6PCJSbnK6zp0aLTSwYZVij1BCDMYleiZcDvIN6Jv/#{rn}#ElnDwrxs1CsMwh7zY8wB8gc7GHq63BBW1hCwsDx2guDCEmbJa+ktv7EBz2BgiL6V#{rn}#Zg+QqIFz0YSDQJfFMTi#{rn}#-----END CERTIFICATE-----",
"fileEncoding": "utf8",
"actionType": "replaceToken",
"actionToken": "#{rn}#",
"actionNewLineType": "crlf"
}
}
20 changes: 20 additions & 0 deletions test/run_all.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const path = require('path');
const ttm = require('azure-pipelines-task-lib/mock-test');

describe('azure-devops-vault-interaction', function () {

it("kv_read", (done) => {

var tp = path.join(__dirname, "kv_read.js");
Expand All @@ -24,4 +25,23 @@ describe('azure-devops-vault-interaction', function () {
done(error);
}
});

it("tool_create_file", (done) => {

var tp = path.join(__dirname, "tool_create_file.js");
var tr = new ttm.MockTestRunner(tp);

tr.run();

try {
assert(tr.succeeded, "Should have succeeded");
console.log("STDOUT", tr.stdout);
done();
}
catch (error) {
console.log("STDERR", tr.stderr);
console.log("STDOUT", tr.stdout);
done(error);
}
});
});
Loading

0 comments on commit 9ca1c89

Please sign in to comment.