aws expired

This commit is contained in:
Manuel Romero
2025-03-05 12:26:13 +01:00
parent be19759f10
commit b700c10669
12 changed files with 128 additions and 12 deletions

View File

@@ -26,8 +26,8 @@
data-access-token-storage="session"
data-auto-redirect="true"></script>
<link rel="stylesheet" href="styles.89804dbd9a428c1d7bdd.css"></head>
<link rel="stylesheet" href="styles.888d76f1576f5fd6c859.css"></head>
<body>
<app-root></app-root>
<script src="runtime.b2175705264e769e2e1d.js" defer></script><script src="polyfills-es5.66d659991e5a8ec6fd9f.js" nomodule defer></script><script src="polyfills.3273b4fb03b5abe684b4.js" defer></script><script src="scripts.399e476bb5562d6fc683.js" defer></script><script src="main.c7f735261bd7dbbbc140.js" defer></script></body>
<script src="runtime.b2175705264e769e2e1d.js" defer></script><script src="polyfills-es5.66d659991e5a8ec6fd9f.js" nomodule defer></script><script src="polyfills.3273b4fb03b5abe684b4.js" defer></script><script src="scripts.399e476bb5562d6fc683.js" defer></script><script src="main.9efbf8135916a2e7521b.js" defer></script></body>
</html>

View File

@@ -24,7 +24,7 @@
"@hapi/boom": "^9.1.0",
"@ng-bootstrap/ng-bootstrap": "6.2.0",
"@types/chart.js": "^2.9.16",
"@QMI/qmi-cloud-common": "2.0.19",
"@QMI/qmi-cloud-common": "2.0.20",
"adal-angular4": "^4.0.12",
"angular-bootstrap-md": "9.0.0",
"animate.css": "^3.7.2",

View File

@@ -59,6 +59,9 @@ async function rotateAccessKey(provision) {
} else if ( provision.outputs['S3_iam_user_name'] ) {
prefix = "S3_";
username = provision.outputs['S3_iam_user_name'];
} else if ( provision.outputs['s3_iam_user_name'] ) {
prefix = "s3_";
username = provision.outputs['s3_iam_user_name'];
} else {
console.log(`AWSCLI# rotateAccessKey - Provision (${provision._id}) does not contain an IAM user`);
return null;
@@ -105,6 +108,59 @@ async function rotateAccessKey(provision) {
}
}
async function checkAccessKeys(provision) {
if (!provision || !provision.outputs ) {
console.log(`AWSCLI# checkAccessKeys - Provision not found or Provision (${provision._id}) does not contain Outputs`);
return null;
}
var username;
if (provision.outputs['iam_user_name']){
username = provision.outputs['iam_user_name'];
} else if ( provision.outputs['S3_iam_user_name'] ) {
username = provision.outputs['S3_iam_user_name'];
} else if ( provision.outputs['s3_iam_user_name'] ) {
username = provision.outputs['s3_iam_user_name'];
} else {
console.log(`AWSCLI# checkAccessKeys - Provision (${provision._id}) does not contain an IAM user`);
return null;
}
try {
const client = new IAMClient({ region: _getRegion(provision) });
// Step 1: List all access keys for the user
const listKeysCommand = new ListAccessKeysCommand({ UserName: username });
const response = await client.send(listKeysCommand);
console.log(`AWSCLI# checkAccessKeys (${username})`);
var out = [];
response.AccessKeyMetadata.forEach((key) => {
// Step 2: Check if the key is older than 90 days
const createdDate = new Date(key.CreateDate);
const now = new Date();
const ageInDays = (now - createdDate) / (1000 * 60 * 60 * 24);
key.is90dExpired = ageInDays > 90;
out.push(key);
});
if (out.length === 0) {
out.push({
is90dExpired: true
});
}
return out;
} catch (error) {
console.error("Error checking access keys:", error);
return null;
}
}
async function stopDbInstance(provision, triggerUserId, isSendEmailAfter) {
if (provision.statusVms === 'Stopped' || provision.statusVms === 'Stopping'){
return;
@@ -282,3 +338,4 @@ module.exports.start = start;
module.exports.stopDbInstance = stopDbInstance;
module.exports.startDbInstance = startDbInstance;
module.exports.rotateAccessKey = rotateAccessKey;
module.exports.checkAccessKeys = checkAccessKeys;

View File

@@ -88,7 +88,15 @@ async function rotateIAMUserAccessKey(provision) {
try {
return await awscli.rotateAccessKey(provision);
} catch (err) {
console.log("CLI# ERROR stopping DB", err);
console.log("CLI# ERROR rotateIAMUserAccessKeyB", err);
}
}
async function checkIAMUserAccessKey(provision) {
try {
return await awscli.checkAccessKeys(provision);
} catch (err) {
console.log("CLI# ERROR checkIAMUserAccessKey", err);
}
}
@@ -99,4 +107,5 @@ module.exports.stopDb = stopDb;
module.exports.startDb = startDb;
module.exports.createSnapshots = createSnapshots;
module.exports.rotateStorageAccountKey = rotateStorageAccountKey;
module.exports.rotateIAMUserAccessKey = rotateIAMUserAccessKey;
module.exports.rotateIAMUserAccessKey = rotateIAMUserAccessKey;
module.exports.checkIAMUserAccessKey = checkIAMUserAccessKey;

View File

@@ -1,6 +1,6 @@
{
"name": "@QMI/qmi-cloud-common",
"version": "2.0.19",
"version": "2.0.20",
"dependencies": {
"@aws-sdk/client-ec2": "^3.590.0",
"@aws-sdk/client-iam": "^3.758.0",

View File

@@ -909,6 +909,45 @@ router.post('/:userId/provisions/:id/rotate-awsiam-key', passport.ensureAuthenti
}
});
/**
* @swagger
* /users/{userId}/provisions/{id}/get-awsiam-key:
* get:
* description: Check AWS IAM user Access Key
* summary: Check AWS IAM user Access Key
* produces:
* - application/json
* parameters:
* - name: userId
* in: path
* type: string
* required: true
* - name: id
* in: path
* type: string
* required: true
* responses:
* 200:
* description: Provision
* 404:
* description: Not found
*
*/
router.get('/:userId/provisions/:id/get-awsiam-key', passport.ensureAuthenticatedAndIsMe, async (req, res, next) => {
try {
let provision = await db.provision.getById(req.params.id);
if (!provision){
return res.status(404).json({"msg": "Not found privision with id "+req.params.id});
}
const result = await cli.checkIAMUserAccessKey(provision);
return res.json(result);
} catch (error) {
next(error);
}
});
/**
* @swagger
* /users/{userId}/provisions/{id}/extend:

View File

@@ -294,11 +294,12 @@
<span *ngIf="item.key === 'WEB_RDP_ACCESS_WITH_GUACAMOLE'">RDP</span>
</button>
<button style="margin-right: 10px;" mdbTooltip="Rotate Storate Account Key" *ngIf="info.scenario !== 'azqmi-databricks-unity-catalog' && (item.key === 'StorageAccount-AccessKey')" (click)="rotateSAKey(info)" class="lui-button">
<span>ROTATE KEY</span>
<span class="fa fa-refresh"></span>
</button>
<button style="margin-right: 10px;" mdbTooltip="Rotate AWS IAM User Key" *ngIf="(item.key === 'S3_iam_user_access_key' || item.key === 'iam_user_access_key')" (click)="rotateAWSKey(info)" class="lui-button">
<span>ROTATE KEY</span>
<span class="fa fa-refresh"></span>
</button>
<span class="lui-text-danger" *ngIf="awsKey && awsKey.is90dExpired && (item.key === 'se_iam_user_access_key' || item.key === 'S3_iam_user_access_key' || item.key === 'iam_user_access_key')">Expired!</span>
<pre style="margin:0px;font-size: 14px;" [ngStyle]="{display: (item.key === 'WEB_SSH_ACCESS_WITH_GUACAMOLE' || item.key === 'WEB_RDP_ACCESS_WITH_GUACAMOLE' || item.key === 'StorageAccount-AccessKey' || item.key === 'S3_iam_user_access_key' || item.key === 'iam_user_access_key')? 'inline': 'block'}">{{ item.value }}</pre>
</td>
</tr>

View File

@@ -17,6 +17,7 @@ export class ModalInfoComponent implements OnInit, OnDestroy {
provisionId;
info;
events;
awsKey;
currentUser;
private _userId;
sharedUsers;
@@ -33,7 +34,12 @@ export class ModalInfoComponent implements OnInit, OnDestroy {
var es = this._provisionsService.getEvents(this.info.user._id, this.provisionId).subscribe(res=> {
this.events = res.results;
es.unsubscribe();
});
});
var es2 = this._provisionsService.getAWSKey(this.info.user._id, this.provisionId).subscribe(res=> {
console.log("awsKey", res);
this.awsKey = (res && res.length > 0)? res[0] : null;
es2.unsubscribe();
});
}
private _refreshShares() {

View File

@@ -206,6 +206,10 @@ export class ProvisionsService {
return this.httpClient.post(`${environment.apiVersionPath}/users/${userId}/provisions/${id}/rotate-awsiam-key`, null);
}
getAWSKey(id, userId): Observable<any> {
return this.httpClient.get(`${environment.apiVersionPath}/users/${userId}/provisions/${id}/get-awsiam-key`);
}
extend(id, userId): Observable<any> {
return this.httpClient.post(`${environment.apiVersionPath}/users/${userId}/provisions/${id}/extend`, null).pipe(map((p:any)=>{
this.timeRunning(p);

View File

@@ -94,7 +94,7 @@ body {
.lui-button {
color: #444;
//color: #444;
border-color: #ccc;
}