Not always a two way Related link in Azure DevOps using c# - c#

I am creating a related link with the referenceName System.LinkTypes.Related in Azure DevOps programmatically using C# and Azure DevOps' SDK as below:
JsonPatchDocument patchDoc = new JsonPatchDocument();
patchDoc.Add(
new JsonPatchOperation
{
From = null,
Operation = Operation.Add,
Path = "/relations/-",
Value = new {
rel = "System.LinkTypes.Related",
url = $"https://dev.azure.com/{organization}/{projectName}/_workitems/edit/{relatedId}",
attributes = new
{
comment = $"Created programmatically on {DateTime.Now}."
}
}
}
);
await azureClient.UpdateWorkItemAsync(patchDoc, id, false, true, true, WorkItemExpand.All, cancellationToken: token);
The code above always created a two way link between id and relatedId.
But sometimes the link is one way!
How can i be sure to always create a link in both directions?

Related

Create Lambda proxy integration inside a non-root resource in API Gateway using AWS SDK with C#

The bounty expires in 7 days. Answers to this question are eligible for a +100 reputation bounty.
Harun Ćerim is looking for an answer from a reputable source:
A detailed explanation of how Lambda integration can be done on a non-root resource inside an API Gateway where routes are currently mapped to an underlying Lambda function and its underlying routes
I am trying to create a proxy integration for Lambda invocation from API Gateway for a specific route (example.com/auth/{proxy+}, example.com/user/{proxy+}, etc..).
I am creating a script for automated infrastructure initialization and deployment (without using CloudFormation, Terraform, etc.) directly from .NET script that is planned to be available as an API.
Predefined infrastructure contains: Route53 config, created API Gateway with custom domain.
Dynamic infrastructure contains: S3 and Lambda together with API Gateway modifications and deployment.
Once the bucket for a new service is created and the built app is pushed to the bucket, new Lambda function is created, configured and published. The last thing that is left is to create a new resource (route) that will invoke underlying Lambda function and its underlying routes (e.g. example.com/auth/register).
The issue is that when I create an integration on a non-root resource, Lambda function cannot be found or the Uri is not specified as it should be (this is something I am trying to figure out).
Here is the simplified code that I wrote to accomplish this (I will exclude Lambda function and S3 bucket created and show only API gateway and Lambda resource policy updates as they are relevant here). Important to note is that this code produces the same results as if it would be done via AWS console. Also, this code produces a working solution if the route is not specified (e.g. example.com/register)
var functionArn = await Lambda.GetFunctionArn(accessKey, secretKey, region, lambdaFunction);
var pathResponse = await c.CreateResourceAsync(new CreateResourceRequest
{
ParentId = rootId,
PathPart = path,
RestApiId = apiId
});
await c.PutMethodAsync(new PutMethodRequest
{
AuthorizationType = "NONE",
HttpMethod = "ANY",
ResourceId = pathResponse.Id,
RestApiId = apiId
});
var proxyResponse = await c.CreateResourceAsync(new CreateResourceRequest
{
ParentId = pathResponse.Id,
PathPart = "{proxy+}",
RestApiId = apiId
});
await c.PutMethodAsync(new PutMethodRequest
{
AuthorizationType = "NONE",
HttpMethod = "ANY",
ResourceId = proxyResponse.Id,
RestApiId = apiId
});
await Lambda.AddPermissions(account, accessKey, secretKey, region, lambdaFunction, apiId, path);
await c.PutIntegrationAsync(new PutIntegrationRequest
{
HttpMethod = "ANY",
IntegrationHttpMethod = "POST",
ResourceId = pathResponse.Id,
RestApiId = apiId,
PassthroughBehavior = "WHEN_NO_MATCH",
Type = IntegrationType.AWS_PROXY,
Uri = $"arn:aws:apigateway:{region}:lambda:path/2015-03-31/functions/{functionArn}/invocations"
});
await c.PutIntegrationAsync(new PutIntegrationRequest
{
HttpMethod = "ANY",
IntegrationHttpMethod = "POST",
ResourceId = proxyResponse.Id,
RestApiId = apiId,
PassthroughBehavior = "WHEN_NO_MATCH",
Type = IntegrationType.AWS_PROXY,
Uri = $"arn:aws:apigateway:{region}:lambda:path/2015-03-31/functions/{functionArn}/invocations"
});
var deployment = await c.CreateDeploymentAsync(new CreateDeploymentRequest
{
Description = $"API deployment to {environment}",
RestApiId = apiId,
StageName = environment
});
return deployment.Id;
where Lambda.AddPermissions is as follows:
var basePermission = await c.AddPermissionAsync(new AddPermissionRequest
{
Action = "lambda:InvokeFunction",
FunctionName = name,
Principal = "apigateway.amazonaws.com",
SourceArn = $"arn:aws:execute-api:{region}:{account}:{apiId}/*/*/{path}/*",
StatementId = Guid.NewGuid().ToString()
});
var proxyPermission = await c.AddPermissionAsync(new AddPermissionRequest
{
Action = "lambda:InvokeFunction",
FunctionName = name,
Principal = "apigateway.amazonaws.com",
SourceArn = $"arn:aws:execute-api:{region}:{account}:{apiId}/*/*/{path}",
StatementId = Guid.NewGuid().ToString()
});
return new List<string>
{
basePermission.Statement,
proxyPermission.Statement
};
Is there an issue with SourceArn specifications? I first created them through the AWS console (they are automatically created when the integration is created for Lambda) and they are the same.
Again, this all works when there is no path (non-root resource).

Assign App Service - Identity to KeyVault in Azure using Pulumi

I create an App Service using "classic" Pulumi.Azure:
var appservice=new AppService(appserviceName, new AppServiceArgs
{
Name = appserviceName,
Location = _resourceGroup.Location,
AppServicePlanId = _servicePlan.Id,
ResourceGroupName = _resourceGroup.Name,
SiteConfig = new Pulumi.Azure.AppService.Inputs.AppServiceSiteConfigArgs
{
DotnetFrameworkVersion = "v5.0",
ScmType = "None",
},
Tags = { { "environemnt", "dev" } },
Logs = new AppServiceLogsArgs
{
HttpLogs = new AppServiceLogsHttpLogsArgs
{
FileSystem = new AppServiceLogsHttpLogsFileSystemArgs { RetentionInDays = 14, RetentionInMb = 35 }
}
}
,
AppSettings = appSettings
});
I also create a keyvault:
var currentConfig=Output.Create(GetClientConfig.InvokeAsync());
var keyVault = new KeyVault(vaultname, new KeyVaultArgs
{
Name = vaultname,
Location = _resourceGroup.Location,
ResourceGroupName = _resourceGroup.Name,
TenantId = currentConfig.Apply(q => q.TenantId),
SkuName="standard"
, AccessPolicies=
{
new Pulumi.Azure.KeyVault.Inputs.KeyVaultAccessPolicyArgs
{
TenantId=currentConfig.Apply(q=>q.TenantId),
ObjectId=currentConfig.Apply(q=>q.ObjectId),
KeyPermissions={"get", "create", "list"},
SecretPermissions={"set","get","delete","purge","recover", "list"}
}
}
});
Both work as expected. KeyVault and App Service are being created and accessable by me. Now I need that the App Service also can access the KeyVault.
But when adding a new Access Policy I am stuck at the ObjectId. The App Service does not seem to have a valid object id I can assign to the vault. When checking the service on Azure Portal I also see the Identy is missing:
So what has to be done as pulumi code that would achieve the same thing as clicking onto "On" in Azure and retrieve the ObjectId afterwards?
You need to set the following property on AppService to enable the managed identity:
Identity = new AppServiceIdentityArgs {Type = "SystemAssigned"},
This example illustrates the end-to-end implementation: https://github.com/pulumi/examples/blob/327afe30ce820901f210ed2a01da408071598ed6/azure-cs-msi-keyvault-rbac/AppStack.cs#L128

How can we add existing links in Azure DevOps programmatically

I want to link the existing work items which are already created in a project under Azure DevOps by writing a code or program in C#, so is there any kind of API or SDK which can be used to link the work items programmatically?
The Workitems can be of any type i.e.
Bug
User Story
Issue
Task etc.
The linking between the Workitems can also be of any type i.e. Relational, Parent-Child, etc.
Recently I referred to this link for my problem.
The link contains issue very much related and similar to mine, however it is not working as expected when I tried it.
Given:
//int relatedId = ...
//int id = ...
//CancellationToken token = ...
//string organization = ...
//string projectName = ...
//WorkItemTrackingHttpClient azureClient = ...
Create a JsonPatchDocument as below:
JsonPatchDocument patchDoc = new JsonPatchDocument();
patchDoc.Add(
new JsonPatchOperation
{
From = null,
Operation = Operation.Add,
Path = "/relations/-",
Value = new {
rel = "System.LinkTypes.Related",
url = $"https://dev.azure.com/{organization}/{projectName}/_workitems/edit/{relatedId}",
attributes = new
{
comment = $"Created programmatically on {DateTime.Now}."
}
}
}
);
and call this async method of Azure DevOps SDK:
await azureClient.UpdateWorkItemAsync(patchDoc, id, false, true, true, WorkItemExpand.All, cancellationToken: token);
In the case above we created a related link using System.LinkTypes.Related referenceName.
For a full link types reference guide in Azure DevOps refer to this so's question or this microsoft's doc.

How to use Embedding with C#? Discord BOT

I am looking to embed the following:
Using the Discord API. I have looked and the only resources I can find are for Python, Java, Ruby, etc.
But when using:
var embed = new Message.Embed(
{
Author =
{
Name = "Name",
Url = "www.url.com"
}
});
It comes back with the message:
And:
Not sure What I need to do to be able use the embed library. Just looking for some guidance on how this works
Edit:
When Using this I get no errors but when running the embed doesnt seem to build. It doesnt error. It just never builds the embed variable
var embed = new Message.Embed
{
Author =
{
Name = "Lawler",
Url = "www.twitch.tv/Lawler"
},
Title = "www.twitch.tv/Lawler",
Thumbnail =
{
ProxyUrl = "https://yt3.ggpht.com/-m-P7t2g-ecQ/AAAAAAAAAAI/AAAAAAAAAAA/YtS2YsD8-AM/s900-c-k-no-mo-rj-c0xffffff/photo.jpg",
Url = "www.twitch.tv/Lawler"
},
Description = "**Now Playing**\n" +
"Rocket League\n" +
"**Stream Title**\n" +
"Lawler RLCS Caster"
};
*Note: I am using Discord v 0.9.6
You can create an Embed Message like the following code (using the most recent version of Discord.Net):
var builder = new EmbedBuilder()
{
//Optional color
Color = Color.Green,
Description = "This is the description of the embed message"
};
Build a field inside the Embed Message:
builder.AddField(x =>
{
x.Name = Author.Name;
x.Value = Author.Url;
x.IsInline = false;
});
And reply to the same channel context:
//Use await if you're using an async Task to be completed.
await ReplyAsync("", false, builder.Build())
The code above should build an embed message, there are more options in the Discord.Net docs. Link: https://docs.stillu.cc/guides/introduction/intro.html
I hope you find this helpful.
Just a quick look at your code, I think you've got a close parenthesis in the wrong place.
Try the following:
var embed = new Message.Embed()
{
Author =
{
Name = "Name",
Url = "www.url.com"
}
};
Again, without doing any research you may also need to do the following:
var embed = new Message.Embed()
{
Author = new Author()
{
Name = "Name",
Url = "www.url.com"
}
};
var embed = new EmbedBuilder()
instead of
var embed = new Message.Embed()
To send the message:
await Context.Channel.SendMessageAsync("", false, embed);
EDIT: 0.9.6 doesn't support embeds, so the code above is useless
If you are in Discord.Net 1.0.1, you can format an embed like so:
var eb = new EmbedBuilder() { Title = "Cool Title", Description = "Description" };
Read the documentation here for more info here.
And if you want to make your text look a little better, you can read the Discord Markdown Documentation here. This works in 0.9.6.
To send an embed use:
await Context.Channel.SendMessageAsync("", false, eb);

Connect CouchDB with asp.net C# application

How to connect couchDB with ASP.NET C# application? If any one can you give a sample application.
I had the same need and after evaluating the options available, to meet the requirements of my application, I created any components that helped me a lot and maybe they can help you and also others. I make it clear that I have no intention of promoting myself here, just sharing something that may be useful.
The detailed explanation of how to configure and use it is on Github.
Link: Nuget Package |
Github
Example of use for retrieving documents with mango-querie:
IList<User> users;
var sts = new List<String> { "ACTIVE", "LOCKED" };
using (UserRepository db = new UserRepository())
{
var query = db.FindOf("list-status", new { id = "OwnerIdloop.user.7", statuses = sts });
users = db.List<User>(query);
}
Array.ForEach(users.ToArray(), Console.WriteLine);
Example of adding documents:
User user = createUser("email#email.com");
using (UserRepository db = new UserRepository())
{
var result = db.Insert<User>(user); // add document and return instance changed with operation revision id
Console.WriteLine(result.Revision);
}
Example of changing documents:
using (UserRepository db = new UserRepository())
{
// Load document data by ID
var user = db.Get<User>("email#email.com");
user.Name = user.Name + "::CHANGED";
var result = db.Update<User>(user); // update document and return instance changed with operation revision id
Console.WriteLine(result.Revision);
}
Example of deleting documents:
using (UserRepository db = new UserRepository())
{
// Load document data by ID
var user = db.Get<User>("email#email.com");
var result = db.Delete<User>(user); // delete document from database. Return true case sucess or false case not deleted
Console.WriteLine($"Sucesso: {result}");
}
After installing the NuGet, just create an instance of MyCouch.Client and pass it the URL of your database.
using (var client = new MyCouchClient("http://127.0.0.1:5984/test"))
{
//Consume here
}
The format is: {scheme}://[{username}:{password}]/{authority}/{localpath}. From v0.11.0, there's a specific MyCouchUriBuilder that you can use for building the Uri. It will automatically e.g. apply Uri.EscapeDataString to username and password when calling SetBasicCredentials.
var uriBuilder = new MyCouchUriBuilder("http://localhost:5984/")
.SetDbName(TestConstants.TestDbName)
.SetBasicCredentials("foob#r", "p#ssword");
return new MyCouchClient(uriBuilder.Build());
For more details Click Here

Categories

Resources