Storage account deployed from ARMTemplate is creating diagnostic settings as disabled.
How to enable diagnostics status using ARMTemplate or Powershell script?
Want to automate the process to deploy diagnostic settings.
Here is a solution using ARM templates in the newer Bicep format. In the example, it configures diagnostics settings for:
StorageAccount
Blob
File
Queue
Table
To reduce the template length, it configures only the StorageRead on the storage account services.
param name string
param location string = resourceGroup().location
param sku string
#description('Resource ID for the destination log analytics workspace.')
param logAnalyticsWorkspaceId string
resource storageAccount 'Microsoft.Storage/storageAccounts#2019-06-01' = {
name: name
location: location
kind: 'StorageV2'
sku: {
name: sku
}
properties: {
allowBlobPublicAccess: false
allowSharedKeyAccess: true
minimumTlsVersion: 'TLS1_2'
accessTier: 'Hot'
supportsHttpsTrafficOnly: true
networkAcls: {
defaultAction: 'Deny'
bypass: 'AzureServices'
}
}
}
resource diagnosticsStorage 'Microsoft.Insights/diagnosticSettings#2021-05-01-preview' = {
scope: storageAccount
name: 'diagnostics00'
properties: {
workspaceId: logAnalyticsWorkspaceId
metrics: [
{
category: 'Transaction'
enabled: true
}
]
}
}
resource blobService 'Microsoft.Storage/storageAccounts/blobServices#2021-06-01' = {
parent: storageAccount
name: 'default'
properties: {}
}
resource diagnosticsBlob 'Microsoft.Insights/diagnosticSettings#2021-05-01-preview' = {
scope: blobService
name: 'diagnostics00'
properties: {
workspaceId: logAnalyticsWorkspaceId
logs: [
{
category: 'StorageRead'
enabled: true
}
]
}
}
resource fileService 'Microsoft.Storage/storageAccounts/fileServices#2021-06-01' = {
parent: storageAccount
name: 'default'
properties: {}
}
resource diagnosticsFile 'Microsoft.Insights/diagnosticSettings#2021-05-01-preview' = {
scope: fileService
name: 'diagnostics00'
properties: {
workspaceId: logAnalyticsWorkspaceId
logs: [
{
category: 'StorageRead'
enabled: true
}
]
}
}
resource queueService 'Microsoft.Storage/storageAccounts/queueServices#2021-06-01' = {
parent: storageAccount
name: 'default'
properties: {}
}
resource diagnosticsQueue 'Microsoft.Insights/diagnosticSettings#2021-05-01-preview' = {
scope: queueService
name: 'diagnostics00'
properties: {
workspaceId: logAnalyticsWorkspaceId
logs: [
{
category: 'StorageRead'
enabled: true
}
]
}
}
resource tableService 'Microsoft.Storage/storageAccounts/tableServices#2021-06-01' = {
parent: storageAccount
name: 'default'
properties: {}
}
resource diagnosticsTable 'Microsoft.Insights/diagnosticSettings#2021-05-01-preview' = {
scope: tableService
name: 'diagnostics00'
properties: {
workspaceId: logAnalyticsWorkspaceId
logs: [
{
category: 'StorageRead'
enabled: true
}
]
}
}
Please follow the below URL to enable the Diagnostics Settings for Azure Storage Account using ARM Template:
https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/resource-manager-diagnostic-settings#diagnostic-setting-for-azure-storage
Related
I'm trying to generate Web API Service from yaml
openapi: 3.0.1
info:
title: ""
description: ''
license:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
version: 1.0.0
servers:
- url: http://localhost:3001
tags:
- name: user
description: Operations with users
- name: stream
description: Operation with streams
paths:
/user/register:
post:
x-vertx-event-bus: user_manager.myapp
tags:
- user
summary: Create user
operationId: createUser
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UserEnter'
required: true
responses:
'200':
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'400':
description: Invalid phone number
content: {}
x-codegen-request-body-name: body
components:
schemas:
UserEnter:
type: object
properties:
phone:
type: integer
format: int32
password:
type: string
additionalProperties: false
required:
- phone
- password
UserService.kt:
#WebApiServiceGen
interface UserService {
#GenIgnore
companion object{
#JvmStatic
fun create(repository: Repository): UserServiceImpl {
return UserServiceImpl(repository)
}
}
fun createUser(userEnter: UserEnter, request: ServiceRequest, resultHandler: Handler<AsyncResult<ServiceResponse>>)
}
UserEnter.kt:
#DataObject(generateConverter = true, publicConverter = false)
class UserEnter {
var phone: Int = 0
var password: String
constructor(phone: Int, password: String){
this.phone = phone
this.password = password
}
constructor(json: JsonObject): this(
json.getInteger("phone", 0),
json.getString("password", ""),
)
fun toJson(): JsonObject {
return JsonObject.mapFrom(this)
}
}
I'm trying to post the data:
{
"phone": 23423423423,
"password": "enim ut"
}
But the server expects this type of data:
"userEnter": {
{
"phone": 23423423423,
"password": "enim ut"
}
}
The part of generated UserServiceVertxProxyHandler.java:
case "createUser": {
JsonObject contextSerialized = json.getJsonObject("context");
if (contextSerialized == null)
throw new IllegalStateException("Received action " + action + " without ServiceRequest \"context\"");
ServiceRequest context = new ServiceRequest(contextSerialized);
JsonObject params = context.getParams();
try {
service.createUser(
searchOptionalInJson(params, "userEnter").map(j -> (io.vertx.core.json.JsonObject)j).map(j -> new com.md.model.user.UserEnter(j)).orElse(null),
context,
res -> {
if (res.failed()) {
if (res.cause() instanceof ServiceException) {
msg.reply(res.cause());
} else {
msg.reply(new ServiceException(-1, res.cause().getMessage()));
}
} else {
msg.reply(res.result() == null ? null : res.result().toJson());
}
}
);
} catch (Exception e) {
HelperUtils.manageFailure(msg, e, includeDebugInfo);
}
break;
}
Gradle:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm") version "1.6.21"
kotlin("kapt") version "1.7.0"
application
}
group = "com.md"
version = "1.0-SNAPSHOT"
repositories {
mavenCentral()
google()
}
dependencies {
kapt("io.vertx:vertx-codegen:4.3.1:processor")
kapt("io.vertx:vertx-web-api-service:4.3.1")
implementation("io.vertx:vertx-core:4.3.1")
implementation("io.vertx:vertx-web:4.3.1")
implementation("io.vertx:vertx-web-validation:4.3.1")
implementation("io.vertx:vertx-web-openapi:4.3.1")
implementation("io.vertx:vertx-service-proxy:4.3.1")
implementation("io.vertx:vertx-web-api-service:4.3.1")
compileOnly("io.vertx:vertx-codegen:4.3.1")
implementation("io.vertx:vertx-mongo-client:4.3.1")
implementation("org.slf4j:jcl-over-slf4j:1.7.36")
implementation("ch.qos.logback:logback-classic:1.2.11")
testImplementation(kotlin("test"))
}
tasks.test {
useJUnitPlatform()
}
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
}
application {
mainClass.set("MainKt")
}
What I’m doing wrong? I’ve made all like in this example: https://github.com/vert-x3/vertx-examples/tree/4.x/web-api-service-example/src/main/java/io/vertx/examples/webapiservice
My YAML file is correct, I’ve generated the kotlin-client on https://editor.swagger.io and it sends:
{
"phone": 23423423423,
"password": "enim ut"
}
Situation:
I am deploying a Synapse workspace instance in Bicep with Managed Virtual Network Enabled.
I can see the Managed Vnet Is enabled from the UI:
However, when I enter the workspace my integration runtimes are not enabled for virtual network access and I cannot create managed private endpoints.
I'm writing the following code for the bicep deployment:
resource synapse_workspace 'Microsoft.Synapse/workspaces#2021-06-01' = {
name: synapse_workspace_name
location: location
tags: {
Workload: '####'
Environment: envName
Classification: 'Confidential'
Criticality: 'Low'
}
identity: {
type: 'SystemAssigned'
}
properties: {
// Git Repo
workspaceRepositoryConfiguration: {
accountName: '#####'
collaborationBranch: 'main'
projectName: '####'
repositoryName: '#############'
rootFolder: '/synapse/syn-data-${envName}'
tenantId: '####################'
type: 'WorkspaceVSTSConfiguration'
}
defaultDataLakeStorage: {
resourceId: storage_account_id
createManagedPrivateEndpoint: true
accountUrl: ###################
filesystem: ################
}
encryption: {
cmk: {
kekIdentity: {
useSystemAssignedIdentity: true
}
key: {
name: 'default'
keyVaultUrl: '#########################'
}
}
}
managedVirtualNetwork: 'default'
connectivityEndpoints: {
web: 'https://web.azuresynapse.net?workspace=%2fsubscriptions%######################
dev: 'https://##############.dev.azuresynapse.net'
sqlOnDemand: '################-ondemand.sql.azuresynapse.net'
sql: '################.sql.azuresynapse.net'
}
managedResourceGroupName: guid('synapseworkspace-managed-resource-group-${envName}')
sqlAdministratorLogin: 'sqladminuser'
privateEndpointConnections: []
managedVirtualNetworkSettings: {
preventDataExfiltration: true
allowedAadTenantIdsForLinking: []
}
publicNetworkAccess: 'Disabled'
cspWorkspaceAdminProperties: {
initialWorkspaceAdminObjectId: '#########################'
}
trustedServiceBypassEnabled: false
}
}
I get no errors in the deployment regarding the virtual network or any associated settings, but I still get the default integration runtime set to "Public" and not "Managed Virtual Network".
Is this a limitation in Bicep or am I missing some parameter?
Any help would be great
Joao
I am currently running the 7 nodes example given in quorum-examples github repo. I have deployed a very simple storage contract which gets and sets the value. As per the example, I am able to interact with the smart contract inside the geth node cmd line. However I would like to interact with it using another address outside the node and so I wrote the following code:
const Web3 = require('web3')
const web3 = new Web3(new Web3.providers.HttpProvider('http://127.0.0.1:22000'))
const { Transaction } = require('#ethereumjs/tx')
const { default: Common } = require('#ethereumjs/common')
const run = async () => {
const contractInstance = await new web3.eth.Contract(
[
{
constant: true,
inputs: [],
name: 'storedData',
outputs: [{ name: '', type: 'uint256' }],
payable: false,
type: 'function',
},
{
constant: false,
inputs: [{ name: 'x', type: 'uint256' }],
name: 'set',
outputs: [],
payable: false,
type: 'function',
},
{
constant: true,
inputs: [],
name: 'get',
outputs: [{ name: 'retVal', type: 'uint256' }],
payable: false,
type: 'function',
},
{
inputs: [{ name: 'initVal', type: 'uint256' }],
payable: false,
type: 'constructor',
},
],
'0xd9d64b7dc034fafdba5dc2902875a67b5d586420'
)
const customCommon = Common.forCustomChain('mainnet', {
chainId: 10,
})
const txCount = await web3.eth.getTransactionCount(
'ed9d02e382b34818e88b88a309c7fe71e65f419d'
)
const txData = {
nonce: web3.utils.toHex(txCount),
gasLimit: '0x47b760',
gasPrice: '0x00',
value: '0x0',
chainId: 10,
to: '0xd9d64b7dc034fafdba5dc2902875a67b5d586420',
data: contractInstance.methods.set(10).encodeABI(),
}
const tx = Transaction.fromTxData(txData, { common: customCommon })
const signedTx = tx.sign(
Buffer.from(
'e6181caaffff94a09d7e332fc8da9884d99902c7874eb74354bdcadf411929f1',
'hex'
)
)
const serializedTx = signedTx.serialize()
const result = await web3.eth.sendSignedTransaction(
`0x${serializedTx.toString('hex')}`
)
return result
}
run().then(console.log).catch(console.log)
However whenever I try to send the transtion, it always errors out to
"Transaction has been reverted by the EVM:\n{\n \"blockHash\": \"0xd6b06321882912185f5e1d3401a012f58b6bbf7eee1e1d2c6c2cd80a0e13bbdc\",\n \"blockNumber\": 5,\n \"contractAddress\": null,\n \"cumulativeGasUsed\": 23751,\n \"from\": \"0x0fbdc686b912d7722dc86510934589e0aaf3b55a\",\n \"gasUsed\": 23751,\n \"logs\": [],\n \"logsBloom\": \"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\n \"status\": false,\n \"to\": \"0x9d13c6d3afe1721beef56b55d303b09e021e27ab\",\n \"transactionHash\": \"0x8c7fd175ab037e24e531804774e8b89bf5aea25de8d99aa9bc2c034229603299\",\n \"transactionIndex\": 0\n}",
Do let me know if more info is required and I will update the post.
The smartcontract code is as follows:
pragma solidity ^0.5.0;
contract simplestorage {
uint public storedData;
constructor(uint initVal) public {
storedData = initVal;
}
function set(uint x) public {
storedData = x;
}
function get() view public returns (uint retVal) {
return storedData;
}
}
I think i met the similar issue as well. My issue was invalid chain id signer. I checked many docs and tried to set the custom chain id which was what you did about "common". But nothing changed until i changed the version of ethereumjs-tx to ^1.3.7. btw you dont need common if you try my solution.
I have a (correctly working) workflow script starting with this guard function:
var entities = require('#jetbrains/youtrack-scripting-api/entities');
exports.rule = entities.Issue.action({
title: 'Create default subtasks',
command: 'tt-create-subtasks',
guard: function(ctx) {
return ctx.issue.fields.Type.name == 'User Story';
},
I thought I would replace that with something like
return ctx.issue.fields.Type == UserStory;
and therefore change the requirements from:
requirements: {
Type: {
type: entities.EnumField.fieldType,
Task: {},
}
}
to:
requirements: {
Type: {
type: entities.EnumField.fieldType,
Task: {},
UserStory: {
name: 'User Story'
}
}
}
Task is used elsewhere in a similar fashion and that works:
newIssue.fields.Type = ctx.Type.Task;
But the editor gives red errors on UserStory in the giard function. Am I doing something wrong in the requirements?
If you declare the requirements like you described
requirements: {
Type: {
type: entities.EnumField.fieldType,
Task: {},
UserStory: {
name: 'User Story'
}
}
}
you'll be able to check the value the following way: issue.fields.is(ctx.Type, ctx.Type.UserStory).
My NestJS server has an endpoint that accepts files and also additional form data
For example I pass a file and a user_id of the file creator in the form.
NestJS Swagger needs to be told explicitly that body contains the file and that the endpoint consumes multipart/form-data this is not documented in the NestJS docs https://docs.nestjs.com/openapi/types-and-parameters#types-and-parameters.
Luckily some bugs led to discussion about how to handle this use case
looking at these two discussions
https://github.com/nestjs/swagger/issues/167
https://github.com/nestjs/swagger/issues/417
I was able to put together the following
I have added annotation using a DTO:
the two critical parts are:
in the DTO add
#ApiProperty({
type: 'file',
properties: {
file: {
type: 'string',
format: 'binary',
},
},
})
public readonly file: any;
#IsString()
public readonly user_id: string;
in the controller add
#ApiConsumes('multipart/form-data')
this gets me a working endpoint
and this OpenAPI Json
{
"/users/files":{
"post":{
"operationId":"UsersController_addPrivateFile",
"summary":"...",
"parameters":[
],
"requestBody":{
"required":true,
"content":{
"multipart/form-data":{
"schema":{
"$ref":"#/components/schemas/UploadFileDto"
}
}
}
}
}
}
}
...
{
"UploadFileDto":{
"type":"object",
"properties":{
"file":{
"type":"file",
"properties":{
"file":{
"type":"string",
"format":"binary"
}
},
"description":"...",
"example":"'file': <any-kind-of-binary-file>"
},
"user_id":{
"type":"string",
"description":"...",
"example":"cus_IPqRS333voIGbS"
}
},
"required":[
"file",
"user_id"
]
}
}
Here is what I find a cleaner Approach:
#Injectable()
class FileToBodyInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const ctx = context.switchToHttp();
const req = ctx.getRequest();
if(req.body && req.file?.fieldname) {
const { fieldname } = req.file;
if(!req.body[fieldname]) {
req.body[fieldname] = req.file;
}
}
return next
.handle();
}
}
const ApiFile = (options?: ApiPropertyOptions): PropertyDecorator => (
target: Object, propertyKey: string | symbol
) => {
ApiProperty({
type: 'file',
properties: {
[propertyKey]: {
type: 'string',
format: 'binary',
},
},
})(target, propertyKey);
};
class UserImageDTO {
#ApiFile()
file: Express.Multer.File; // you can name it something else like image or photo
#ApiProperty()
user_id: string;
}
#Controller('users')
export class UsersController {
#ApiBody({ type: UserImageDTO })
// #ApiResponse( { type: ... } ) // some dto to annotate the response
#Post('files')
#ApiConsumes('multipart/form-data')
#UseInterceptors(
FileInterceptor('file'), //this should match the file property name
FileToBodyInterceptor, // this is to inject the file into the body object
)
async addFile(#Body() userImage: UserImageDTO): Promise<void> { // if you return something to the client put it here
console.log({modelImage}); // all the fields and the file
console.log(userImage.file); // the file is here
// ... your logic
}
}
FileToBodyInterceptor and ApiFile are general, I wish they where in the NestJs
You probably need to install #types/multer to have to Express.Multer.File