How to overwrite parameter of Data Factory in Azure DevOps Pipeline? - Empty space in ARM Template cause errors? - azure-devops

I'm trying to add parameter in Azure Data Factory so that I can overwrite parameter value for each Dev, Test and Prod environment. Currently I have set static string in DevOps Release as parameter value.
However I get strange errors from Azure DevOps.
I wonder why Data Factory save parameter name as "Web pipeline_properties_parameters_LogicAppURL_defaultValue", which has empty space after Web.
Have edited "ARM Template"->"Edit parameter configuration" and published parameter:
"Microsoft.DataFactory/factories/pipelines": {
"properties": {
"parameters": {
"LogicAppURL": {
"defaultValue": "="
}
}
}
ARMTemplateParametersForFactory.json in Git Repo:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"factoryName": {
"value": "my-warehouse-dev-df"
},
"Web pipeline_properties_parameters_LogicAppURL_defaultValue": {
"value": "http://www.devpipeline.fi"
}
}
}
Error when creating release:
The detected encoding for file 'D:\a\r1\a\_Azure Data
Factory DevOps-CI\drop\ARMTemplateForFactory.json' is 'utf-8'
The detected encoding for file 'D:\a\r1\a\_Azure Data
Factory DevOps-CI\drop\ARMTemplateParametersForFactory.json' is 'utf-8'
There was an error while overriding 'Web' parameter
because of 'TypeError: Cannot read property 'type' of undefined', make sure it
follows JavaScript Object Notation (JSON)
There was an error while overriding '' parameter
because of 'TypeError: Cannot read property 'type' of undefined', make sure it
follows
JavaScript Object Notation (JSON)
Starting template validation.
Deployment name is ARMTemplateForFactory-20211220-162118-0e5d
There were errors in your deployment. Error code:
InvalidDeploymentParameterKey.
##[error]One of the deployment parameters has an empty
key. Please see https://aka.ms/resource-manager-parameter-files for details.

This is a known issue. As the error says, try to edit the parameter name as below.
However, placing it between " " should have sufficed.
"Web_pipeline_properties_parameters_LogicAppURL_defaultValue"
Also, if you would want to leave the parameter value empty by default, you can set as below:
"Microsoft.DataFactory/factories/pipelines": {
"properties": {
"parameters": {
"LogicAppURL": {
"defaultValue": {}
}
}
}
And while overriding template parameter, use:
-param "value"

Related

How do I make parcel inline sourcemaps?

By default parcel put source map in a separate file. How do I tell parcel to put source map in the same output file? I guess it is called inline source maps?
See this section of the documentation: https://parceljs.org/features/targets/#sourcemap.
In your package.json, add the following:
{
"targets": {
"default": {
"sourceMap": {
"inline": true
}
}
}
}
Note that you may need to change "default" to match your own target name, if you've configured other options.

Parsing integers in serverless.yml to use MemoryDB's ClusterEndpoint.Port in Environment Variable

I'm creating a MemoryDB cluster for my serverless function, but the Port for the MemoryDB endpoint is an Integer, so when I try to set an environment variable to pass the endpoint URL to my function I get an error
Error:
Cannot resolve serverless.yml: Variables resolution errored with:
- Cannot resolve variable at "provider.environment.MEMORYDB_ENDPOINT": String value consist of variable which resolve with non-string value
Example serverless.yml file:
provider:
name: aws
# [...]
environment:
MEMORYDB_PORT: ${self:custom.MEMORYDB_PORT}
# [...]
custom:
MEMORYDB_PORT: !GetAtt MemoryDB.ClusterEndpoint.Port
I've tried with Fn::Join, Fn::Sub (plugin) and others but they all expect strings as arguments.
I'm not planning on using a custom port so I can always assume the default, however I feel like I'm missing some thing here.
Is there a way to parse integers in serverless/cloudformation somehow? Or at least convert that port into a string?
As far as I know serverless doesn't allow having functions in .yaml file, since that is just a declaration.
You could have a custom plugin: https://www.serverless.com/framework/docs/guides/plugins/custom-variables
It would looks something similar
export class MaxBatchingWindowIntParser {
public configurationVariablesSources: object;
public constructor() {
this.configurationVariablesSources = {
parseValue: {
resolve({ address }) {
return {
value: Number.parseInt(address, 10),
};
},
},
};
}
}

How to use if else in ARM template azure

I have created sample function here in c# which set the location value based on the parameter. I want to write below expression by using arm template style format.
public static Main(string name)
{
string location = string.Empty;
if(name == "uksouth")
{
location = "UKS";
}else if(name == "ukwest")
{
location = "UKE";
}else if(name == "IndiaWest")
{
location = "INDW";
}
else {
location = "INDS";
}
}
I have written this for one match condition, but i want to return value based on the user resource group.
"value": "[if(equals(resourceGroup().location,'uksouth'), 'UKS', 'EUS')]"
Unfortunately, ARM templates don't provide the equivalent of a "switch" mechanism, which is what might make this easier. However, you can nest multiple if statements. The syntax is a bit clunky, but this should be the equivalent of the code you've written:
"value": "[if(equals(resourceGroup().location,'uksouth'), 'UKS', [if(equals(resourceGroup().location,'ukwest'), 'UKE', [if(equals(resourceGroup().location,'IndiaWest'), 'INDW', 'INDS')])])]"
Here's the same code with a little formatting applied to make it more obvious what's happening here:
"value": "
[if(equals(resourceGroup().location,'uksouth'),
'UKS',
[if(equals(resourceGroup().location,'ukwest'),
'UKE',
[if(equals(resourceGroup().location,'IndiaWest'),
'INDW',
'INDS')])])]
"
You might also consider the approach described in this answer for a bit of a cleaner solution.
Try defining a variable that is an object used like a hashtable. Retrieve different properties from the object by key-name, accessing the properties as key-value pairs. I use something very similar to lookup values inside my ARM templates.
"variables" {
"locationShorten": {
"uksouth": "UKS",
"ukwest": "UKE",
"IndiaWest": "INDW",
"IndiaSouth": "INDS"
},
"locationShort": "[variables('locationShorten')[resourceGroup().location]]"}
Microsoft defines an object's properties as key-value pairs. "Each property in an object consists of key and value. The key and value are enclosed in double quotes and separated by a colon (:)."
Source: https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/data-types#objects
As for the documentation on using [] to access object properties, I can no longer find it for JSON but it is there for BICEP. "You can also use the [] syntax to access a property."
Source: https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/data-types#objects

Add tasks to tasks.json for users of a vscode extension

I am writing a vscode extention for a specification language. I would like to provide the users of the plugin with a specific task. The task could be made available using tasks.json.
Is there a way to add tasks to the tasks.json of a user that uses that extension?
The documentation didn't help me here either. When you provide tasks through the extension there is the TaskProvider API. The example doesn't go into much detail about how these tasks are created though, compared to the classical tasks.json approach.
In your package.json you need to define the types of tasks this extension contributes. This has nothing to do with the type in tasks.json. It's rather a freeform string. If you need custom problem matchers you also need to define theme here.
"contributes": {
"taskDefinitions": [
{
"type": "mytask"
}
],
"problemMatchers": [
{
"name": "mywarnings",
"base": "$gcc",
"fileLocation": [
"relative",
"/"
]
}
]
},
In extension.ts you need to provide the tasks. Say we have an array of vscode.Task in tasks you can do:
vscode.tasks.registerTaskProvider('mytask', {
provideTasks: () => {
return tasks;
},
resolveTask(_task: vscode.Task): vscode.Task | undefined {
// as far as I can see from the documentation this just needs to return undefined.
return undefined;
}
});
If you want to create a shell task you need the following:
new vscode.Task (
{type: 'shell'}, // this is the same type as in tasks.json
ws, // The workspace folder
'name', // how you name the task
'MyTask', // Shows up as MyTask: name
new vscode.ShellExecution(command),
["mywarnings"] // list of problem matchers (can use $gcc or other pre-built matchers, or the ones defined in package.json)
);
I hope this helps. The bigges issue I see is the overloading of various names (like type), and that the format in tasks.json is completely different to the way tasks are built with TaskProvider API.

What is the difference between sap.ui.core.routing.Router.navTo() and sap.m.routing.Targets.display()?

Let’s say we I have one route and one target:
"routes": [{
"pattern": "modify",
"name": "modify",
"target": [
"master",
"modify"
]
}],
"targets": {
"modify": {
"viewName": "Modify",
"viewId": "modify",
"viewLevel": 2
}
}
So I can access the route by this.getRouter().navTo("modify"), meanwhile I can access the target by this.getRouter().getTargets().display("modify"). Both API can carry parameter by the second argument. It seems to achieve the same effect.
I can access target without defining a route for it. So I did not quite understand why I need a route?
Ref: sap.m.routing.Targets and
sap.ui.core.routing.Router
display displays the target view without changing the hash value in contrast to navTo.
You can find more information in the tutorial "Display a Target Without Changing the Hash".
Both API can carry parameter by the second argument. It seems to achieve the same effect.
The data in display method is for the display event handler. When the event is fired, the handler carries the data we passed earlier.
The parameter map we can pass to navTo is mandatory if the pattern actually awaits a parameter, e.g. if we've defined the pattern like this initially: "pattern": "modify/{id}". Check out "Navigate to Routes with Mandatory Parameters".
Just complement Boghyon's answer:
Route pattern is defined in Router, and hash is set in Router. That's the main difference.BTW, UI5 uses crossroads and hasher to help implementing router.
navTo() in sap.m.routing.Router is borrowed from sap.ui.core.routing.Router
display() in sap.m.routing.Targets is borrowed from sap.ui.core.routing.Targets
in _routeMatched of Route, oRouter._oTargets._display is called. So _display is called in both Router and Targets.
The parameter they use are different.navTo use Route name, and display use Target name. Sometimes they are defined the same.
onToPage2 : function () {
// this.getOwnerComponent().getRouter().navTo("pageRoute2");
this.getOwnerComponent().getRouter().getTargets().display("pageTarget2");
},
onToPage1 : function () {
this.getOwnerComponent().getRouter().navTo("pageRoute1");
// this.getOwnerComponent().getRouter().getTargets().display("pageTarget1");
}