Skip to content

Commit 1e2916c

Browse files
Generated session id, Updated the user profile and refreshed the id if expired
1 parent 32b5585 commit 1e2916c

File tree

5 files changed

+228
-10
lines changed

5 files changed

+228
-10
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ bld/
2424

2525
# Visual Studio 2015 cache/options directory
2626
.vs/
27+
.vscode/
2728
# Uncomment if you have tasks that create the project's static files in wwwroot
2829
#wwwroot/
2930

src/Cohesity.Powershell/Cmdlets/Cluster/ConnectCohesityCluster.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,14 +219,13 @@ protected override void ProcessRecord()
219219
SessionId = this.SessionId
220220
};
221221
userProfileProvider.SetUserProfile(userProfile);
222+
223+
222224
if (SessionIdAdapter.ValidateSessionId(this.Server, this.SessionId))
223225
{
224226
WriteObject($"Connected to the Cohesity Cluster {Server} Successfully");
225227
return;
226228
}
227-
userProfileProvider.DeleteUserProfile();
228-
WriteObject("Failed to connect to the Cohesity Cluster.");
229-
return;
230229
}
231230

232231
var networkCredential = Credential.GetNetworkCredential();

src/Cohesity.Powershell/Cohesity.PowerShell.psd1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ FunctionsToExport = @(
112112
'New-CohesityPhysicalServerProtectionJob'
113113
'New-CohesityProtectionPolicy',
114114
'New-CohesityRoutes',
115+
'New-CohesitySessionId',
115116
'New-CohesityStorageDomain',
116117
'New-CohesityUserGroup',
117118
'New-CohesityVirtualIP',
Lines changed: 100 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,117 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4+
using System.Net;
5+
using System.Net.Http;
46
using System.Text;
5-
using System.Threading.Tasks;
7+
using Cohesity.Model;
8+
using Newtonsoft.Json;
69

710
namespace Cohesity.Powershell.Common
811
{
912
class SessionIdAdapter
1013
{
11-
static public bool ValidateSessionId(string server, string sessionId)
14+
public static bool ValidateSessionId(string server, string sessionId)
1215
{
13-
Session session = new Session();
16+
var session = new Session();
1417
var preparedUrl = $"/public/users";
15-
var result = session.ApiClient.Get<IEnumerable<Model.User>>(preparedUrl);
16-
ICollection<Model.User> users = result as ICollection<Model.User>;
17-
if (users.Count == 0)
18+
19+
try
20+
{
21+
var result = session.ApiClient.Get<IEnumerable<Model.User>>(preparedUrl);
22+
if (result is ICollection<Model.User> users && users.Count > 0)
23+
{
24+
return true;
25+
}
26+
}
27+
catch (Exception ex)
1828
{
29+
Console.WriteLine("Exception during session regeneration: " + ex.Message);
30+
}
31+
32+
return TryRegenerateSessionId(server);
33+
}
34+
35+
private static bool TryRegenerateSessionId(string server)
36+
{
37+
var userProfileProvider = ServiceLocator.GetUserProfileProvider();
38+
var userProfile = userProfileProvider.GetUserProfile();
39+
var credentials = userProfileProvider.GetCredentials();
40+
41+
if (userProfile == null || credentials == null || userProfile.ClusterUri == null)
42+
{
43+
Console.WriteLine("Missing profile or credentials.");
1944
return false;
2045
}
21-
return true;
46+
47+
try
48+
{
49+
var requestBody = new
50+
{
51+
username = credentials.Username,
52+
password = credentials.Password
53+
};
54+
55+
var clusterUri = userProfile.ClusterUri.ToString();
56+
if (clusterUri.Contains("/irisservices/api/v1"))
57+
{
58+
clusterUri = clusterUri.Replace("/irisservices/api/v1", "");
59+
}
60+
61+
var baseUri = new Uri(clusterUri);
62+
var apiUri = new Uri(baseUri, "v2/users/sessions");
63+
64+
var httpRequest = new HttpRequestMessage(HttpMethod.Post, apiUri)
65+
{
66+
Content = new StringContent(JsonConvert.SerializeObject(requestBody), Encoding.UTF8, "application/json")
67+
};
68+
69+
var httpClient = new RestApiClient().BuildClient(userProfile.ClusterUri, true);
70+
71+
72+
73+
var response = httpClient.SendAsync(httpRequest).Result;
74+
var content = response.Content.ReadAsStringAsync().Result;
75+
76+
if (response.StatusCode == HttpStatusCode.Created)
77+
{
78+
var sessionResponse = JsonConvert.DeserializeObject<SessionIdResponse>(content);
79+
userProfile.SessionId = sessionResponse.SessionId;
80+
userProfileProvider.SetUserProfile(userProfile);
81+
82+
Console.WriteLine("Session ID successfully regenerated.");
83+
84+
// Retry validation
85+
var session = new Session();
86+
var users = session.ApiClient.Get<IEnumerable<Model.User>>("/public/users");
87+
return users != null && users.Any();
88+
}
89+
else
90+
{
91+
Console.WriteLine("Failed to regenerate session ID: " + content);
92+
}
93+
}
94+
catch (Exception ex)
95+
{
96+
StringBuilder sb = new StringBuilder();
97+
sb.AppendLine("Failed to connect to the Cohesity Cluster");
98+
sb.AppendLine(ex.Message);
99+
throw new Exception(sb.ToString());
100+
}
101+
102+
return false;
22103
}
23104
}
105+
106+
/// <summary>
107+
/// Represents the response from the Cohesity API containing the session ID.
108+
/// </summary>
109+
public class SessionIdResponse
110+
{
111+
/// <summary>
112+
/// The session ID returned by the Cohesity API after successful authentication.
113+
/// </summary>
114+
[JsonProperty("sessionId")]
115+
public string SessionId { get; set; }
116+
}
24117
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
$Global:CohesityUserAgentName = $null
2+
$Global:CohesityAPIError = $null
3+
4+
# Allow the caller to have access to response object,
5+
# it is observed that some of the REST APIs (PUT method) do not return object,
6+
# therefore provisioning an object, so that the caller can identify using the status code, if the API call succeeded
7+
# Capture all response codes and the relevant error messages.
8+
$Global:CohesityAPIStatus = $null
9+
10+
function New-CohesitySessionId {
11+
<#
12+
.SYNOPSIS
13+
Returns the session ID For the user
14+
.DESCRIPTION
15+
Create the user session
16+
.NOTES
17+
Published by Cohesity
18+
.LINK
19+
https://cohesity.github.io/cohesity-powershell-module/#/README
20+
.EXAMPLE
21+
New-CohesitySessionId -Server 10.0.0.1 -Credential (Get-Credential)
22+
#>
23+
[CmdletBinding()]
24+
Param (
25+
[Parameter(Mandatory = $true)]
26+
[string[]]$Server,
27+
28+
[Parameter(Mandatory = $true)]
29+
[PSCredential]$Credential,
30+
31+
[Parameter(Mandatory = $false)]
32+
[string]$Domain = "LOCAL", # default domain
33+
34+
[Parameter(Mandatory = $false)]
35+
[string]$OtpCode,
36+
37+
[Parameter(Mandatory = $false)]
38+
[string]$OtpType
39+
)
40+
Enable-SelfSignedCertificates
41+
if ($null -eq $Global:CohesityCmdletConfig) {
42+
$Global:CohesityCmdletConfig = Get-CohesityCmdletConfig
43+
}
44+
45+
46+
$Global:CohesityAPIError = $null
47+
try {
48+
$username = $Credential.UserName
49+
$password = $Credential.GetNetworkCredential().Password
50+
51+
$cohesitycredentials = @{
52+
otpType = "Totp"
53+
certificate = $null
54+
domain = "LOCAL"
55+
otpCode = $null
56+
password = $password
57+
privateKey = $null
58+
username =$username
59+
}
60+
$jsonProfile = $cohesitycredentials | ConvertTo-Json -Compress -Depth 5
61+
62+
[Environment]::SetEnvironmentVariable("cohesityCredentials", $jsonProfile, 'Process')
63+
64+
$baseUri = "https://$Server"
65+
$sessionUri = $baseUri + "/v2/users/sessions"
66+
$sessionBody = @{
67+
username = $Username
68+
password = $Password
69+
}
70+
71+
$jsonBody = $sessionBody | ConvertTo-Json -Compress -Depth 5
72+
73+
$PSBoundParameters = @{
74+
Uri = $sessionUri
75+
Method = 'Post'
76+
Body = $jsonBody
77+
}
78+
79+
$result = Invoke-WebRequest @PSBoundParameters
80+
81+
if ($result.Content) {
82+
$parsedResponse = $result.Content | ConvertFrom-Json
83+
$sessionId = $parsedResponse.sessionId
84+
$cohesitySession = @{
85+
ClusterUri = $baseUri
86+
AllowInvalidServerCertificates = $true
87+
AccessToken = $null
88+
SessionId = $sessionId
89+
ApiKey = $null
90+
}
91+
CohesityUserProfile -UserProfileData $cohesitySession
92+
}
93+
else {
94+
$errorMsg = "Session Id was not Created"
95+
Write-Output $errorMsg
96+
CSLog -Message $errorMsg
97+
}
98+
99+
if ($Global:CohesityCmdletConfig) {
100+
if ($Global:CohesityCmdletConfig.LogResponseData -eq $true) {
101+
if ($result.Content) {
102+
Write-Host "Connected to the Cohesity Cluster $Server Successfully"
103+
}
104+
else {
105+
CSLog -Message "Response content not available" -Severity 1
106+
}
107+
}
108+
}
109+
110+
111+
}
112+
catch {
113+
# this flag can be optionally used by the caller to identify the details of failure
114+
$Global:CohesityAPIError = $_.Exception
115+
# to make the ScriptAnalyzer happy
116+
CSLog -Message ($Global:CohesityAPIError | ConvertTo-json) -Severity 3
117+
# capturing the error message from the cluster rather than the powershell framework $_.Exception.Message
118+
$errorMsg = $_
119+
$Global:CohesityAPIStatus = ConstructResponseWithStatus -APIResponse $errorMsg
120+
Write-Output $errorMsg
121+
CSLog -Message $errorMsg -Severity 3
122+
}
123+
124+
}

0 commit comments

Comments
 (0)