Just initialize this new branch for Cohesity internal collaboration/r… - #2
Just initialize this new branch for Cohesity internal collaboration/r…#2yinghuang123 wants to merge 343 commits into
Conversation
eerus
left a comment
There was a problem hiding this comment.
@yinghuang123 , I finished my review. Please submit changes before you submit another round of reviews to Microsoft.
@ishitagupta25 , please chime in, too. In a few comments I specifically tagged you if I think that you should do the change.
| * need to rewrite GetAccessTokenAsync function | ||
| * as it uses obsolete technology to get the bearer token. | ||
| */ | ||
| internal async Task<string> GetAccessTokenAsync(string uri) |
There was a problem hiding this comment.
Rewrite GetAccessTokenAsync function as it uses obsolete technology to get the bearer token. Here's the migration guide to new authentication functions. Please remember that the new authentication mechanism may nit need TenantID, ClientID and and ClientKey, so you'll also have to apply changes in local.settings.json and the corresponding ARM templates.
There was a problem hiding this comment.
put this one to lower priority.
There was a problem hiding this comment.
You can also check how other pieces of code authenticate, e.g. https://github.com/cohesity/Azure-Sentinel/blob/CohesitySecurity.internal/Tools/Sample%20Code/AzureSentinel-ManagementAPICsharp/AzureSentinel_ManagementAPI/Incidents/IncidentsController.cs.
Also, check how we can put all secrets to the KeyVault to enable key rotation (see example at https://github.com/cohesity/Azure-Sentinel/tree/CohesitySecurity.internal/DataConnectors/AzureStorage#readme)
eerus
left a comment
There was a problem hiding this comment.
Deleted comments about pre-built binaries
8463ba0 to
2bb8bdb
Compare
eerus
left a comment
There was a problem hiding this comment.
@yinghuang123 , I walked through your changes. The code definitely looks better in terms of handling exceptions and parallelism. I left only a few comments.
| log.LogError("URI --> " + URI); | ||
| log.LogError("body --> " + body); | ||
| log.LogError("ex --> " + ex.Message); | ||
| throw new Exception(); |
There was a problem hiding this comment.
Move it outside of the catch block, i.e. outside of the exception handler. Place it after the line 71. This way, it'll be clearer that you're intentionally re-throwing the exception if the code didn't reach ln 63: return result. Also, it'd be great to explain in the comments why you're doing it and how to customize your queue wait and retry times.
| } | ||
|
|
||
| [FunctionName("IncidentConsumer")] | ||
| [FixedDelayRetry(5, "00:05:00")] |
There was a problem hiding this comment.
I'd move these parameters to host.json file together with other settings (see my another comment in host.json).
eerus
left a comment
There was a problem hiding this comment.
Please address the comment about exposing extra-parameters and then please switch to updating the Restore From Last Snapshot playbook.
Other comments can be addressed later.
| "CohesityQueueName": "your CohesityQueueName", | ||
| "DefaultEndpointsProtocol": "your DefaultEndpointsProtocol", | ||
| "AccountKey": "your AccountKey", | ||
| "BlobEndpoint": "https://127.0.0.1:10000/devstoreaccount1", |
There was a problem hiding this comment.
I don't think that you use the following parameters anywhere.
- "BlobEndpoint": "https://127.0.0.1:10000/devstoreaccount1"
- "QueueEndpoint": "https://127.0.0.1:10001/devstoreaccount1"
- "TableEndpoint": "https://127.0.0.1:10002/devstoreaccount1"
Please remove them.
| "IsEncrypted": false, | ||
| "Values": { | ||
| "AzureWebJobsStorage": "UseDevelopmentStorage=true", | ||
| "apiKey": "11111111-2222-3333-4444-555555555555", |
There was a problem hiding this comment.
Come up with a single standard for naming variables and stick to it. For ex, apiKey is written in camel case starting from the lowercase letter, while CohesityQueueName starts from the uppercase letter.
| } | ||
| else | ||
| { | ||
| throw new InvalidProgramException("Invalid format string"); |
There was a problem hiding this comment.
Make the error message clearer and more specific, e.g. "Invalid storage connection string."
| try | ||
| { | ||
| const string container = "extra-parameters"; | ||
| string Blob = incidentID + "\\" + param; // ID unique to the incident |
There was a problem hiding this comment.
Nit: Come up with a single way for variable naming and stick to it. For ex, Blob starts from the uppercase letter and blobStorageKeys from the lowercase one.
There was a problem hiding this comment.
These 2 variables can be made class variables and can be initialized only once in RunAsync. There's no need to re-initialize them every time in every function call as they never change.
var blobStorageConnectionString = Environment.GetEnvironmentVariable("BlobStorageConnectionString");
var blobStorageKeys = Environment.GetEnvironmentVariable("BlobStorageAccountKeys");
There was a problem hiding this comment.
Also, after your remove the variables above to a different place, will you still need TextWriter function for just 2 lines of code? Probably, it'd be better to remove the function and just directly call
WriteData(incidentID + "\\" + param, value);
|
|
||
| foreach (var alert in alerts) | ||
| { | ||
| await ParseAlertToQueueAsync(outputQueueItem, alert, log); |
There was a problem hiding this comment.
Why are you doing it sequentially now? There was a code here that did all iterations in parallel.
| else | ||
| output.properties.severity = "Medium"; | ||
| break; | ||
| case 0: |
There was a problem hiding this comment.
Nit: Sort the case statements in ascending order for a better readability, like this
case 0:
case 4:
case 7:
case 10:
case 11:
| { | ||
| switch (i) | ||
| { | ||
| case 12: |
There was a problem hiding this comment.
Nit: For a better readability, put case 12 statement to the end of switch as it's easier to read when the values go in ascending order, especially if we plan to extend the amount of extra info.
| { | ||
| try | ||
| { | ||
| const string container = "extra-parameters"; |
There was a problem hiding this comment.
The container name can't be hardcoded as users are supposed to create it prior deployment.
- Create an environment variable with the container name. Make the default value equal to "cohesity-extra-parameters".
- Make sure that the corresponding playbooks are getting it as a parameter as well.
- The corresponding readme-files should be updated with the instructions about creating containers and entering container names during deployment.
I also think that this constant can be initialized only once, e.g. in RunAsync or when the object is created. You can make it a class variable as there's no need to re-initialize it multiple times with every function call.
| { | ||
| var db = Connection.GetDatabase(); | ||
| string apiKey = Environment.GetEnvironmentVariable("apiKey"); | ||
| string redisKey = Environment.GetEnvironmentVariable("workspace") + apiKey; |
There was a problem hiding this comment.
With introducing the storage blob we don't really need storing timestamps in Redis anymore. We can re-use the same container and create there a separate blob with the name equal to Environment.GetEnvironmentVariable("workspace") + apiKey.
It'll reduce monthly bill for the customer.
eerus
left a comment
There was a problem hiding this comment.
Everything looks good. I left a few more nit comments.
| } | ||
| } | ||
|
|
||
| private static void WriteData(string storageConnectionString, string path, string data) |
There was a problem hiding this comment.
storageConnectionString doesn't change. There's no need to pass it all the time. You can get the value only once at the object creation time or in RunAsync.
private static void WriteData(string path, string data)
| { | ||
| if (CloudStorageAccount.TryParse(storageConnectionString, out var storageAccount)) | ||
| { | ||
| var cloudBlobClient = storageAccount.CreateCloudBlobClient(); |
There was a problem hiding this comment.
The values of these variables don't change much. You can easily set them up during object initialization or in RunAsync.
var cloudBlobClient = storageAccount.CreateCloudBlobClient();
var container = cloudBlobClient.GetContainerReference(containerName);
| try | ||
| { | ||
| const string container = "extra-parameters"; | ||
| string Blob = incidentID + "\\" + param; // ID unique to the incident |
There was a problem hiding this comment.
Also, after your remove the variables above to a different place, will you still need TextWriter function for just 2 lines of code? Probably, it'd be better to remove the function and just directly call
WriteData(incidentID + "\\" + param, value);
Added specific name for the vault
Added specific name for the playbook
- Fixed broken links - Added info about the Cohesity Close Helios Incident playbook - Did some formatting
- Replaced Helios with DataHawk + a few other formatting changes.
- Added info about creating an automation trigger for closing SNOW tickets
Add info about skipping steps if the API key is already stored in the vault.
Typo.
Fixed broken links
Fixed broken links
Fixed broken links
Added connection authorization instructions
Added instructions about connection authorization
Test Azure func deploy
Initial version of the IncidentProducer Function App
./Solutions/CohesitySecurity/Playbooks/Cohesity_Close_Helios_Incident/azuredeploy.json
./Solutions/CohesitySecurity/Playbooks/Cohesity_CreateOrUpdate_ServiceNow_Incident/azuredeploy.json
+++ ./Solutions/CohesitySecurity/Package/createUiDefinition.json +++ ./Solutions/CohesitySecurity/Package/mainTemplate.json
Returned the reference to the Restore playbook
add Anomaly Strength in description re-organize the codes
eerus
left a comment
There was a problem hiding this comment.
Added a few optimization suggestions after getting rid of Redis.
| { | ||
| if (CloudStorageAccount.TryParse(blobStorageConnectionString, out var storageAccount)) | ||
| { | ||
| var cloudBlobClient = storageAccount.CreateCloudBlobClient(); |
There was a problem hiding this comment.
The values for both of these variables never change after initialization. It's worth putting them outside of the function
var cloudBlobClient = storageAccount.CreateCloudBlobClient();
var container = cloudBlobClient.GetContainerReference(containerName);
|
|
||
| private static void TextWriter(string incidentID, string param, string value, ILogger log) | ||
| { | ||
| WriteData(incidentID + "\\" + param, value, log); |
There was a problem hiding this comment.
It doesn't make sense to have a one-line function, TextWriter. Call WriteData directly.
| "AzureWebJobsStorage": "UseDevelopmentStorage=true", | ||
| "apiKey": "11111111-2222-3333-4444-555555555555", | ||
| "startDaysAgo": "-30", | ||
| "connectStr": "your azure redis cache connection string", |
There was a problem hiding this comment.
Remove it as you don't have Redis dependency anymore.
| "workspace": "your instance name", | ||
| "CohesityQueueName": "your CohesityQueueName", | ||
| "DefaultEndpointsProtocol": "your DefaultEndpointsProtocol", | ||
| "AccountKey": "your AccountKey", |
There was a problem hiding this comment.
Where do you use it? Remove it if you don't.
| "DefaultEndpointsProtocol": "your DefaultEndpointsProtocol", | ||
| "AccountKey": "your AccountKey", | ||
| "BlobStorageConnectionString": "your BlobStorageConnectionString", | ||
| "BlobStorageAccountKeys": "your BlobStorageAccountKeys", |
There was a problem hiding this comment.
Where do you use it? Remove it if you don't.
eerus
left a comment
There was a problem hiding this comment.
New comments about redundant env variables
| { | ||
| private static readonly object queueLock = new object(); | ||
| private static Lazy<ConnectionMultiplexer> lazyConnection = CreateConnection(); | ||
| private static string containerName = Environment.GetEnvironmentVariable("containerName"); |
There was a problem hiding this comment.
There's no need to take it from the environment as it's created by deployment wizard and never changed. Set it equal to "cohesity-extra-parameters"
There was a problem hiding this comment.
so, you means this change?
- private static string containerName = GetSecret("containerName");
+ private static string containerName = "cohesity-extra-parameters";
There was a problem hiding this comment.
Yes, but also can you move shared constants and functions to one place, so both producer and consumer can use them. For ex, you can create a shared library for it or reference from both projects.
eerus
left a comment
There was a problem hiding this comment.
Thoughts on queue name to simplify deployment configs
| } | ||
|
|
||
| [FunctionName("IncidentConsumer")] | ||
| public void Run([QueueTrigger("%CohesityQueueName%", Connection = "AzureWebJobsStorage")]string queueItem, ILogger log) |
There was a problem hiding this comment.
Why did we decide to put the queue name to the environment variable? If the deployment wizard creates a storage account with a unique name, then we can just have a common constant between producer and consumer for the queue name
There was a problem hiding this comment.
Here you can create a shared constant "cohesity-incidents" that both projects have access to.
| } | ||
|
|
||
| public static async Task ParseAlertToQueue( | ||
| [Queue("%CohesityQueueName%"), StorageAccount("AzureWebJobsStorage")] ICollector<string> outputQueueItem, |
There was a problem hiding this comment.
Why did we decide to put the queue name to the environment variable? If the deployment wizard creates a storage account with a unique name, then we can just have a common constant between producer and consumer for the queue name
ARM template for deploying both Azure functions.
…torUpdate Updated azuredeploy template of Rubrik Data Connector to prevent public access and cross tenant replicaion in storage account
Update ingestASimSampleData.py
Bumps [System.Text.Json](https://github.com/dotnet/runtime) from 8.0.4 to 8.0.5. - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](dotnet/runtime@v8.0.4...v8.0.5) --- updated-dependencies: - dependency-name: System.Text.Json dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com>
Fixing "Invalid Login Endpoint" issue
Added TeamCymruScout Solution
…ure-function-v4 Cybersixgill Actionable Alerts Python Version Upgrade
…tors/O365-DataCSharp/Teams.CustomConnector.StorageHandler/System.Text.Json-8.0.5 Bump System.Text.Json from 8.0.4 to 8.0.5 in /DataConnectors/O365 DataCSharp/Teams.CustomConnector.StorageHandler
Updated code to fix the bug in CrowdStrike Replicator V2
…eview.
Required items, please complete
Change(s):
Reason for Change(s):
Version Updated:
Testing Completed:
Checked that the validations are passing and have addressed any issues that are present:
Guidance <- remove section before submitting
Before submitting this PR please ensure that you have read the following sections and filled out the changes, reason for change and testing complete sections:
Thank you for your contribution to the Microsoft Sentinel Github repo.
Change(s):
Reason for Change(s):
Version updated:
Testing Completed:
Note: If updating a detection, you must update the version field.
Checked that the validations are passing and have addressed any issues that are present:
Note: Let us know if you have tried fixing the validation error and need help.