mirror of https://github.com/apache/cloudstack.git
resolve merge conflict with main
This commit is contained in:
commit
928db650e3
10
.asf.yaml
10
.asf.yaml
|
|
@ -50,16 +50,10 @@ github:
|
|||
rebase: false
|
||||
|
||||
collaborators:
|
||||
- acs-robot
|
||||
- gpordeus
|
||||
- hsato03
|
||||
- FelipeM525
|
||||
- lucas-a-martins
|
||||
- nicoschmdt
|
||||
- abh1sar
|
||||
- rosi-shapeblue
|
||||
- sudo87
|
||||
- erikbocks
|
||||
- Imvedansh
|
||||
- Damans227
|
||||
|
||||
protected_branches: ~
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
.github/workflows/*.lock.yml linguist-generated=true merge=ours
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
# Mark all cached import files as generated
|
||||
* linguist-generated=true
|
||||
|
||||
# Use 'ours' merge strategy to keep local cached versions
|
||||
* merge=ours
|
||||
73
.github/aw/imports/github/gh-aw/94662b1dee8ce96c876ba9f33b3ab8be32de82a4/.github_workflows_shared_reporting.md
generated
vendored
Normal file
73
.github/aw/imports/github/gh-aw/94662b1dee8ce96c876ba9f33b3ab8be32de82a4/.github_workflows_shared_reporting.md
generated
vendored
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
---
|
||||
# Report formatting guidelines
|
||||
---
|
||||
|
||||
## Report Structure Guidelines
|
||||
|
||||
### 1. Header Levels
|
||||
**Use h3 (###) or lower for all headers in your issue report to maintain proper document hierarchy.**
|
||||
|
||||
When creating GitHub issues or discussions:
|
||||
- Use `###` (h3) for main sections (e.g., "### Test Summary")
|
||||
- Use `####` (h4) for subsections (e.g., "#### Device-Specific Results")
|
||||
- Never use `##` (h2) or `#` (h1) in reports - these are reserved for titles
|
||||
|
||||
### 2. Progressive Disclosure
|
||||
**Wrap detailed test results in `<details><summary><b>Section Name</b></summary>` tags to improve readability and reduce scrolling.**
|
||||
|
||||
Use collapsible sections for:
|
||||
- Verbose details (full test logs, raw data)
|
||||
- Secondary information (minor warnings, extra context)
|
||||
- Per-item breakdowns when there are many items
|
||||
|
||||
Always keep critical information visible (summary, critical issues, key metrics).
|
||||
|
||||
### 3. Report Structure Pattern
|
||||
|
||||
1. **Overview**: 1-2 paragraphs summarizing key findings
|
||||
2. **Critical Information**: Show immediately (summary stats, critical issues)
|
||||
3. **Details**: Use `<details><summary><b>Section Name</b></summary>` for expanded content
|
||||
4. **Context**: Add helpful metadata (workflow run, date, trigger)
|
||||
|
||||
### Design Principles (Airbnb-Inspired)
|
||||
|
||||
Reports should:
|
||||
- **Build trust through clarity**: Most important info immediately visible
|
||||
- **Exceed expectations**: Add helpful context like trends, comparisons
|
||||
- **Create delight**: Use progressive disclosure to reduce overwhelm
|
||||
- **Maintain consistency**: Follow patterns across all reports
|
||||
|
||||
### Example Report Structure
|
||||
|
||||
```markdown
|
||||
### Summary
|
||||
- Key metric 1: value
|
||||
- Key metric 2: value
|
||||
- Status: ✅/⚠️/❌
|
||||
|
||||
### Critical Issues
|
||||
[Always visible - these are important]
|
||||
|
||||
<details>
|
||||
<summary><b>View Detailed Results</b></summary>
|
||||
|
||||
[Comprehensive details, logs, traces]
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>View All Warnings</b></summary>
|
||||
|
||||
[Minor issues and potential problems]
|
||||
|
||||
</details>
|
||||
|
||||
### Recommendations
|
||||
[Actionable next steps - keep visible]
|
||||
```
|
||||
|
||||
## Workflow Run References
|
||||
|
||||
- Format run IDs as links: `[§12345](https://github.com/owner/repo/actions/runs/12345)`
|
||||
- Include up to 3 most relevant run URLs at end under `**References:**`
|
||||
- Do NOT add footer attribution (system adds automatically)
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,54 @@
|
|||
---
|
||||
description: |
|
||||
This workflow creates daily repo status reports. It gathers recent repository
|
||||
activity (issues, PRs, discussions, releases, code changes) and generates
|
||||
engaging GitHub issues with productivity insights, community highlights,
|
||||
and project recommendations.
|
||||
|
||||
on:
|
||||
schedule: daily
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
issues: read
|
||||
pull-requests: read
|
||||
|
||||
network: defaults
|
||||
|
||||
tools:
|
||||
github:
|
||||
# If in a public repo, setting `lockdown: false` allows
|
||||
# reading issues, pull requests and comments from 3rd-parties
|
||||
# If in a private repo this has no particular effect.
|
||||
lockdown: false
|
||||
|
||||
safe-outputs:
|
||||
create-issue:
|
||||
title-prefix: "[repo-status] "
|
||||
labels: [report, daily-status]
|
||||
source: githubnext/agentics/workflows/daily-repo-status.md@d19056381ba48cb1f7c78510c23069701fa7ae87
|
||||
---
|
||||
|
||||
# Daily Repo Status
|
||||
|
||||
Create an upbeat daily status report for the repo as a GitHub issue.
|
||||
|
||||
## What to include
|
||||
|
||||
- Recent repository activity (issues, PRs, discussions, releases, code changes)
|
||||
- Progress tracking, goal reminders and highlights
|
||||
- Project status and recommendations
|
||||
- Actionable next steps for maintainers
|
||||
|
||||
## Style
|
||||
|
||||
- Be positive, encouraging, and helpful 🌟
|
||||
- Use emojis moderately for engagement
|
||||
- Keep it concise - adjust length based on actual activity
|
||||
|
||||
## Process
|
||||
|
||||
1. Gather recent activity from the repository
|
||||
2. Study the repository, its issues and its pull requests
|
||||
3. Create a new GitHub issue with your findings and insights
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,78 @@
|
|||
---
|
||||
on:
|
||||
schedule: 0 14 * * 1-5
|
||||
workflow_dispatch: null
|
||||
permissions:
|
||||
issues: read
|
||||
imports:
|
||||
- github/gh-aw/.github/workflows/shared/reporting.md@94662b1dee8ce96c876ba9f33b3ab8be32de82a4
|
||||
safe-outputs:
|
||||
add-comment: {}
|
||||
add-labels:
|
||||
allowed:
|
||||
- bug
|
||||
- feature
|
||||
- enhancement
|
||||
- documentation
|
||||
- question
|
||||
- help-wanted
|
||||
- good-first-issue
|
||||
source: github/gh-aw/.github/workflows/issue-triage-agent.md@94662b1dee8ce96c876ba9f33b3ab8be32de82a4
|
||||
strict: true
|
||||
timeout-minutes: 5
|
||||
tools:
|
||||
github:
|
||||
toolsets:
|
||||
- issues
|
||||
- labels
|
||||
---
|
||||
# Issue Triage Agent
|
||||
|
||||
List open issues in ${{ github.repository }} that have no labels. For each unlabeled issue, analyze the title and body, then add one of the allowed labels: `bug`, `feature`, `enhancement`, `documentation`, `question`, `help-wanted`, or `good-first-issue`.
|
||||
|
||||
Skip issues that:
|
||||
- Already have any of these labels
|
||||
- Have been assigned to any user (especially non-bot users)
|
||||
|
||||
After adding the label to an issue, mention the issue author in a comment using this format (follow shared/reporting.md guidelines):
|
||||
|
||||
**Comment Template**:
|
||||
```markdown
|
||||
### 🏷️ Issue Triaged
|
||||
|
||||
Hi @{author}! I've categorized this issue as **{label_name}** based on the following analysis:
|
||||
|
||||
**Reasoning**: {brief_explanation_of_why_this_label}
|
||||
|
||||
<details>
|
||||
<summary><b>View Triage Details</b></summary>
|
||||
|
||||
#### Analysis
|
||||
- **Keywords detected**: {list_of_keywords_that_matched}
|
||||
- **Issue type indicators**: {what_made_this_fit_the_category}
|
||||
- **Confidence**: {High/Medium/Low}
|
||||
|
||||
#### Recommended Next Steps
|
||||
- {context_specific_suggestion_1}
|
||||
- {context_specific_suggestion_2}
|
||||
|
||||
</details>
|
||||
|
||||
**References**: [Triage run §{run_id}](https://github.com/github/gh-aw/actions/runs/{run_id})
|
||||
```
|
||||
|
||||
**Key formatting requirements**:
|
||||
- Use h3 (###) for the main heading
|
||||
- Keep reasoning visible for quick understanding
|
||||
- Wrap detailed analysis in `<details>` tags
|
||||
- Include workflow run reference
|
||||
- Keep total comment concise (collapsed details prevent noise)
|
||||
|
||||
## Batch Comment Optimization
|
||||
|
||||
For efficiency, if multiple issues are triaged in a single run:
|
||||
1. Add individual labels to each issue
|
||||
2. Add a brief comment to each issue (using the template above)
|
||||
3. Optionally: Create a discussion summarizing all triage actions for that run
|
||||
|
||||
This provides both per-issue context and batch visibility.
|
||||
|
|
@ -18,8 +18,8 @@
|
|||
name: "PR Merge Conflict Check"
|
||||
on:
|
||||
push:
|
||||
pull_request_target:
|
||||
types: [synchronize]
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
permissions: # added using https://github.com/step-security/secure-workflows
|
||||
contents: read
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ repos:
|
|||
- --license-filepath
|
||||
- .github/workflows/license-templates/LICENSE.txt
|
||||
- --fuzzy-match-generates-todo
|
||||
exclude: ^(CHANGES|ISSUE_TEMPLATE|PULL_REQUEST_TEMPLATE)\.md$|^ui/docs/(full|smoke)-test-plan\.template\.md$
|
||||
exclude: ^(CHANGES|ISSUE_TEMPLATE|PULL_REQUEST_TEMPLATE)\.md$|^ui/docs/(full|smoke)-test-plan\.template\.md$|^\.github/workflows/.*\.md$|^\.github/aw/.*\.md$
|
||||
- id: insert-license
|
||||
name: add license for all properties files
|
||||
description: automatically adds a licence header to all properties files that don't have a license header
|
||||
|
|
@ -120,6 +120,7 @@ repos:
|
|||
- --license-filepath
|
||||
- .github/workflows/license-templates/LICENSE.txt
|
||||
- --fuzzy-match-generates-todo
|
||||
exclude: ^\.github/workflows/.*\.lock\.yml$
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v6.0.0
|
||||
hooks:
|
||||
|
|
@ -195,4 +196,4 @@ repos:
|
|||
args: [--config-file=.github/linters/.yamllint.yml]
|
||||
types: [yaml]
|
||||
files: \.ya?ml$
|
||||
exclude: ^.*k8s-.*\.ya?ml$
|
||||
exclude: ^.*k8s-.*\.ya?ml$|^.github/workflows/.*\.lock\.ya?ml$
|
||||
|
|
|
|||
|
|
@ -59,6 +59,9 @@ public interface Host extends StateObject<Status>, Identity, Partition, HAResour
|
|||
String HOST_INSTANCE_CONVERSION = "host.instance.conversion";
|
||||
String HOST_OVFTOOL_VERSION = "host.ovftool.version";
|
||||
String HOST_VIRTV2V_VERSION = "host.virtv2v.version";
|
||||
String HOST_SSH_PORT = "host.ssh.port";
|
||||
|
||||
int DEFAULT_SSH_PORT = 22;
|
||||
|
||||
/**
|
||||
* @return name of the machine.
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ public interface AccountService {
|
|||
|
||||
User getSystemUser();
|
||||
|
||||
User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID);
|
||||
User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone,
|
||||
String accountName, Long domainId, String userUUID, boolean isPasswordChangeRequired);
|
||||
|
||||
User createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID,
|
||||
User.Source source);
|
||||
|
|
|
|||
|
|
@ -1261,6 +1261,7 @@ public class ApiConstants {
|
|||
public static final String PROVIDER_FOR_2FA = "providerfor2fa";
|
||||
public static final String ISSUER_FOR_2FA = "issuerfor2fa";
|
||||
public static final String MANDATE_2FA = "mandate2fa";
|
||||
public static final String PASSWORD_CHANGE_REQUIRED = "passwordchangerequired";
|
||||
public static final String SECRET_CODE = "secretcode";
|
||||
public static final String LOGIN = "login";
|
||||
public static final String LOGOUT = "logout";
|
||||
|
|
|
|||
|
|
@ -60,7 +60,8 @@ public class AddHostCmd extends BaseCmd {
|
|||
@Parameter(name = ApiConstants.POD_ID, type = CommandType.UUID, entityType = PodResponse.class, required = true, description = "The Pod ID for the host")
|
||||
private Long podId;
|
||||
|
||||
@Parameter(name = ApiConstants.URL, type = CommandType.STRING, required = true, description = "The host URL")
|
||||
@Parameter(name = ApiConstants.URL, type = CommandType.STRING, required = true, description = "The host URL, optionally add ssh port (format: 'host:port') for KVM hosts," +
|
||||
" otherwise falls back to the port defined at the config 'kvm.host.discovery.ssh.port'")
|
||||
private String url;
|
||||
|
||||
@Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "The Zone ID for the host")
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import org.apache.cloudstack.api.ServerApiException;
|
|||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
import org.apache.cloudstack.api.response.UserResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.commons.lang.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.cloud.user.Account;
|
||||
|
|
@ -78,6 +79,12 @@ public class CreateUserCmd extends BaseCmd {
|
|||
@Parameter(name = ApiConstants.USER_ID, type = CommandType.STRING, description = "User UUID, required for adding account from external provisioning system")
|
||||
private String userUUID;
|
||||
|
||||
@Parameter(name = ApiConstants.PASSWORD_CHANGE_REQUIRED,
|
||||
type = CommandType.BOOLEAN,
|
||||
description = "Provide true to mandate the User to reset password on next login.",
|
||||
since = "4.23.0")
|
||||
private Boolean passwordChangeRequired;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -118,6 +125,10 @@ public class CreateUserCmd extends BaseCmd {
|
|||
return userUUID;
|
||||
}
|
||||
|
||||
public Boolean isPasswordChangeRequired() {
|
||||
return BooleanUtils.isTrue(passwordChangeRequired);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -147,7 +158,7 @@ public class CreateUserCmd extends BaseCmd {
|
|||
CallContext.current().setEventDetails("UserName: " + getUserName() + ", FirstName :" + getFirstName() + ", LastName: " + getLastName());
|
||||
User user =
|
||||
_accountService.createUser(getUserName(), getPassword(), getFirstName(), getLastName(), getEmail(), getTimezone(), getAccountName(), getDomainId(),
|
||||
getUserUUID());
|
||||
getUserUUID(), isPasswordChangeRequired());
|
||||
if (user != null) {
|
||||
UserResponse response = _responseGenerator.createUserResponse(user);
|
||||
response.setResponseName(getCommandName());
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import org.apache.cloudstack.api.ServerApiException;
|
|||
import org.apache.cloudstack.api.response.UserResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.region.RegionService;
|
||||
import org.apache.commons.lang.BooleanUtils;
|
||||
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.User;
|
||||
|
|
@ -38,6 +39,8 @@ import com.cloud.user.UserAccount;
|
|||
requestHasSensitiveInfo = true, responseHasSensitiveInfo = true)
|
||||
public class UpdateUserCmd extends BaseCmd {
|
||||
|
||||
@Inject
|
||||
private RegionService _regionService;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
|
|
@ -85,8 +88,11 @@ public class UpdateUserCmd extends BaseCmd {
|
|||
"This parameter is only used to mandate 2FA, not to disable 2FA", since = "4.18.0.0")
|
||||
private Boolean mandate2FA;
|
||||
|
||||
@Inject
|
||||
private RegionService _regionService;
|
||||
@Parameter(name = ApiConstants.PASSWORD_CHANGE_REQUIRED,
|
||||
type = CommandType.BOOLEAN,
|
||||
description = "Provide true to mandate the User to reset password on next login.",
|
||||
since = "4.23.0")
|
||||
private Boolean passwordChangeRequired;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
|
|
@ -193,4 +199,8 @@ public class UpdateUserCmd extends BaseCmd {
|
|||
public ApiCommandResourceType getApiResourceType() {
|
||||
return ApiCommandResourceType.User;
|
||||
}
|
||||
|
||||
public Boolean isPasswordChangeRequired() {
|
||||
return BooleanUtils.isTrue(passwordChangeRequired);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,6 +90,10 @@ public class LoginCmdResponse extends AuthenticationCmdResponse {
|
|||
@Param(description = "Management Server ID that the user logged to", since = "4.21.0.0")
|
||||
private String managementServerId;
|
||||
|
||||
@SerializedName(value = ApiConstants.PASSWORD_CHANGE_REQUIRED)
|
||||
@Param(description = "Indicates whether the User is required to change password on next login.", since = "4.23.0")
|
||||
private Boolean passwordChangeRequired;
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
|
@ -223,4 +227,12 @@ public class LoginCmdResponse extends AuthenticationCmdResponse {
|
|||
public void setManagementServerId(String managementServerId) {
|
||||
this.managementServerId = managementServerId;
|
||||
}
|
||||
|
||||
public Boolean getPasswordChangeRequired() {
|
||||
return passwordChangeRequired;
|
||||
}
|
||||
|
||||
public void setPasswordChangeRequired(Boolean passwordChangeRequired) {
|
||||
this.passwordChangeRequired = passwordChangeRequired;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import org.apache.cloudstack.api.command.user.backup.ListBackupScheduleCmd;
|
|||
import org.apache.cloudstack.api.command.user.backup.ListBackupsCmd;
|
||||
import org.apache.cloudstack.api.response.BackupResponse;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.framework.config.ValidatedConfigKey;
|
||||
import org.apache.cloudstack.framework.config.Configurable;
|
||||
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
|
|
@ -53,10 +54,11 @@ public interface BackupManager extends BackupService, Configurable, PluggableSer
|
|||
"false",
|
||||
"Is backup and recovery framework enabled.", false, ConfigKey.Scope.Zone);
|
||||
|
||||
ConfigKey<String> BackupProviderPlugin = new ConfigKey<>("Advanced", String.class,
|
||||
ConfigKey<String> BackupProviderPlugin = new ValidatedConfigKey<>("Advanced", String.class,
|
||||
"backup.framework.provider.plugin",
|
||||
"dummy",
|
||||
"The backup and recovery provider plugin. Valid plugin values: dummy, veeam, networker and nas", true, ConfigKey.Scope.Zone, BackupFrameworkEnabled.key());
|
||||
"The backup and recovery provider plugin. Valid plugin values: dummy, veeam, networker and nas",
|
||||
true, ConfigKey.Scope.Zone, BackupFrameworkEnabled.key(), value -> validateBackupProviderConfig((String)value));
|
||||
|
||||
ConfigKey<Long> BackupSyncPollingInterval = new ConfigKey<>("Advanced", Long.class,
|
||||
"backup.framework.sync.interval",
|
||||
|
|
@ -249,4 +251,14 @@ public interface BackupManager extends BackupService, Configurable, PluggableSer
|
|||
Capacity getBackupStorageUsedStats(Long zoneId);
|
||||
|
||||
void checkAndRemoveBackupOfferingBeforeExpunge(VirtualMachine vm);
|
||||
|
||||
static void validateBackupProviderConfig(String value) {
|
||||
if (value != null && (value.contains(",") || value.trim().contains(" "))) {
|
||||
throw new IllegalArgumentException("Multiple backup provider plugins are not supported. Please provide a single plugin value.");
|
||||
}
|
||||
List<String> validPlugins = List.of("dummy", "veeam", "networker", "nas");
|
||||
if (value != null && !validPlugins.contains(value)) {
|
||||
throw new IllegalArgumentException("Invalid backup provider plugin: " + value + ". Valid plugin values are: " + String.join(", ", validPlugins));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ public class CreateUserCmdTest {
|
|||
} catch (ServerApiException e) {
|
||||
Assert.assertTrue("Received exception as the mock accountService createUser returns null user", true);
|
||||
}
|
||||
Mockito.verify(accountService, Mockito.times(1)).createUser(null, "Test", null, null, null, null, null, null, null);
|
||||
Mockito.verify(accountService, Mockito.times(1)).createUser(null, "Test", null, null, null, null, null, null, null, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -82,7 +82,7 @@ public class CreateUserCmdTest {
|
|||
Assert.assertEquals(ApiErrorCode.PARAM_ERROR,e.getErrorCode());
|
||||
Assert.assertEquals("Empty passwords are not allowed", e.getMessage());
|
||||
}
|
||||
Mockito.verify(accountService, Mockito.never()).createUser(null, null, null, null, null, null, null, null, null);
|
||||
Mockito.verify(accountService, Mockito.never()).createUser(null, null, null, null, null, null, null, null, null, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -95,6 +95,6 @@ public class CreateUserCmdTest {
|
|||
Assert.assertEquals(ApiErrorCode.PARAM_ERROR,e.getErrorCode());
|
||||
Assert.assertEquals("Empty passwords are not allowed", e.getMessage());
|
||||
}
|
||||
Mockito.verify(accountService, Mockito.never()).createUser(null, null, null, null, null, null, null, null, null);
|
||||
Mockito.verify(accountService, Mockito.never()).createUser(null, null, null, null, null, null, null, null, null, true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cloudstack.api.command.admin.user;
|
||||
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class UpdateUserCmdTest {
|
||||
@InjectMocks
|
||||
private UpdateUserCmd cmd;
|
||||
|
||||
@Test
|
||||
public void testGetApiResourceId() {
|
||||
Long userId = 99L;
|
||||
cmd.setId(userId);
|
||||
Assert.assertEquals(userId, cmd.getApiResourceId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetApiResourceType() {
|
||||
Assert.assertEquals(ApiCommandResourceType.User, cmd.getApiResourceType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsPasswordChangeRequired_True() {
|
||||
ReflectionTestUtils.setField(cmd, "passwordChangeRequired", Boolean.TRUE);
|
||||
Assert.assertTrue(cmd.isPasswordChangeRequired());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsPasswordChangeRequired_False() {
|
||||
ReflectionTestUtils.setField(cmd, "passwordChangeRequired", Boolean.FALSE);
|
||||
Assert.assertFalse(cmd.isPasswordChangeRequired());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsPasswordChangeRequired_Null() {
|
||||
ReflectionTestUtils.setField(cmd, "passwordChangeRequired", null);
|
||||
Assert.assertFalse(cmd.isPasswordChangeRequired());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.api.response;
|
||||
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class LoginCmdResponseTest {
|
||||
|
||||
@Test
|
||||
public void testAllGettersAndSetters() {
|
||||
LoginCmdResponse response = new LoginCmdResponse();
|
||||
|
||||
response.setUsername("user1");
|
||||
response.setUserId("100");
|
||||
response.setDomainId("200");
|
||||
response.setTimeout(3600);
|
||||
response.setAccount("account1");
|
||||
response.setFirstName("John");
|
||||
response.setLastName("Doe");
|
||||
response.setType("admin");
|
||||
response.setTimeZone("UTC");
|
||||
response.setTimeZoneOffset("+00:00");
|
||||
response.setRegistered("true");
|
||||
response.setSessionKey("session-key");
|
||||
response.set2FAenabled("true");
|
||||
response.set2FAverfied("false");
|
||||
response.setProviderFor2FA("totp");
|
||||
response.setIssuerFor2FA("cloudstack");
|
||||
response.setManagementServerId("ms-1");
|
||||
|
||||
Assert.assertEquals("user1", response.getUsername());
|
||||
Assert.assertEquals("100", response.getUserId());
|
||||
Assert.assertEquals("200", response.getDomainId());
|
||||
Assert.assertEquals(Integer.valueOf(3600), response.getTimeout());
|
||||
Assert.assertEquals("account1", response.getAccount());
|
||||
Assert.assertEquals("John", response.getFirstName());
|
||||
Assert.assertEquals("Doe", response.getLastName());
|
||||
Assert.assertEquals("admin", response.getType());
|
||||
Assert.assertEquals("UTC", response.getTimeZone());
|
||||
Assert.assertEquals("+00:00", response.getTimeZoneOffset());
|
||||
Assert.assertEquals("true", response.getRegistered());
|
||||
Assert.assertEquals("session-key", response.getSessionKey());
|
||||
Assert.assertEquals("true", response.is2FAenabled());
|
||||
Assert.assertEquals("false", response.is2FAverfied());
|
||||
Assert.assertEquals("totp", response.getProviderFor2FA());
|
||||
Assert.assertEquals("cloudstack", response.getIssuerFor2FA());
|
||||
Assert.assertEquals("ms-1", response.getManagementServerId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPasswordChangeRequired_True() {
|
||||
LoginCmdResponse response = new LoginCmdResponse();
|
||||
response.setPasswordChangeRequired(true);
|
||||
Assert.assertTrue(response.getPasswordChangeRequired());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPasswordChangeRequired_False() {
|
||||
LoginCmdResponse response = new LoginCmdResponse();
|
||||
response.setPasswordChangeRequired(false);
|
||||
Assert.assertFalse(response.getPasswordChangeRequired());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPasswordChangeRequired_Null() {
|
||||
LoginCmdResponse response = new LoginCmdResponse();
|
||||
response.setPasswordChangeRequired(null);
|
||||
Assert.assertNull("Boolean.parseBoolean(null) should return null", response.getPasswordChangeRequired());
|
||||
}
|
||||
}
|
||||
|
|
@ -46,6 +46,10 @@ public class ModifyStoragePoolAnswer extends Answer {
|
|||
templateInfo = tInfo;
|
||||
}
|
||||
|
||||
public ModifyStoragePoolAnswer(final Command command, final boolean success, final String details) {
|
||||
super(command, success, details);
|
||||
}
|
||||
|
||||
public ModifyStoragePoolAnswer(ModifyStoragePoolCommand cmd, boolean success, String details) {
|
||||
super(cmd, success, details);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,9 +34,9 @@ public class RestoreBackupCommand extends Command {
|
|||
private List<String> backupVolumesUUIDs;
|
||||
private List<PrimaryDataStoreTO> restoreVolumePools;
|
||||
private List<String> restoreVolumePaths;
|
||||
private List<String> backupFiles;
|
||||
private String diskType;
|
||||
private Boolean vmExists;
|
||||
private String restoreVolumeUUID;
|
||||
private VirtualMachine.State vmState;
|
||||
private Integer mountTimeout;
|
||||
|
||||
|
|
@ -92,6 +92,14 @@ public class RestoreBackupCommand extends Command {
|
|||
this.restoreVolumePaths = restoreVolumePaths;
|
||||
}
|
||||
|
||||
public List<String> getBackupFiles() {
|
||||
return backupFiles;
|
||||
}
|
||||
|
||||
public void setBackupFiles(List<String> backupFiles) {
|
||||
this.backupFiles = backupFiles;
|
||||
}
|
||||
|
||||
public Boolean isVmExists() {
|
||||
return vmExists;
|
||||
}
|
||||
|
|
@ -116,14 +124,6 @@ public class RestoreBackupCommand extends Command {
|
|||
this.mountOptions = mountOptions;
|
||||
}
|
||||
|
||||
public String getRestoreVolumeUUID() {
|
||||
return restoreVolumeUUID;
|
||||
}
|
||||
|
||||
public void setRestoreVolumeUUID(String restoreVolumeUUID) {
|
||||
this.restoreVolumeUUID = restoreVolumeUUID;
|
||||
}
|
||||
|
||||
public VirtualMachine.State getVmState() {
|
||||
return vmState;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,10 @@ public interface AgentManager {
|
|||
"This timeout overrides the wait global config. This holds a comma separated key value pairs containing timeout (in seconds) for specific commands. " +
|
||||
"For example: DhcpEntryCommand=600, SavePasswordCommand=300, VmDataCommand=300", false);
|
||||
|
||||
ConfigKey<Integer> KVMHostDiscoverySshPort = new ConfigKey<>(ConfigKey.CATEGORY_ADVANCED, Integer.class,
|
||||
"kvm.host.discovery.ssh.port", String.valueOf(Host.DEFAULT_SSH_PORT), "SSH port used for KVM host discovery and any other operations on host (using SSH)." +
|
||||
" Please note that this is applicable when port is not defined through host url while adding the KVM host.", true, ConfigKey.Scope.Cluster);
|
||||
|
||||
enum TapAgentsAction {
|
||||
Add, Del, Contains,
|
||||
}
|
||||
|
|
@ -172,4 +176,6 @@ public interface AgentManager {
|
|||
void propagateChangeToAgents(Map<String, String> params);
|
||||
|
||||
boolean transferDirectAgentsFromMS(String fromMsUuid, long fromMsId, long timeoutDurationInMs, boolean excludeHostsInMaintenance);
|
||||
|
||||
int getHostSshPort(HostVO host);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,6 +167,8 @@ public interface ResourceManager extends ResourceService, Configurable {
|
|||
|
||||
public HostVO findHostByGuid(String guid);
|
||||
|
||||
HostVO findHostByGuidPrefix(String guid);
|
||||
|
||||
public HostVO findHostByName(String name);
|
||||
|
||||
HostStats getHostStatistics(Host host);
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ import java.util.stream.Collectors;
|
|||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.utils.StringUtils;
|
||||
import org.apache.cloudstack.agent.lb.IndirectAgentLB;
|
||||
import org.apache.cloudstack.ca.CAManager;
|
||||
import org.apache.cloudstack.command.ReconcileCommandService;
|
||||
|
|
@ -64,7 +65,6 @@ import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToSt
|
|||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.ThreadContext;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
|
|
@ -2111,7 +2111,7 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
return new ConfigKey<?>[] { CheckTxnBeforeSending, Workers, Port, Wait, AlertWait, DirectAgentLoadSize,
|
||||
DirectAgentPoolSize, DirectAgentThreadCap, EnableKVMAutoEnableDisable, ReadyCommandWait,
|
||||
GranularWaitTimeForCommands, RemoteAgentSslHandshakeTimeout, RemoteAgentMaxConcurrentNewConnections,
|
||||
RemoteAgentNewConnectionsMonitorInterval };
|
||||
RemoteAgentNewConnectionsMonitorInterval, KVMHostDiscoverySshPort };
|
||||
}
|
||||
|
||||
protected class SetHostParamsListener implements Listener {
|
||||
|
|
@ -2234,6 +2234,25 @@ public class AgentManagerImpl extends ManagerBase implements AgentManager, Handl
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHostSshPort(HostVO host) {
|
||||
if (host == null) {
|
||||
return KVMHostDiscoverySshPort.value();
|
||||
}
|
||||
|
||||
if (host.getHypervisorType() != HypervisorType.KVM) {
|
||||
return Host.DEFAULT_SSH_PORT;
|
||||
}
|
||||
|
||||
_hostDao.loadDetails(host);
|
||||
String hostPort = host.getDetail(Host.HOST_SSH_PORT);
|
||||
if (StringUtils.isBlank(hostPort)) {
|
||||
return KVMHostDiscoverySshPort.valueIn(host.getClusterId());
|
||||
}
|
||||
|
||||
return Integer.parseInt(hostPort);
|
||||
}
|
||||
|
||||
private GlobalLock getHostJoinLock(Long hostId) {
|
||||
return GlobalLock.getInternLock(String.format("%s-%s", "Host-Join", hostId));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import com.cloud.agent.api.ReadyCommand;
|
|||
import com.cloud.agent.api.StartupCommand;
|
||||
import com.cloud.agent.api.StartupRoutingCommand;
|
||||
import com.cloud.exception.ConnectionException;
|
||||
import com.cloud.host.Host;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.Status;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
|
|
@ -104,4 +105,36 @@ public class AgentManagerImplTest {
|
|||
|
||||
Assert.assertEquals(50, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetHostSshPortWithHostNull() {
|
||||
int hostSshPort = mgr.getHostSshPort(null);
|
||||
Assert.assertEquals(22, hostSshPort);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetHostSshPortWithNonKVMHost() {
|
||||
HostVO host = Mockito.mock(HostVO.class);
|
||||
Mockito.when(host.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.XenServer);
|
||||
int hostSshPort = mgr.getHostSshPort(host);
|
||||
Assert.assertEquals(22, hostSshPort);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetHostSshPortWithKVMHostDefaultPort() {
|
||||
HostVO host = Mockito.mock(HostVO.class);
|
||||
Mockito.when(host.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
|
||||
Mockito.when(host.getClusterId()).thenReturn(1L);
|
||||
int hostSshPort = mgr.getHostSshPort(host);
|
||||
Assert.assertEquals(22, hostSshPort);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetHostSshPortWithKVMHostCustomPort() {
|
||||
HostVO host = Mockito.mock(HostVO.class);
|
||||
Mockito.when(host.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
|
||||
Mockito.when(host.getDetail(Host.HOST_SSH_PORT)).thenReturn(String.valueOf(3922));
|
||||
int hostSshPort = mgr.getHostSshPort(host);
|
||||
Assert.assertEquals(3922, hostSshPort);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ public class ClusterDetailsDaoImpl extends ResourceDetailsDaoBase<ClusterDetails
|
|||
@Override
|
||||
public String getConfigValue(long id, String key) {
|
||||
ClusterDetailsVO vo = findDetail(id, key);
|
||||
return vo == null ? null : vo.getValue();
|
||||
return vo == null ? null : getActualValue(vo);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ public class DataCenterDetailsDaoImpl extends ResourceDetailsDaoBase<DataCenterD
|
|||
@Override
|
||||
public String getConfigValue(long id, String key) {
|
||||
ResourceDetail vo = findDetail(id, key);
|
||||
return vo == null ? null : vo.getValue();
|
||||
return vo == null ? null : getActualValue(vo);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -1412,7 +1412,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
|
|||
SearchCriteria<HostVO> sc = TypeStatusStateSearch.create();
|
||||
sc.setParameters("type", Host.Type.Routing);
|
||||
sc.setParameters("cluster", clusterId);
|
||||
List<HostVO> list = listBy(sc, new Filter(1));
|
||||
List<HostVO> list = listBy(sc, new Filter(1, true));
|
||||
return list.isEmpty() ? null : list.get(0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -383,7 +383,7 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
|
|||
|
||||
public VolumeDaoImpl() {
|
||||
AllFieldsSearch = createSearchBuilder();
|
||||
AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ);
|
||||
AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.IN);
|
||||
AllFieldsSearch.and("accountId", AllFieldsSearch.entity().getAccountId(), Op.EQ);
|
||||
AllFieldsSearch.and("dcId", AllFieldsSearch.entity().getDataCenterId(), Op.EQ);
|
||||
AllFieldsSearch.and("pod", AllFieldsSearch.entity().getPodId(), Op.EQ);
|
||||
|
|
@ -581,17 +581,16 @@ public class VolumeDaoImpl extends GenericDaoBase<VolumeVO, Long> implements Vol
|
|||
|
||||
@Override
|
||||
public List<VolumeVO> listVolumesToBeDestroyed() {
|
||||
SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("state", Volume.State.Destroy);
|
||||
|
||||
return listBy(sc);
|
||||
return listVolumesToBeDestroyed(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VolumeVO> listVolumesToBeDestroyed(Date date) {
|
||||
SearchCriteria<VolumeVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("state", Volume.State.Destroy);
|
||||
sc.setParameters("updateTime", date);
|
||||
sc.setParameters("state", Volume.State.Destroy, Volume.State.Expunging);
|
||||
if (date != null) {
|
||||
sc.setParameters("updateTime", date);
|
||||
}
|
||||
|
||||
return listBy(sc);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,8 +123,8 @@ public class UserVO implements User, Identity, InternalIdentity {
|
|||
}
|
||||
|
||||
public UserVO(long id) {
|
||||
this();
|
||||
this.id = id;
|
||||
this.uuid = UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
public UserVO(long accountId, String username, String password, String firstName, String lastName, String email, String timezone, String uuid, Source source) {
|
||||
|
|
|
|||
|
|
@ -21,13 +21,11 @@ import java.util.List;
|
|||
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface AccountDao extends GenericDao<AccountVO, Long> {
|
||||
Pair<User, Account> findUserAccountByApiKey(String apiKey);
|
||||
|
||||
List<AccountVO> findAccountsLike(String accountName);
|
||||
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@
|
|||
// under the License.
|
||||
package com.cloud.user.dao;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -27,10 +25,7 @@ import org.springframework.stereotype.Component;
|
|||
import com.cloud.user.Account;
|
||||
import com.cloud.user.Account.State;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.UserVO;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.crypt.DBEncryptionUtil;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.GenericSearchBuilder;
|
||||
|
|
@ -38,13 +33,9 @@ import com.cloud.utils.db.SearchBuilder;
|
|||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.SearchCriteria.Func;
|
||||
import com.cloud.utils.db.SearchCriteria.Op;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
|
||||
@Component
|
||||
public class AccountDaoImpl extends GenericDaoBase<AccountVO, Long> implements AccountDao {
|
||||
private static final String FIND_USER_ACCOUNT_BY_API_KEY = "SELECT u.id, u.username, u.account_id, u.secret_key, u.state, u.api_key_access, "
|
||||
+ "a.id, a.account_name, a.type, a.role_id, a.domain_id, a.state, a.api_key_access " + "FROM `cloud`.`user` u, `cloud`.`account` a "
|
||||
+ "WHERE u.account_id = a.id AND u.api_key = ? and u.removed IS NULL";
|
||||
|
||||
protected final SearchBuilder<AccountVO> AllFieldsSearch;
|
||||
protected final SearchBuilder<AccountVO> AccountTypeSearch;
|
||||
|
|
@ -132,51 +123,6 @@ public class AccountDaoImpl extends GenericDaoBase<AccountVO, Long> implements A
|
|||
return listBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<User, Account> findUserAccountByApiKey(String apiKey) {
|
||||
TransactionLegacy txn = TransactionLegacy.currentTxn();
|
||||
PreparedStatement pstmt = null;
|
||||
Pair<User, Account> userAcctPair = null;
|
||||
try {
|
||||
String sql = FIND_USER_ACCOUNT_BY_API_KEY;
|
||||
pstmt = txn.prepareAutoCloseStatement(sql);
|
||||
pstmt.setString(1, apiKey);
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
// TODO: make sure we don't have more than 1 result? ApiKey had better be unique
|
||||
if (rs.next()) {
|
||||
User u = new UserVO(rs.getLong(1));
|
||||
u.setUsername(rs.getString(2));
|
||||
u.setAccountId(rs.getLong(3));
|
||||
u.setSecretKey(DBEncryptionUtil.decrypt(rs.getString(4)));
|
||||
u.setState(State.getValueOf(rs.getString(5)));
|
||||
boolean apiKeyAccess = rs.getBoolean(6);
|
||||
if (rs.wasNull()) {
|
||||
u.setApiKeyAccess(null);
|
||||
} else {
|
||||
u.setApiKeyAccess(apiKeyAccess);
|
||||
}
|
||||
|
||||
AccountVO a = new AccountVO(rs.getLong(7));
|
||||
a.setAccountName(rs.getString(8));
|
||||
a.setType(Account.Type.getFromValue(rs.getInt(9)));
|
||||
a.setRoleId(rs.getLong(10));
|
||||
a.setDomainId(rs.getLong(11));
|
||||
a.setState(State.getValueOf(rs.getString(12)));
|
||||
apiKeyAccess = rs.getBoolean(13);
|
||||
if (rs.wasNull()) {
|
||||
a.setApiKeyAccess(null);
|
||||
} else {
|
||||
a.setApiKeyAccess(apiKeyAccess);
|
||||
}
|
||||
|
||||
userAcctPair = new Pair<User, Account>(u, a);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("Exception finding user/acct by api key: " + apiKey, e);
|
||||
}
|
||||
return userAcctPair;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AccountVO> findAccountsLike(String accountName) {
|
||||
return findAccountsLike(accountName, null).first();
|
||||
|
|
@ -341,11 +287,9 @@ public class AccountDaoImpl extends GenericDaoBase<AccountVO, Long> implements A
|
|||
domain_id = account_vo.getDomainId();
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.warn("getDomainIdForGivenAccountId: Exception :" + e.getMessage());
|
||||
}
|
||||
finally {
|
||||
return domain_id;
|
||||
logger.warn("Can not get DomainId for the given AccountId; exception message : {}", e.getMessage());
|
||||
}
|
||||
return domain_id;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ public class UserDetailVO implements ResourceDetail {
|
|||
public static final String Setup2FADetail = "2FASetupStatus";
|
||||
public static final String PasswordResetToken = "PasswordResetToken";
|
||||
public static final String PasswordResetTokenExpiryDate = "PasswordResetTokenExpiryDate";
|
||||
public static final String PasswordChangeRequired = "PasswordChangeRequired";
|
||||
public static final String OauthLogin = "OauthLogin";
|
||||
|
||||
public UserDetailVO() {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ public class ImageStoreDaoImpl extends GenericDaoBase<ImageStoreVO, Long> implem
|
|||
sc.setParameters("dataCenterId", dataCenterId);
|
||||
sc.setParameters("protocol", protocol);
|
||||
sc.setParameters("role", DataStoreRole.Image);
|
||||
Filter filter = new Filter(1);
|
||||
Filter filter = new Filter(1, true);
|
||||
List<ImageStoreVO> results = listBy(sc, filter);
|
||||
return results.size() == 0 ? null : results.get(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -436,6 +436,9 @@ public class VolumeServiceImpl implements VolumeService {
|
|||
// no need to change state in volumes table
|
||||
volume.processEventOnly(Event.DestroyRequested);
|
||||
} else if (volume.getDataStore().getRole() == DataStoreRole.Primary) {
|
||||
if (vol.getState() == Volume.State.Expunging) {
|
||||
logger.info("Volume {} is already in Expunging, retrying", volume);
|
||||
}
|
||||
volume.processEvent(Event.ExpungeRequested);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,27 +14,25 @@
|
|||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.framework.config;
|
||||
|
||||
package org.apache.cloudstack.quota.activationrule.presetvariables;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
public class ValidatedConfigKey<T> extends ConfigKey<T> {
|
||||
private final Consumer<T> validator;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ResourceTest {
|
||||
|
||||
@Test
|
||||
public void toStringTestReturnAJson() {
|
||||
Resource variable = new Resource();
|
||||
|
||||
String expected = ToStringBuilder.reflectionToString(variable, ToStringStyle.JSON_STYLE);
|
||||
String result = variable.toString();
|
||||
|
||||
Assert.assertEquals(expected, result);
|
||||
public ValidatedConfigKey(String category, Class<T> type, String name, String defaultValue, String description, boolean dynamic, Scope scope, String parent, Consumer<T> validator) {
|
||||
super(category, type, name, defaultValue, description, dynamic, scope, parent);
|
||||
this.validator = validator;
|
||||
}
|
||||
|
||||
public Consumer<T> getValidator() {
|
||||
return validator;
|
||||
}
|
||||
|
||||
public void validateValue(String value) {
|
||||
if (validator != null) {
|
||||
validator.accept((T) value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -57,7 +57,18 @@ public class Filter {
|
|||
}
|
||||
|
||||
public Filter(long limit) {
|
||||
_orderBy = " ORDER BY RAND()";
|
||||
this(limit, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for creating a filter with random ordering
|
||||
* @param limit the maximum number of results to return
|
||||
* @param randomize if true, orders results randomly
|
||||
*/
|
||||
public Filter(long limit, boolean randomize) {
|
||||
if (randomize) {
|
||||
_orderBy = " ORDER BY RAND()" ;
|
||||
}
|
||||
_limit = limit;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -347,7 +347,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
|
|||
@Override
|
||||
@DB()
|
||||
public T lockOneRandomRow(final SearchCriteria<T> sc, final boolean exclusive) {
|
||||
final Filter filter = new Filter(1);
|
||||
final Filter filter = new Filter(1, true);
|
||||
final List<T> beans = search(sc, filter, exclusive, true);
|
||||
return beans.isEmpty() ? null : beans.get(0);
|
||||
}
|
||||
|
|
@ -927,7 +927,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
|
|||
|
||||
@DB()
|
||||
protected T findOneIncludingRemovedBy(final SearchCriteria<T> sc) {
|
||||
Filter filter = new Filter(1);
|
||||
Filter filter = new Filter(1, true);
|
||||
List<T> results = searchIncludingRemoved(sc, filter, null, false);
|
||||
assert results.size() <= 1 : "Didn't the limiting worked?";
|
||||
return results.size() == 0 ? null : results.get(0);
|
||||
|
|
@ -1335,7 +1335,7 @@ public abstract class GenericDaoBase<T, ID extends Serializable> extends Compone
|
|||
Filter filter = null;
|
||||
final long batchSizeFinal = ObjectUtils.defaultIfNull(batchSize, 0L);
|
||||
if (batchSizeFinal > 0) {
|
||||
filter = new Filter(null, batchSizeFinal);
|
||||
filter = new Filter(batchSizeFinal);
|
||||
}
|
||||
int expunged = 0;
|
||||
int currentExpunged = 0;
|
||||
|
|
|
|||
|
|
@ -41,4 +41,62 @@ public class FilterTest {
|
|||
Assert.assertTrue(filter.getOrderBy().split(",").length == 3);
|
||||
Assert.assertTrue(filter.getOrderBy().split(",")[2].trim().toLowerCase().equals("test.fld_int asc"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testFilterWithLimitOnly() {
|
||||
Filter filter = new Filter(5);
|
||||
|
||||
Assert.assertEquals(Long.valueOf(5), filter.getLimit());
|
||||
Assert.assertNull(filter.getOrderBy());
|
||||
Assert.assertNull(filter.getOffset());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFilterWithLimitAndRandomizeFalse() {
|
||||
Filter filter = new Filter(10, false);
|
||||
|
||||
Assert.assertEquals(Long.valueOf(10), filter.getLimit());
|
||||
Assert.assertNull(filter.getOrderBy());
|
||||
Assert.assertNull(filter.getOffset());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFilterWithLimitAndRandomizeTrue() {
|
||||
Filter filter = new Filter(3, true);
|
||||
|
||||
Assert.assertNull(filter.getLimit());
|
||||
Assert.assertNotNull(filter.getOrderBy());
|
||||
Assert.assertTrue(filter.getOrderBy().contains("ORDER BY RAND()"));
|
||||
Assert.assertTrue(filter.getOrderBy().contains("LIMIT 3"));
|
||||
Assert.assertEquals(" ORDER BY RAND() LIMIT 3", filter.getOrderBy());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFilterRandomizeWithDifferentLimits() {
|
||||
Filter filter1 = new Filter(1, true);
|
||||
Filter filter10 = new Filter(10, true);
|
||||
Filter filter100 = new Filter(100, true);
|
||||
|
||||
Assert.assertEquals(" ORDER BY RAND() LIMIT 1", filter1.getOrderBy());
|
||||
Assert.assertEquals(" ORDER BY RAND() LIMIT 10", filter10.getOrderBy());
|
||||
Assert.assertEquals(" ORDER BY RAND() LIMIT 100", filter100.getOrderBy());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFilterConstructorBackwardsCompatibility() {
|
||||
// Test that Filter(long) behaves differently now (no ORDER BY RAND())
|
||||
// compared to Filter(long, true) which preserves old behavior
|
||||
Filter simpleLimitFilter = new Filter(1);
|
||||
Filter randomFilter = new Filter(1, true);
|
||||
|
||||
// Simple limit filter should just set limit
|
||||
Assert.assertEquals(Long.valueOf(1), simpleLimitFilter.getLimit());
|
||||
Assert.assertNull(simpleLimitFilter.getOrderBy());
|
||||
|
||||
// Random filter should set orderBy with RAND()
|
||||
Assert.assertNull(randomFilter.getLimit());
|
||||
Assert.assertNotNull(randomFilter.getOrderBy());
|
||||
Assert.assertTrue(randomFilter.getOrderBy().contains("RAND()"));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import java.sql.ResultSet;
|
|||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
|
|
@ -263,4 +264,71 @@ public class GenericDaoBaseTest {
|
|||
" INNER JOIN tableA tableA2Alias ON tableC.column3=tableA2Alias.column2 " +
|
||||
" INNER JOIN tableA tableA3Alias ON tableD.column4=tableA3Alias.column3 AND tableD.column5=? ", joinString.toString());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testLockOneRandomRowUsesRandomFilter() {
|
||||
// Create a mock DAO to test lockOneRandomRow behavior
|
||||
GenericDaoBase<DbTestVO, Long> testDao = Mockito.mock(GenericDaoBase.class);
|
||||
|
||||
// Capture the filter passed to the search method
|
||||
final Filter[] capturedFilter = new Filter[1];
|
||||
|
||||
Mockito.when(testDao.lockOneRandomRow(Mockito.any(SearchCriteria.class), Mockito.anyBoolean()))
|
||||
.thenCallRealMethod();
|
||||
|
||||
Mockito.when(testDao.search(Mockito.any(SearchCriteria.class), Mockito.any(Filter.class),
|
||||
Mockito.anyBoolean(), Mockito.anyBoolean()))
|
||||
.thenAnswer(invocation -> {
|
||||
capturedFilter[0] = invocation.getArgument(1);
|
||||
return new ArrayList<DbTestVO>();
|
||||
});
|
||||
|
||||
SearchCriteria<DbTestVO> sc = Mockito.mock(SearchCriteria.class);
|
||||
testDao.lockOneRandomRow(sc, true);
|
||||
|
||||
// Verify that the filter uses random ordering
|
||||
Assert.assertNotNull(capturedFilter[0]);
|
||||
Assert.assertNotNull(capturedFilter[0].getOrderBy());
|
||||
Assert.assertTrue(capturedFilter[0].getOrderBy().contains("ORDER BY RAND()"));
|
||||
Assert.assertTrue(capturedFilter[0].getOrderBy().contains("LIMIT 1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLockOneRandomRowReturnsNullOnEmptyResult() {
|
||||
GenericDaoBase<DbTestVO, Long> testDao = Mockito.mock(GenericDaoBase.class);
|
||||
|
||||
Mockito.when(testDao.lockOneRandomRow(Mockito.any(SearchCriteria.class), Mockito.anyBoolean()))
|
||||
.thenCallRealMethod();
|
||||
|
||||
Mockito.when(testDao.search(Mockito.any(SearchCriteria.class), Mockito.any(Filter.class),
|
||||
Mockito.anyBoolean(), Mockito.anyBoolean()))
|
||||
.thenReturn(new ArrayList<DbTestVO>());
|
||||
|
||||
SearchCriteria<DbTestVO> sc = Mockito.mock(SearchCriteria.class);
|
||||
DbTestVO result = testDao.lockOneRandomRow(sc, true);
|
||||
|
||||
Assert.assertNull(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLockOneRandomRowReturnsFirstElement() {
|
||||
GenericDaoBase<DbTestVO, Long> testDao = Mockito.mock(GenericDaoBase.class);
|
||||
DbTestVO expectedResult = new DbTestVO();
|
||||
List<DbTestVO> resultList = new ArrayList<>();
|
||||
resultList.add(expectedResult);
|
||||
|
||||
Mockito.when(testDao.lockOneRandomRow(Mockito.any(SearchCriteria.class), Mockito.anyBoolean()))
|
||||
.thenCallRealMethod();
|
||||
|
||||
Mockito.when(testDao.search(Mockito.any(SearchCriteria.class), Mockito.any(Filter.class),
|
||||
Mockito.anyBoolean(), Mockito.anyBoolean()))
|
||||
.thenReturn(resultList);
|
||||
|
||||
SearchCriteria<DbTestVO> sc = Mockito.mock(SearchCriteria.class);
|
||||
DbTestVO result = testDao.lockOneRandomRow(sc, true);
|
||||
|
||||
Assert.assertNotNull(result);
|
||||
Assert.assertEquals(expectedResult, result);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -429,7 +429,7 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
|
|||
}
|
||||
|
||||
injectPresetVariablesIntoJsInterpreter(jsInterpreter, presetVariables);
|
||||
jsInterpreter.injectVariable("lastTariffs", lastAppliedTariffsList.toString());
|
||||
jsInterpreter.injectVariable("lastTariffs", lastAppliedTariffsList);
|
||||
|
||||
String scriptResult = jsInterpreter.executeScript(activationRule).toString();
|
||||
|
||||
|
|
@ -459,12 +459,12 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
|
|||
protected void injectPresetVariablesIntoJsInterpreter(JsInterpreter jsInterpreter, PresetVariables presetVariables) {
|
||||
jsInterpreter.discardCurrentVariables();
|
||||
|
||||
jsInterpreter.injectVariable("account", presetVariables.getAccount().toString());
|
||||
jsInterpreter.injectVariable("domain", presetVariables.getDomain().toString());
|
||||
jsInterpreter.injectVariable("account", presetVariables.getAccount());
|
||||
jsInterpreter.injectVariable("domain", presetVariables.getDomain());
|
||||
|
||||
GenericPresetVariable project = presetVariables.getProject();
|
||||
if (project != null) {
|
||||
jsInterpreter.injectVariable("project", project.toString());
|
||||
jsInterpreter.injectVariable("project", project);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -474,8 +474,8 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
|
|||
}
|
||||
|
||||
jsInterpreter.injectVariable("resourceType", presetVariables.getResourceType());
|
||||
jsInterpreter.injectVariable("value", presetVariables.getValue().toString());
|
||||
jsInterpreter.injectVariable("zone", presetVariables.getZone().toString());
|
||||
jsInterpreter.injectVariable("value", presetVariables.getValue());
|
||||
jsInterpreter.injectVariable("zone", presetVariables.getZone());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ public class Account extends GenericPresetVariable {
|
|||
|
||||
public void setRole(Role role) {
|
||||
this.role = role;
|
||||
fieldNamesToIncludeInToString.add("role");
|
||||
}
|
||||
|
||||
public String getCreated() {
|
||||
|
|
@ -45,6 +44,5 @@ public class Account extends GenericPresetVariable {
|
|||
|
||||
public void setCreated(Date created) {
|
||||
this.created = DateUtil.displayDateInTimezone(TimeZone.getTimeZone("GMT"), created);
|
||||
fieldNamesToIncludeInToString.add("created");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,5 @@ public class BackupOffering extends GenericPresetVariable {
|
|||
|
||||
public void setExternalId(String externalId) {
|
||||
this.externalId = externalId;
|
||||
fieldNamesToIncludeInToString.add("externalId");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ public class ComputeOffering extends GenericPresetVariable {
|
|||
|
||||
public void setCustomized(boolean customized) {
|
||||
this.customized = customized;
|
||||
fieldNamesToIncludeInToString.add("customized");
|
||||
}
|
||||
|
||||
public boolean offerHa() {
|
||||
|
|
@ -41,7 +40,5 @@ public class ComputeOffering extends GenericPresetVariable {
|
|||
|
||||
public void setOfferHa(boolean offerHa) {
|
||||
this.offerHa = offerHa;
|
||||
fieldNamesToIncludeInToString.add("offerHa");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,5 @@ public class Configuration extends GenericPresetVariable{
|
|||
|
||||
public void setForceHa(boolean forceHa) {
|
||||
this.forceHa = forceHa;
|
||||
fieldNamesToIncludeInToString.add("forceHa");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ public class DiskOfferingPresetVariables extends GenericPresetVariable {
|
|||
|
||||
public void setBytesReadRate(Long bytesReadRate) {
|
||||
this.bytesReadRate = bytesReadRate;
|
||||
fieldNamesToIncludeInToString.add("bytesReadRate");
|
||||
}
|
||||
|
||||
public Long getBytesReadBurst() {
|
||||
|
|
@ -70,7 +69,6 @@ public class DiskOfferingPresetVariables extends GenericPresetVariable {
|
|||
|
||||
public void setBytesReadBurst(Long bytesReadBurst) {
|
||||
this.bytesReadBurst = bytesReadBurst;
|
||||
fieldNamesToIncludeInToString.add("bytesReadBurst");
|
||||
}
|
||||
|
||||
public Long getBytesReadBurstLength() {
|
||||
|
|
@ -79,7 +77,6 @@ public class DiskOfferingPresetVariables extends GenericPresetVariable {
|
|||
|
||||
public void setBytesReadBurstLength(Long bytesReadBurstLength) {
|
||||
this.bytesReadBurstLength = bytesReadBurstLength;
|
||||
fieldNamesToIncludeInToString.add("bytesReadBurstLength");
|
||||
}
|
||||
|
||||
public Long getBytesWriteRate() {
|
||||
|
|
@ -88,7 +85,6 @@ public class DiskOfferingPresetVariables extends GenericPresetVariable {
|
|||
|
||||
public void setBytesWriteRate(Long bytesWriteRate) {
|
||||
this.bytesWriteRate = bytesWriteRate;
|
||||
fieldNamesToIncludeInToString.add("bytesWriteRate");
|
||||
}
|
||||
|
||||
public Long getBytesWriteBurst() {
|
||||
|
|
@ -97,7 +93,6 @@ public class DiskOfferingPresetVariables extends GenericPresetVariable {
|
|||
|
||||
public void setBytesWriteBurst(Long bytesWriteBurst) {
|
||||
this.bytesWriteBurst = bytesWriteBurst;
|
||||
fieldNamesToIncludeInToString.add("bytesWriteBurst");
|
||||
}
|
||||
|
||||
public Long getBytesWriteBurstLength() {
|
||||
|
|
@ -106,7 +101,6 @@ public class DiskOfferingPresetVariables extends GenericPresetVariable {
|
|||
|
||||
public void setBytesWriteBurstLength(Long bytesWriteBurstLength) {
|
||||
this.bytesWriteBurstLength = bytesWriteBurstLength;
|
||||
fieldNamesToIncludeInToString.add("bytesWriteBurstLength");
|
||||
}
|
||||
|
||||
public Long getIopsReadRate() {
|
||||
|
|
@ -115,7 +109,6 @@ public class DiskOfferingPresetVariables extends GenericPresetVariable {
|
|||
|
||||
public void setIopsReadRate(Long iopsReadRate) {
|
||||
this.iopsReadRate = iopsReadRate;
|
||||
fieldNamesToIncludeInToString.add("iopsReadRate");
|
||||
}
|
||||
|
||||
public Long getIopsReadBurst() {
|
||||
|
|
@ -124,7 +117,6 @@ public class DiskOfferingPresetVariables extends GenericPresetVariable {
|
|||
|
||||
public void setIopsReadBurst(Long iopsReadBurst) {
|
||||
this.iopsReadBurst = iopsReadBurst;
|
||||
fieldNamesToIncludeInToString.add("iopsReadBurst");
|
||||
}
|
||||
|
||||
public Long getIopsReadBurstLength() {
|
||||
|
|
@ -133,7 +125,6 @@ public class DiskOfferingPresetVariables extends GenericPresetVariable {
|
|||
|
||||
public void setIopsReadBurstLength(Long iopsReadBurstLength) {
|
||||
this.iopsReadBurstLength = iopsReadBurstLength;
|
||||
fieldNamesToIncludeInToString.add("iopsReadBurstLength");
|
||||
}
|
||||
|
||||
public Long getIopsWriteRate() {
|
||||
|
|
@ -142,7 +133,6 @@ public class DiskOfferingPresetVariables extends GenericPresetVariable {
|
|||
|
||||
public void setIopsWriteRate(Long iopsWriteRate) {
|
||||
this.iopsWriteRate = iopsWriteRate;
|
||||
fieldNamesToIncludeInToString.add("iopsWriteRate");
|
||||
}
|
||||
|
||||
public Long getIopsWriteBurst() {
|
||||
|
|
@ -151,7 +141,6 @@ public class DiskOfferingPresetVariables extends GenericPresetVariable {
|
|||
|
||||
public void setIopsWriteBurst(Long iopsWriteBurst) {
|
||||
this.iopsWriteBurst = iopsWriteBurst;
|
||||
fieldNamesToIncludeInToString.add("iopsWriteBurst");
|
||||
}
|
||||
|
||||
public Long getIopsWriteBurstLength() {
|
||||
|
|
@ -160,6 +149,5 @@ public class DiskOfferingPresetVariables extends GenericPresetVariable {
|
|||
|
||||
public void setIopsWriteBurstLength(Long iopsWriteBurstLength) {
|
||||
this.iopsWriteBurstLength = iopsWriteBurstLength;
|
||||
fieldNamesToIncludeInToString.add("iopsWriteBurstLength");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ public class Domain extends GenericPresetVariable {
|
|||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
fieldNamesToIncludeInToString.add("path");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,10 +17,8 @@
|
|||
|
||||
package org.apache.cloudstack.quota.activationrule.presetvariables;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
public class GenericPresetVariable {
|
||||
@PresetVariableDefinition(description = "ID of the resource.")
|
||||
|
|
@ -29,15 +27,12 @@ public class GenericPresetVariable {
|
|||
@PresetVariableDefinition(description = "Name of the resource.")
|
||||
private String name;
|
||||
|
||||
protected transient Set<String> fieldNamesToIncludeInToString = new HashSet<>();
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
fieldNamesToIncludeInToString.add("id");
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
|
|
@ -46,15 +41,10 @@ public class GenericPresetVariable {
|
|||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
fieldNamesToIncludeInToString.add("name");
|
||||
}
|
||||
|
||||
/***
|
||||
* Converts the preset variable into a valid JSON object that will be injected into the JS interpreter.
|
||||
* This method should not be overridden or changed.
|
||||
*/
|
||||
@Override
|
||||
public final String toString() {
|
||||
return ReflectionToStringBuilderUtils.reflectOnlySelectedFields(this, fieldNamesToIncludeInToString.toArray(new String[0]));
|
||||
public String toString() {
|
||||
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ public class Host extends GenericPresetVariable {
|
|||
|
||||
public void setTags(List<String> tags) {
|
||||
this.tags = tags;
|
||||
fieldNamesToIncludeInToString.add("tags");
|
||||
}
|
||||
|
||||
public Boolean getIsTagARule() {
|
||||
|
|
@ -41,6 +40,5 @@ public class Host extends GenericPresetVariable {
|
|||
|
||||
public void setIsTagARule(Boolean isTagARule) {
|
||||
this.isTagARule = isTagARule;
|
||||
fieldNamesToIncludeInToString.add("isTagARule");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ public class PresetVariableHelper {
|
|||
Role role = new Role();
|
||||
role.setId(roleVo.getUuid());
|
||||
role.setName(roleVo.getName());
|
||||
role.setType(roleVo.getRoleType());
|
||||
role.setType(roleVo.getRoleType().toString());
|
||||
|
||||
return role;
|
||||
}
|
||||
|
|
@ -538,8 +538,8 @@ public class PresetVariableHelper {
|
|||
value.setDiskOffering(getPresetVariableValueDiskOffering(volumeVo.getDiskOfferingId()));
|
||||
value.setId(volumeVo.getUuid());
|
||||
value.setName(volumeVo.getName());
|
||||
value.setProvisioningType(volumeVo.getProvisioningType());
|
||||
value.setVolumeType(volumeVo.getVolumeType());
|
||||
value.setVolumeType(volumeVo.getVolumeType().toString());
|
||||
value.setProvisioningType(volumeVo.getProvisioningType().toString());
|
||||
|
||||
Long poolId = volumeVo.getPoolId();
|
||||
if (poolId == null) {
|
||||
|
|
@ -594,7 +594,7 @@ public class PresetVariableHelper {
|
|||
storage = new Storage();
|
||||
storage.setId(storagePoolVo.getUuid());
|
||||
storage.setName(storagePoolVo.getName());
|
||||
storage.setScope(storagePoolVo.getScope());
|
||||
storage.setScope(storagePoolVo.getScope().toString());
|
||||
List<StoragePoolTagVO> storagePoolTagVOList = storagePoolTagsDao.findStoragePoolTags(storageId);
|
||||
List<String> storageTags = new ArrayList<>();
|
||||
boolean isTagARule = false;
|
||||
|
|
@ -663,7 +663,7 @@ public class PresetVariableHelper {
|
|||
value.setId(snapshotVo.getUuid());
|
||||
value.setName(snapshotVo.getName());
|
||||
value.setSize(ByteScaleUtils.bytesToMebibytes(snapshotVo.getSize()));
|
||||
value.setSnapshotType(Snapshot.Type.values()[snapshotVo.getSnapshotType()]);
|
||||
value.setSnapshotType(Snapshot.Type.values()[snapshotVo.getSnapshotType()].toString());
|
||||
value.setStorage(getPresetVariableValueStorage(getSnapshotDataStoreId(snapshotId, usageRecord.getZoneId()), usageType));
|
||||
value.setTags(getPresetVariableValueResourceTags(snapshotId, ResourceObjectType.Snapshot));
|
||||
Hypervisor.HypervisorType hypervisorType = snapshotVo.getHypervisorType();
|
||||
|
|
@ -732,7 +732,7 @@ public class PresetVariableHelper {
|
|||
value.setId(vmSnapshotVo.getUuid());
|
||||
value.setName(vmSnapshotVo.getName());
|
||||
value.setTags(getPresetVariableValueResourceTags(vmSnapshotId, ResourceObjectType.VMSnapshot));
|
||||
value.setVmSnapshotType(vmSnapshotVo.getType());
|
||||
value.setVmSnapshotType(vmSnapshotVo.getType().toString());
|
||||
|
||||
VMInstanceVO vmVo = vmInstanceDao.findByIdIncludingRemoved(vmSnapshotVo.getVmId());
|
||||
if (vmVo != null && vmVo.getHypervisorType() != null) {
|
||||
|
|
|
|||
|
|
@ -17,19 +17,16 @@
|
|||
|
||||
package org.apache.cloudstack.quota.activationrule.presetvariables;
|
||||
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
|
||||
public class Role extends GenericPresetVariable {
|
||||
@PresetVariableDefinition(description = "Role type of the resource's owner.")
|
||||
private RoleType type;
|
||||
private String type;
|
||||
|
||||
public RoleType getType() {
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(RoleType type) {
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
fieldNamesToIncludeInToString.add("type");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@ package org.apache.cloudstack.quota.activationrule.presetvariables;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.storage.ScopeType;
|
||||
|
||||
public class Storage extends GenericPresetVariable {
|
||||
@PresetVariableDefinition(description = "List of string representing the tags of the storage where the volume is (i.e.: [\"a\", \"b\"]).")
|
||||
private List<String> tags;
|
||||
|
|
@ -29,7 +27,7 @@ public class Storage extends GenericPresetVariable {
|
|||
private Boolean isTagARule;
|
||||
|
||||
@PresetVariableDefinition(description = "Scope of the storage where the volume is. Values can be: ZONE, CLUSTER or HOST. Applicable only for primary storages.")
|
||||
private ScopeType scope;
|
||||
private String scope;
|
||||
|
||||
public List<String> getTags() {
|
||||
return tags;
|
||||
|
|
@ -37,7 +35,6 @@ public class Storage extends GenericPresetVariable {
|
|||
|
||||
public void setTags(List<String> tags) {
|
||||
this.tags = tags;
|
||||
fieldNamesToIncludeInToString.add("tags");
|
||||
}
|
||||
|
||||
public Boolean getIsTagARule() {
|
||||
|
|
@ -46,16 +43,14 @@ public class Storage extends GenericPresetVariable {
|
|||
|
||||
public void setIsTagARule(Boolean isTagARule) {
|
||||
this.isTagARule = isTagARule;
|
||||
fieldNamesToIncludeInToString.add("isTagARule");
|
||||
}
|
||||
|
||||
public ScopeType getScope() {
|
||||
public String getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
public void setScope(ScopeType scope) {
|
||||
public void setScope(String scope) {
|
||||
this.scope = scope;
|
||||
fieldNamesToIncludeInToString.add("scope");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,5 @@ public class Tariff extends GenericPresetVariable {
|
|||
|
||||
public void setValue(BigDecimal value) {
|
||||
this.value = value;
|
||||
fieldNamesToIncludeInToString.add("value");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,10 +20,6 @@ package org.apache.cloudstack.quota.activationrule.presetvariables;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.storage.Snapshot;
|
||||
import com.cloud.storage.Storage.ProvisioningType;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.vm.snapshot.VMSnapshot;
|
||||
import org.apache.cloudstack.quota.constant.QuotaTypes;
|
||||
|
||||
public class Value extends GenericPresetVariable {
|
||||
|
|
@ -61,13 +57,13 @@ public class Value extends GenericPresetVariable {
|
|||
private Long virtualSize;
|
||||
|
||||
@PresetVariableDefinition(description = "Provisioning type of the resource. Values can be: thin, sparse or fat.", supportedTypes = {QuotaTypes.VOLUME})
|
||||
private ProvisioningType provisioningType;
|
||||
private String provisioningType;
|
||||
|
||||
@PresetVariableDefinition(description = "Type of the snapshot. Values can be: MANUAL, RECURRING, HOURLY, DAILY, WEEKLY and MONTHLY.", supportedTypes = {QuotaTypes.SNAPSHOT})
|
||||
private Snapshot.Type snapshotType;
|
||||
private String snapshotType;
|
||||
|
||||
@PresetVariableDefinition(description = "Type of the VM snapshot. Values can be: Disk or DiskAndMemory.", supportedTypes = {QuotaTypes.VM_SNAPSHOT})
|
||||
private VMSnapshot.Type vmSnapshotType;
|
||||
private String vmSnapshotType;
|
||||
|
||||
@PresetVariableDefinition(description = "Computing offering of the VM.", supportedTypes = {QuotaTypes.RUNNING_VM, QuotaTypes.ALLOCATED_VM})
|
||||
private ComputeOffering computeOffering;
|
||||
|
|
@ -96,7 +92,7 @@ public class Value extends GenericPresetVariable {
|
|||
private String volumeFormat;
|
||||
|
||||
@PresetVariableDefinition(description = "The volume type. Values can be: UNKNOWN, ROOT, SWAP, DATADISK and ISO.", supportedTypes = {QuotaTypes.VOLUME})
|
||||
private Volume.Type volumeType;
|
||||
private String volumeType;
|
||||
|
||||
private String state;
|
||||
|
||||
|
|
@ -106,7 +102,6 @@ public class Value extends GenericPresetVariable {
|
|||
|
||||
public void setHost(Host host) {
|
||||
this.host = host;
|
||||
fieldNamesToIncludeInToString.add("host");
|
||||
}
|
||||
|
||||
public String getOsName() {
|
||||
|
|
@ -115,7 +110,6 @@ public class Value extends GenericPresetVariable {
|
|||
|
||||
public void setOsName(String osName) {
|
||||
this.osName = osName;
|
||||
fieldNamesToIncludeInToString.add("osName");
|
||||
}
|
||||
|
||||
public List<Resource> getAccountResources() {
|
||||
|
|
@ -124,7 +118,6 @@ public class Value extends GenericPresetVariable {
|
|||
|
||||
public void setAccountResources(List<Resource> accountResources) {
|
||||
this.accountResources = accountResources;
|
||||
fieldNamesToIncludeInToString.add("accountResources");
|
||||
}
|
||||
|
||||
public Map<String, String> getTags() {
|
||||
|
|
@ -133,7 +126,6 @@ public class Value extends GenericPresetVariable {
|
|||
|
||||
public void setTags(Map<String, String> tags) {
|
||||
this.tags = tags;
|
||||
fieldNamesToIncludeInToString.add("tags");
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
|
|
@ -142,7 +134,6 @@ public class Value extends GenericPresetVariable {
|
|||
|
||||
public void setTag(String tag) {
|
||||
this.tag = tag;
|
||||
fieldNamesToIncludeInToString.add("tag");
|
||||
}
|
||||
|
||||
public Long getSize() {
|
||||
|
|
@ -151,34 +142,30 @@ public class Value extends GenericPresetVariable {
|
|||
|
||||
public void setSize(Long size) {
|
||||
this.size = size;
|
||||
fieldNamesToIncludeInToString.add("size");
|
||||
}
|
||||
|
||||
public ProvisioningType getProvisioningType() {
|
||||
public String getProvisioningType() {
|
||||
return provisioningType;
|
||||
}
|
||||
|
||||
public void setProvisioningType(ProvisioningType provisioningType) {
|
||||
public void setProvisioningType(String provisioningType) {
|
||||
this.provisioningType = provisioningType;
|
||||
fieldNamesToIncludeInToString.add("provisioningType");
|
||||
}
|
||||
|
||||
public Snapshot.Type getSnapshotType() {
|
||||
public String getSnapshotType() {
|
||||
return snapshotType;
|
||||
}
|
||||
|
||||
public void setSnapshotType(Snapshot.Type snapshotType) {
|
||||
public void setSnapshotType(String snapshotType) {
|
||||
this.snapshotType = snapshotType;
|
||||
fieldNamesToIncludeInToString.add("snapshotType");
|
||||
}
|
||||
|
||||
public VMSnapshot.Type getVmSnapshotType() {
|
||||
public String getVmSnapshotType() {
|
||||
return vmSnapshotType;
|
||||
}
|
||||
|
||||
public void setVmSnapshotType(VMSnapshot.Type vmSnapshotType) {
|
||||
public void setVmSnapshotType(String vmSnapshotType) {
|
||||
this.vmSnapshotType = vmSnapshotType;
|
||||
fieldNamesToIncludeInToString.add("vmSnapshotType");
|
||||
}
|
||||
|
||||
public ComputeOffering getComputeOffering() {
|
||||
|
|
@ -187,7 +174,6 @@ public class Value extends GenericPresetVariable {
|
|||
|
||||
public void setComputeOffering(ComputeOffering computeOffering) {
|
||||
this.computeOffering = computeOffering;
|
||||
fieldNamesToIncludeInToString.add("computeOffering");
|
||||
}
|
||||
|
||||
public GenericPresetVariable getTemplate() {
|
||||
|
|
@ -196,7 +182,6 @@ public class Value extends GenericPresetVariable {
|
|||
|
||||
public void setTemplate(GenericPresetVariable template) {
|
||||
this.template = template;
|
||||
fieldNamesToIncludeInToString.add("template");
|
||||
}
|
||||
|
||||
public DiskOfferingPresetVariables getDiskOffering() {
|
||||
|
|
@ -205,7 +190,6 @@ public class Value extends GenericPresetVariable {
|
|||
|
||||
public void setDiskOffering(DiskOfferingPresetVariables diskOffering) {
|
||||
this.diskOffering = diskOffering;
|
||||
fieldNamesToIncludeInToString.add("diskOffering");
|
||||
}
|
||||
|
||||
public Storage getStorage() {
|
||||
|
|
@ -214,7 +198,6 @@ public class Value extends GenericPresetVariable {
|
|||
|
||||
public void setStorage(Storage storage) {
|
||||
this.storage = storage;
|
||||
fieldNamesToIncludeInToString.add("storage");
|
||||
}
|
||||
|
||||
public ComputingResources getComputingResources() {
|
||||
|
|
@ -223,7 +206,6 @@ public class Value extends GenericPresetVariable {
|
|||
|
||||
public void setComputingResources(ComputingResources computingResources) {
|
||||
this.computingResources = computingResources;
|
||||
fieldNamesToIncludeInToString.add("computingResources");
|
||||
}
|
||||
|
||||
public Long getVirtualSize() {
|
||||
|
|
@ -232,7 +214,6 @@ public class Value extends GenericPresetVariable {
|
|||
|
||||
public void setVirtualSize(Long virtualSize) {
|
||||
this.virtualSize = virtualSize;
|
||||
fieldNamesToIncludeInToString.add("virtualSize");
|
||||
}
|
||||
|
||||
public BackupOffering getBackupOffering() {
|
||||
|
|
@ -241,12 +222,10 @@ public class Value extends GenericPresetVariable {
|
|||
|
||||
public void setBackupOffering(BackupOffering backupOffering) {
|
||||
this.backupOffering = backupOffering;
|
||||
fieldNamesToIncludeInToString.add("backupOffering");
|
||||
}
|
||||
|
||||
public void setHypervisorType(String hypervisorType) {
|
||||
this.hypervisorType = hypervisorType;
|
||||
fieldNamesToIncludeInToString.add("hypervisorType");
|
||||
}
|
||||
|
||||
public String getHypervisorType() {
|
||||
|
|
@ -255,20 +234,18 @@ public class Value extends GenericPresetVariable {
|
|||
|
||||
public void setVolumeFormat(String volumeFormat) {
|
||||
this.volumeFormat = volumeFormat;
|
||||
fieldNamesToIncludeInToString.add("volumeFormat");
|
||||
}
|
||||
|
||||
public String getVolumeFormat() {
|
||||
return volumeFormat;
|
||||
}
|
||||
|
||||
public Volume.Type getVolumeType() {
|
||||
public String getVolumeType() {
|
||||
return volumeType;
|
||||
}
|
||||
|
||||
public void setVolumeType(Volume.Type volumeType) {
|
||||
public void setVolumeType(String volumeType) {
|
||||
this.volumeType = volumeType;
|
||||
fieldNamesToIncludeInToString.add("volumeType");
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
|
|
@ -277,6 +254,5 @@ public class Value extends GenericPresetVariable {
|
|||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
fieldNamesToIncludeInToString.add("state");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -267,12 +267,12 @@ public class QuotaManagerImplTest {
|
|||
|
||||
quotaManagerImplSpy.injectPresetVariablesIntoJsInterpreter(jsInterpreterMock, presetVariablesMock);
|
||||
|
||||
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("account"), Mockito.anyString());
|
||||
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("domain"), Mockito.anyString());
|
||||
Mockito.verify(jsInterpreterMock, Mockito.never()).injectVariable(Mockito.eq("project"), Mockito.anyString());
|
||||
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("resourceType"), Mockito.anyString());
|
||||
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("value"), Mockito.anyString());
|
||||
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("zone"), Mockito.anyString());
|
||||
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("account"), Mockito.any());
|
||||
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("domain"), Mockito.any());
|
||||
Mockito.verify(jsInterpreterMock, Mockito.never()).injectVariable(Mockito.eq("project"), Mockito.any());
|
||||
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("resourceType"), Mockito.any());
|
||||
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("value"), Mockito.any());
|
||||
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("zone"), Mockito.any());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -288,12 +288,12 @@ public class QuotaManagerImplTest {
|
|||
|
||||
quotaManagerImplSpy.injectPresetVariablesIntoJsInterpreter(jsInterpreterMock, presetVariablesMock);
|
||||
|
||||
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("account"), Mockito.anyString());
|
||||
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("domain"), Mockito.anyString());
|
||||
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("project"), Mockito.anyString());
|
||||
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("resourceType"), Mockito.anyString());
|
||||
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("value"), Mockito.anyString());
|
||||
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("zone"), Mockito.anyString());
|
||||
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("account"), Mockito.any());
|
||||
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("domain"), Mockito.any());
|
||||
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("project"), Mockito.any());
|
||||
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("resourceType"), Mockito.any());
|
||||
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("value"), Mockito.any());
|
||||
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("zone"), Mockito.any());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -1,34 +0,0 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.quota.activationrule.presetvariables;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class AccountTest {
|
||||
|
||||
@Test
|
||||
public void setRoleTestAddFieldRoleToCollection() {
|
||||
Account variable = new Account();
|
||||
variable.setRole(null);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("role"));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.apache.cloudstack.quota.activationrule.presetvariables;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class BackupOfferingTest {
|
||||
@Test
|
||||
public void setExternalIdTestAddFieldExternalIdToCollection() {
|
||||
BackupOffering backupOffering = new BackupOffering();
|
||||
backupOffering.setExternalId("any-external-id");
|
||||
Assert.assertTrue(backupOffering.fieldNamesToIncludeInToString.contains("externalId"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.quota.activationrule.presetvariables;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ComputeOfferingTest {
|
||||
|
||||
@Test
|
||||
public void setCustomizedTestAddFieldCustomizedToCollection() {
|
||||
ComputeOffering variable = new ComputeOffering();
|
||||
variable.setCustomized(true);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("customized"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.quota.activationrule.presetvariables;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ComputingResourcesTest {
|
||||
|
||||
@Test
|
||||
public void toStringTestReturnAJson() {
|
||||
ComputingResources variable = new ComputingResources();
|
||||
|
||||
String expected = ToStringBuilder.reflectionToString(variable, ToStringStyle.JSON_STYLE);
|
||||
String result = variable.toString();
|
||||
|
||||
Assert.assertEquals(expected, result);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.quota.activationrule.presetvariables;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class DomainTest {
|
||||
|
||||
@Test
|
||||
public void setPathTestAddFieldPathToCollection() {
|
||||
Domain variable = new Domain();
|
||||
variable.setPath("test path");
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("path"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.quota.activationrule.presetvariables;
|
||||
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class GenericPresetVariableTest {
|
||||
|
||||
@Test
|
||||
public void setIdTestAddFieldIdToCollection() {
|
||||
GenericPresetVariable variable = new GenericPresetVariable();
|
||||
variable.setId("test");
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("id"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setNameTestAddFieldNameToCollection() {
|
||||
GenericPresetVariable variable = new GenericPresetVariable();
|
||||
variable.setName("test");
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("name"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toStringTestSetAllFieldsAndReturnAJson() {
|
||||
GenericPresetVariable variable = new GenericPresetVariable();
|
||||
variable.setId("test id");
|
||||
variable.setName("test name");
|
||||
|
||||
String expected = ReflectionToStringBuilderUtils.reflectOnlySelectedFields(variable, "id", "name");
|
||||
String result = variable.toString();
|
||||
|
||||
Assert.assertEquals(expected, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toStringTestSetSomeFieldsAndReturnAJson() {
|
||||
GenericPresetVariable variable = new GenericPresetVariable();
|
||||
variable.setId("test id");
|
||||
|
||||
String expected = ReflectionToStringBuilderUtils.reflectOnlySelectedFields(variable, "id");
|
||||
String result = variable.toString();
|
||||
|
||||
Assert.assertEquals(expected, result);
|
||||
|
||||
variable = new GenericPresetVariable();
|
||||
variable.setName("test name");
|
||||
|
||||
expected = ReflectionToStringBuilderUtils.reflectOnlySelectedFields(variable, "name");
|
||||
result = variable.toString();
|
||||
|
||||
Assert.assertEquals(expected, result);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.quota.activationrule.presetvariables;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class HostTest {
|
||||
|
||||
@Test
|
||||
public void setTagsTestAddFieldTagsToCollection() {
|
||||
Host variable = new Host();
|
||||
variable.setTags(null);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("tags"));
|
||||
}
|
||||
}
|
||||
|
|
@ -215,14 +215,14 @@ public class PresetVariableHelperTest {
|
|||
value.setTags(Collections.singletonMap("tag1", "value1"));
|
||||
value.setTemplate(getGenericPresetVariableForTests());
|
||||
value.setDiskOffering(getDiskOfferingForTests());
|
||||
value.setProvisioningType(ProvisioningType.THIN);
|
||||
value.setProvisioningType(ProvisioningType.THIN.toString());
|
||||
value.setStorage(getStorageForTests());
|
||||
value.setSize(ByteScaleUtils.GiB);
|
||||
value.setSnapshotType(Snapshot.Type.HOURLY);
|
||||
value.setSnapshotType(Snapshot.Type.HOURLY.toString());
|
||||
value.setTag("tag_test");
|
||||
value.setVmSnapshotType(VMSnapshot.Type.Disk);
|
||||
value.setVmSnapshotType(VMSnapshot.Type.Disk.toString());
|
||||
value.setComputingResources(getComputingResourcesForTests());
|
||||
value.setVolumeType(Volume.Type.DATADISK);
|
||||
value.setVolumeType(Volume.Type.DATADISK.toString());
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
@ -272,7 +272,7 @@ public class PresetVariableHelperTest {
|
|||
storage.setId("storage_id");
|
||||
storage.setName("storage_name");
|
||||
storage.setTags(Arrays.asList("tag1", "tag2"));
|
||||
storage.setScope(ScopeType.ZONE);
|
||||
storage.setScope(ScopeType.ZONE.toString());
|
||||
return storage;
|
||||
}
|
||||
|
||||
|
|
@ -298,9 +298,9 @@ public class PresetVariableHelperTest {
|
|||
|
||||
private List<VMInstanceDetailVO> getVmDetailsForTests() {
|
||||
List<VMInstanceDetailVO> details = new LinkedList<>();
|
||||
details.add(new VMInstanceDetailVO(1l, "test_with_value", "277", false));
|
||||
details.add(new VMInstanceDetailVO(1l, "test_with_invalid_value", "invalid", false));
|
||||
details.add(new VMInstanceDetailVO(1l, "test_with_null", null, false));
|
||||
details.add(new VMInstanceDetailVO(1L, "test_with_value", "277", false));
|
||||
details.add(new VMInstanceDetailVO(1L, "test_with_invalid_value", "invalid", false));
|
||||
details.add(new VMInstanceDetailVO(1L, "test_with_null", null, false));
|
||||
return details;
|
||||
}
|
||||
|
||||
|
|
@ -309,13 +309,6 @@ public class PresetVariableHelperTest {
|
|||
Assert.assertEquals(expected.getName(), result.getName());
|
||||
}
|
||||
|
||||
private void validateFieldNamesToIncludeInToString(List<String> expected, GenericPresetVariable resultObject) {
|
||||
List<String> result = new ArrayList<>(resultObject.fieldNamesToIncludeInToString);
|
||||
Collections.sort(expected);
|
||||
Collections.sort(result);
|
||||
Assert.assertEquals(expected, result);
|
||||
}
|
||||
|
||||
private BackupOffering getBackupOfferingForTests() {
|
||||
BackupOffering backupOffering = new BackupOffering();
|
||||
backupOffering.setId("backup_offering_id");
|
||||
|
|
@ -415,7 +408,6 @@ public class PresetVariableHelperTest {
|
|||
|
||||
Assert.assertNotNull(result.getProject());
|
||||
assertPresetVariableIdAndName(account, result.getProject());
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("id", "name"), result.getProject());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -430,10 +422,9 @@ public class PresetVariableHelperTest {
|
|||
Mockito.doReturn(account.getName()).when(accountVoMock).getName();
|
||||
Mockito.doReturn(account.getCreated()).when(accountVoMock).getCreated();
|
||||
|
||||
Account result = presetVariableHelperSpy.getPresetVariableAccount(1l);
|
||||
Account result = presetVariableHelperSpy.getPresetVariableAccount(1L);
|
||||
|
||||
assertPresetVariableIdAndName(account, result);
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("created", "id", "name"), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -463,18 +454,16 @@ public class PresetVariableHelperTest {
|
|||
Role role = new Role();
|
||||
role.setId("test_id");
|
||||
role.setName("test_name");
|
||||
role.setType(roleType);
|
||||
role.setType(roleType.toString());
|
||||
|
||||
Mockito.doReturn(role.getId()).when(roleVoMock).getUuid();
|
||||
Mockito.doReturn(role.getName()).when(roleVoMock).getName();
|
||||
Mockito.doReturn(role.getType()).when(roleVoMock).getRoleType();
|
||||
Mockito.doReturn(RoleType.fromString(role.getType())).when(roleVoMock).getRoleType();
|
||||
|
||||
Role result = presetVariableHelperSpy.getPresetVariableRole(1l);
|
||||
Role result = presetVariableHelperSpy.getPresetVariableRole(1L);
|
||||
|
||||
assertPresetVariableIdAndName(role, result);
|
||||
Assert.assertEquals(role.getType(), result.getType());
|
||||
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("id", "name", "type"), result);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -489,12 +478,10 @@ public class PresetVariableHelperTest {
|
|||
Mockito.doReturn(domain.getName()).when(domainVoMock).getName();
|
||||
Mockito.doReturn(domain.getPath()).when(domainVoMock).getPath();
|
||||
|
||||
Domain result = presetVariableHelperSpy.getPresetVariableDomain(1l);
|
||||
Domain result = presetVariableHelperSpy.getPresetVariableDomain(1L);
|
||||
|
||||
assertPresetVariableIdAndName(domain, result);
|
||||
Assert.assertEquals(domain.getPath(), result.getPath());
|
||||
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("id", "name", "path"), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -507,10 +494,9 @@ public class PresetVariableHelperTest {
|
|||
Mockito.doReturn(expected.getId()).when(dataCenterVoMock).getUuid();
|
||||
Mockito.doReturn(expected.getName()).when(dataCenterVoMock).getName();
|
||||
|
||||
GenericPresetVariable result = presetVariableHelperSpy.getPresetVariableZone(1l);
|
||||
GenericPresetVariable result = presetVariableHelperSpy.getPresetVariableZone(1L);
|
||||
|
||||
assertPresetVariableIdAndName(expected, result);
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("id", "name"), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -531,7 +517,6 @@ public class PresetVariableHelperTest {
|
|||
Value result = presetVariableHelperSpy.getPresetVariableValue(usageVoMock);
|
||||
|
||||
Assert.assertEquals(resources, result.getAccountResources());
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("accountResources"), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -541,7 +526,7 @@ public class PresetVariableHelperTest {
|
|||
Mockito.doReturn(new Date()).when(usageVoMock).getEndDate();
|
||||
Mockito.doReturn(expected).when(usageDaoMock).listAccountResourcesInThePeriod(Mockito.anyLong(), Mockito.anyInt(), Mockito.any(Date.class), Mockito.any(Date.class));
|
||||
|
||||
List<Resource> result = presetVariableHelperSpy.getPresetVariableAccountResources(usageVoMock, 1l, 0);
|
||||
List<Resource> result = presetVariableHelperSpy.getPresetVariableAccountResources(usageVoMock, 1L, 0);
|
||||
|
||||
for (int i = 0; i < expected.size(); i++) {
|
||||
Assert.assertEquals(expected.get(i).first(), result.get(i).getZoneId());
|
||||
|
|
@ -590,8 +575,6 @@ public class PresetVariableHelperTest {
|
|||
Assert.assertEquals(expected.getTags(), result.getTags());
|
||||
Assert.assertEquals(expected.getTemplate(), result.getTemplate());
|
||||
Assert.assertEquals(hypervisorType.name(), result.getHypervisorType());
|
||||
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("id", "name", "osName", "tags", "template", "hypervisorType"), result);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -614,7 +597,6 @@ public class PresetVariableHelperTest {
|
|||
public void setPresetVariableHostInValueIfUsageTypeIsRunningVmTestQuotaTypeIsRunningVmSetHost() {
|
||||
Value result = new Value();
|
||||
Host expectedHost = getHostForTests();
|
||||
List<HostTagVO> expectedHostTags = getHostTagsForTests();
|
||||
|
||||
Mockito.doReturn(expectedHost).when(presetVariableHelperSpy).getPresetVariableValueHost(Mockito.anyLong());
|
||||
presetVariableHelperSpy.setPresetVariableHostInValueIfUsageTypeIsRunningVm(result, UsageTypes.RUNNING_VM, vmInstanceVoMock);
|
||||
|
|
@ -623,7 +605,6 @@ public class PresetVariableHelperTest {
|
|||
|
||||
assertPresetVariableIdAndName(expectedHost, result.getHost());
|
||||
Assert.assertEquals(expectedHost.getTags(), result.getHost().getTags());
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("host"), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -638,11 +619,10 @@ public class PresetVariableHelperTest {
|
|||
Mockito.doReturn(expected.getName()).when(hostVoMock).getName();
|
||||
Mockito.doReturn(hostTagVOListMock).when(hostTagsDaoMock).getHostTags(Mockito.anyLong());
|
||||
|
||||
Host result = presetVariableHelperSpy.getPresetVariableValueHost(1l);
|
||||
Host result = presetVariableHelperSpy.getPresetVariableValueHost(1L);
|
||||
|
||||
assertPresetVariableIdAndName(expected, result);
|
||||
Assert.assertEquals(expected.getTags(), result.getTags());
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("id", "isTagARule", "name", "tags"), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -657,12 +637,11 @@ public class PresetVariableHelperTest {
|
|||
Mockito.doReturn(expected.getName()).when(hostVoMock).getName();
|
||||
Mockito.doReturn(hostTagVOListMock).when(hostTagsDaoMock).getHostTags(Mockito.anyLong());
|
||||
|
||||
Host result = presetVariableHelperSpy.getPresetVariableValueHost(1l);
|
||||
Host result = presetVariableHelperSpy.getPresetVariableValueHost(1L);
|
||||
|
||||
assertPresetVariableIdAndName(expected, result);
|
||||
Assert.assertEquals(new ArrayList<>(), result.getTags());
|
||||
Assert.assertTrue(result.getIsTagARule());
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("id", "isTagARule", "name", "tags"), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -674,7 +653,7 @@ public class PresetVariableHelperTest {
|
|||
String expected = "os_display_name";
|
||||
Mockito.doReturn(expected).when(guestOsVoMock).getDisplayName();
|
||||
|
||||
String result = presetVariableHelperSpy.getPresetVariableValueOsName(1l);
|
||||
String result = presetVariableHelperSpy.getPresetVariableValueOsName(1L);
|
||||
|
||||
Assert.assertEquals(expected, result);
|
||||
}
|
||||
|
|
@ -692,7 +671,6 @@ public class PresetVariableHelperTest {
|
|||
assertPresetVariableIdAndName(expected, result);
|
||||
Assert.assertEquals(expected.isCustomized(), result.isCustomized());
|
||||
Assert.assertEquals(expected.offerHa(), result.offerHa());
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("id", "name", "customized", "offerHa"), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -706,10 +684,8 @@ public class PresetVariableHelperTest {
|
|||
|
||||
assertPresetVariableIdAndName(expected, result);
|
||||
Assert.assertEquals(expected.isCustomized(), result.isCustomized());
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("id", "name", "customized"), result);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void getPresetVariableValueTemplateTestSetValuesAndReturnObject() {
|
||||
VMTemplateVO vmTemplateVoMock = Mockito.mock(VMTemplateVO.class);
|
||||
|
|
@ -720,10 +696,9 @@ public class PresetVariableHelperTest {
|
|||
Mockito.doReturn(expected.getId()).when(vmTemplateVoMock).getUuid();
|
||||
Mockito.doReturn(expected.getName()).when(vmTemplateVoMock).getName();
|
||||
|
||||
GenericPresetVariable result = presetVariableHelperSpy.getPresetVariableValueTemplate(1l);
|
||||
GenericPresetVariable result = presetVariableHelperSpy.getPresetVariableValueTemplate(1L);
|
||||
|
||||
assertPresetVariableIdAndName(expected, result);
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("id", "name"), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -735,7 +710,7 @@ public class PresetVariableHelperTest {
|
|||
Mockito.doReturn(listExpected).when(resourceTagDaoMock).listBy(Mockito.anyLong(), Mockito.any(ResourceObjectType.class));
|
||||
|
||||
Arrays.asList(ResourceObjectType.values()).forEach(type -> {
|
||||
Map<String, String> result = presetVariableHelperSpy.getPresetVariableValueResourceTags(1l, type);
|
||||
Map<String, String> result = presetVariableHelperSpy.getPresetVariableValueResourceTags(1L, type);
|
||||
|
||||
for (ResourceTag expected: listExpected) {
|
||||
Assert.assertEquals(expected.getValue(), result.get(expected.getKey()));
|
||||
|
|
@ -760,15 +735,15 @@ public class PresetVariableHelperTest {
|
|||
|
||||
VolumeVO volumeVoMock = Mockito.mock(VolumeVO.class);
|
||||
Mockito.doReturn(volumeVoMock).when(volumeDaoMock).findByIdIncludingRemoved(Mockito.anyLong());
|
||||
Mockito.doReturn(1l).when(volumeVoMock).getPoolId();
|
||||
Mockito.doReturn(1L).when(volumeVoMock).getPoolId();
|
||||
|
||||
mockMethodValidateIfObjectIsNull();
|
||||
|
||||
Mockito.doReturn(expected.getId()).when(volumeVoMock).getUuid();
|
||||
Mockito.doReturn(expected.getName()).when(volumeVoMock).getName();
|
||||
Mockito.doReturn(expected.getDiskOffering()).when(presetVariableHelperSpy).getPresetVariableValueDiskOffering(Mockito.anyLong());
|
||||
Mockito.doReturn(expected.getProvisioningType()).when(volumeVoMock).getProvisioningType();
|
||||
Mockito.doReturn(expected.getVolumeType()).when(volumeVoMock).getVolumeType();
|
||||
Mockito.doReturn(ProvisioningType.getProvisioningType(expected.getProvisioningType())).when(volumeVoMock).getProvisioningType();
|
||||
Mockito.doReturn(Volume.Type.valueOf(expected.getVolumeType())).when(volumeVoMock).getVolumeType();
|
||||
Mockito.doReturn(expected.getStorage()).when(presetVariableHelperSpy).getPresetVariableValueStorage(Mockito.anyLong(), Mockito.anyInt());
|
||||
Mockito.doReturn(expected.getTags()).when(presetVariableHelperSpy).getPresetVariableValueResourceTags(Mockito.anyLong(), Mockito.any(ResourceObjectType.class));
|
||||
Mockito.doReturn(expected.getSize()).when(volumeVoMock).getSize();
|
||||
|
|
@ -789,8 +764,6 @@ public class PresetVariableHelperTest {
|
|||
Assert.assertEquals(expected.getTags(), result.getTags());
|
||||
Assert.assertEquals(expectedSize, result.getSize());
|
||||
Assert.assertEquals(imageFormat.name(), result.getVolumeFormat());
|
||||
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("id", "name", "diskOffering", "provisioningType", "volumeType", "storage", "tags", "size", "volumeFormat"), result);
|
||||
}
|
||||
|
||||
Mockito.verify(presetVariableHelperSpy, Mockito.times(ImageFormat.values().length)).getPresetVariableValueResourceTags(Mockito.anyLong(),
|
||||
|
|
@ -811,8 +784,8 @@ public class PresetVariableHelperTest {
|
|||
Mockito.doReturn(expected.getId()).when(volumeVoMock).getUuid();
|
||||
Mockito.doReturn(expected.getName()).when(volumeVoMock).getName();
|
||||
Mockito.doReturn(expected.getDiskOffering()).when(presetVariableHelperSpy).getPresetVariableValueDiskOffering(Mockito.anyLong());
|
||||
Mockito.doReturn(expected.getProvisioningType()).when(volumeVoMock).getProvisioningType();
|
||||
Mockito.doReturn(expected.getVolumeType()).when(volumeVoMock).getVolumeType();
|
||||
Mockito.doReturn(Volume.Type.valueOf(expected.getVolumeType())).when(volumeVoMock).getVolumeType();
|
||||
Mockito.doReturn(ProvisioningType.getProvisioningType(expected.getProvisioningType())).when(volumeVoMock).getProvisioningType();
|
||||
Mockito.doReturn(expected.getTags()).when(presetVariableHelperSpy).getPresetVariableValueResourceTags(Mockito.anyLong(), Mockito.any(ResourceObjectType.class));
|
||||
Mockito.doReturn(expected.getSize()).when(volumeVoMock).getSize();
|
||||
Mockito.doReturn(imageFormat).when(volumeVoMock).getFormat();
|
||||
|
|
@ -832,8 +805,6 @@ public class PresetVariableHelperTest {
|
|||
Assert.assertEquals(expected.getTags(), result.getTags());
|
||||
Assert.assertEquals(expectedSize, result.getSize());
|
||||
Assert.assertEquals(imageFormat.name(), result.getVolumeFormat());
|
||||
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("id", "name", "diskOffering", "provisioningType", "volumeType", "tags", "size", "volumeFormat"), result);
|
||||
}
|
||||
|
||||
Mockito.verify(presetVariableHelperSpy, Mockito.times(ImageFormat.values().length)).getPresetVariableValueResourceTags(Mockito.anyLong(),
|
||||
|
|
@ -850,11 +821,9 @@ public class PresetVariableHelperTest {
|
|||
Mockito.doReturn(expected.getId()).when(diskOfferingVoMock).getUuid();
|
||||
Mockito.doReturn(expected.getName()).when(diskOfferingVoMock).getName();
|
||||
|
||||
GenericPresetVariable result = presetVariableHelperSpy.getPresetVariableValueDiskOffering(1l);
|
||||
GenericPresetVariable result = presetVariableHelperSpy.getPresetVariableValueDiskOffering(1L);
|
||||
|
||||
assertPresetVariableIdAndName(expected, result);
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("bytesReadBurst", "bytesReadBurstLength", "bytesReadRate", "bytesWriteBurst", "bytesWriteBurstLength", "bytesWriteRate",
|
||||
"id", "iopsReadBurst", "iopsReadBurstLength", "iopsReadRate", "iopsWriteBurst", "iopsWriteBurstLength", "iopsWriteRate", "name"), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -862,7 +831,7 @@ public class PresetVariableHelperTest {
|
|||
Storage expected = getStorageForTests();
|
||||
Mockito.doReturn(expected).when(presetVariableHelperSpy).getSecondaryStorageForSnapshot(Mockito.anyLong(), Mockito.anyInt());
|
||||
|
||||
Storage result = presetVariableHelperSpy.getPresetVariableValueStorage(1l, 2);
|
||||
Storage result = presetVariableHelperSpy.getPresetVariableValueStorage(1L, 2);
|
||||
|
||||
Assert.assertEquals(expected, result);
|
||||
Mockito.verify(primaryStorageDaoMock, Mockito.never()).findByIdIncludingRemoved(Mockito.anyLong());
|
||||
|
|
@ -880,16 +849,14 @@ public class PresetVariableHelperTest {
|
|||
|
||||
Mockito.doReturn(expected.getId()).when(storagePoolVoMock).getUuid();
|
||||
Mockito.doReturn(expected.getName()).when(storagePoolVoMock).getName();
|
||||
Mockito.doReturn(expected.getScope()).when(storagePoolVoMock).getScope();
|
||||
Mockito.doReturn(ScopeType.validateAndGetScopeType(expected.getScope())).when(storagePoolVoMock).getScope();
|
||||
Mockito.doReturn(storageTagVOListMock).when(storagePoolTagsDaoMock).findStoragePoolTags(Mockito.anyLong());
|
||||
|
||||
Storage result = presetVariableHelperSpy.getPresetVariableValueStorage(1l, 2);
|
||||
Storage result = presetVariableHelperSpy.getPresetVariableValueStorage(1L, 2);
|
||||
|
||||
assertPresetVariableIdAndName(expected, result);
|
||||
Assert.assertEquals(expected.getScope(), result.getScope());
|
||||
Assert.assertEquals(expected.getTags(), result.getTags());
|
||||
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("id", "isTagARule", "name", "scope", "tags"), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -904,24 +871,22 @@ public class PresetVariableHelperTest {
|
|||
|
||||
Mockito.doReturn(expected.getId()).when(storagePoolVoMock).getUuid();
|
||||
Mockito.doReturn(expected.getName()).when(storagePoolVoMock).getName();
|
||||
Mockito.doReturn(expected.getScope()).when(storagePoolVoMock).getScope();
|
||||
Mockito.doReturn(ScopeType.validateAndGetScopeType(expected.getScope())).when(storagePoolVoMock).getScope();
|
||||
Mockito.doReturn(storageTagVOListMock).when(storagePoolTagsDaoMock).findStoragePoolTags(Mockito.anyLong());
|
||||
|
||||
Storage result = presetVariableHelperSpy.getPresetVariableValueStorage(1l, 2);
|
||||
Storage result = presetVariableHelperSpy.getPresetVariableValueStorage(1L, 2);
|
||||
|
||||
assertPresetVariableIdAndName(expected, result);
|
||||
Assert.assertEquals(expected.getScope(), result.getScope());
|
||||
Assert.assertEquals(new ArrayList<>(), result.getTags());
|
||||
Assert.assertTrue(result.getIsTagARule());
|
||||
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("id", "isTagARule", "name", "scope", "tags"), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSecondaryStorageForSnapshotTestAllTypesAndDoNotBackupSnapshotReturnNull() {
|
||||
presetVariableHelperSpy.backupSnapshotAfterTakingSnapshot = false;
|
||||
getQuotaTypesForTests().forEach(type -> {
|
||||
Storage result = presetVariableHelperSpy.getSecondaryStorageForSnapshot(1l, type.getKey());
|
||||
Storage result = presetVariableHelperSpy.getSecondaryStorageForSnapshot(1L, type.getKey());
|
||||
Assert.assertNull(result);
|
||||
});
|
||||
}
|
||||
|
|
@ -930,7 +895,7 @@ public class PresetVariableHelperTest {
|
|||
public void getSecondaryStorageForSnapshotTestAllTypesExceptSnapshotAndBackupSnapshotReturnNull() {
|
||||
presetVariableHelperSpy.backupSnapshotAfterTakingSnapshot = true;
|
||||
getQuotaTypesForTests(UsageTypes.SNAPSHOT).forEach(type -> {
|
||||
Storage result = presetVariableHelperSpy.getSecondaryStorageForSnapshot(1l, type.getKey());
|
||||
Storage result = presetVariableHelperSpy.getSecondaryStorageForSnapshot(1L, type.getKey());
|
||||
Assert.assertNull(result);
|
||||
});
|
||||
}
|
||||
|
|
@ -947,10 +912,9 @@ public class PresetVariableHelperTest {
|
|||
Mockito.doReturn(expected.getName()).when(imageStoreVoMock).getName();
|
||||
presetVariableHelperSpy.backupSnapshotAfterTakingSnapshot = true;
|
||||
|
||||
Storage result = presetVariableHelperSpy.getSecondaryStorageForSnapshot(1l, UsageTypes.SNAPSHOT);
|
||||
Storage result = presetVariableHelperSpy.getSecondaryStorageForSnapshot(1L, UsageTypes.SNAPSHOT);
|
||||
|
||||
assertPresetVariableIdAndName(expected, result);
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("id", "name"), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -991,8 +955,6 @@ public class PresetVariableHelperTest {
|
|||
Assert.assertEquals(expected.getOsName(), result.getOsName());
|
||||
Assert.assertEquals(expected.getTags(), result.getTags());
|
||||
Assert.assertEquals(expectedSize, result.getSize());
|
||||
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("id", "name", "osName", "tags", "size"), result);
|
||||
});
|
||||
|
||||
Mockito.verify(presetVariableHelperSpy).getPresetVariableValueResourceTags(Mockito.anyLong(), Mockito.eq(ResourceObjectType.Template));
|
||||
|
|
@ -1025,7 +987,7 @@ public class PresetVariableHelperTest {
|
|||
Mockito.doReturn(expected.getName()).when(snapshotVoMock).getName();
|
||||
Mockito.doReturn(expected.getSize()).when(snapshotVoMock).getSize();
|
||||
Mockito.doReturn((short) 3).when(snapshotVoMock).getSnapshotType();
|
||||
Mockito.doReturn(1l).when(presetVariableHelperSpy).getSnapshotDataStoreId(Mockito.anyLong(), Mockito.anyLong());
|
||||
Mockito.doReturn(1L).when(presetVariableHelperSpy).getSnapshotDataStoreId(Mockito.anyLong(), Mockito.anyLong());
|
||||
Mockito.doReturn(expected.getStorage()).when(presetVariableHelperSpy).getPresetVariableValueStorage(Mockito.anyLong(), Mockito.anyInt());
|
||||
Mockito.doReturn(expected.getTags()).when(presetVariableHelperSpy).getPresetVariableValueResourceTags(Mockito.anyLong(), Mockito.any(ResourceObjectType.class));
|
||||
Mockito.doReturn(hypervisorType).when(snapshotVoMock).getHypervisorType();
|
||||
|
|
@ -1043,8 +1005,6 @@ public class PresetVariableHelperTest {
|
|||
Assert.assertEquals(expected.getTags(), result.getTags());
|
||||
Assert.assertEquals(expectedSize, result.getSize());
|
||||
Assert.assertEquals(hypervisorType.name(), result.getHypervisorType());
|
||||
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("id", "name", "snapshotType", "storage", "tags", "size", "hypervisorType"), result);
|
||||
}
|
||||
|
||||
Mockito.verify(presetVariableHelperSpy, Mockito.times(Hypervisor.HypervisorType.values().length)).getPresetVariableValueResourceTags(Mockito.anyLong(),
|
||||
|
|
@ -1056,12 +1016,12 @@ public class PresetVariableHelperTest {
|
|||
public void getSnapshotDataStoreIdTestDoNotBackupSnapshotToSecondaryRetrievePrimaryStorage() {
|
||||
SnapshotDataStoreVO snapshotDataStoreVoMock = Mockito.mock(SnapshotDataStoreVO.class);
|
||||
|
||||
Long expected = 1l;
|
||||
Long expected = 1L;
|
||||
Mockito.doReturn(snapshotDataStoreVoMock).when(snapshotDataStoreDaoMock).findOneBySnapshotAndDatastoreRole(Mockito.anyLong(), Mockito.any(DataStoreRole.class));
|
||||
Mockito.doReturn(expected).when(snapshotDataStoreVoMock).getDataStoreId();
|
||||
presetVariableHelperSpy.backupSnapshotAfterTakingSnapshot = false;
|
||||
|
||||
Long result = presetVariableHelperSpy.getSnapshotDataStoreId(1l, 1l);
|
||||
Long result = presetVariableHelperSpy.getSnapshotDataStoreId(1L, 1L);
|
||||
|
||||
Assert.assertEquals(expected, result);
|
||||
|
||||
|
|
@ -1078,7 +1038,7 @@ public class PresetVariableHelperTest {
|
|||
public void getSnapshotDataStoreIdTestBackupSnapshotToSecondaryRetrieveSecondaryStorage() {
|
||||
SnapshotDataStoreVO snapshotDataStoreVoMock = Mockito.mock(SnapshotDataStoreVO.class);
|
||||
|
||||
Long expected = 2l;
|
||||
Long expected = 2L;
|
||||
ImageStoreVO imageStore = Mockito.mock(ImageStoreVO.class);
|
||||
Mockito.when(imageStoreDaoMock.findById(Mockito.anyLong())).thenReturn(imageStore);
|
||||
Mockito.when(imageStore.getDataCenterId()).thenReturn(1L);
|
||||
|
|
@ -1086,7 +1046,7 @@ public class PresetVariableHelperTest {
|
|||
Mockito.doReturn(expected).when(snapshotDataStoreVoMock).getDataStoreId();
|
||||
presetVariableHelperSpy.backupSnapshotAfterTakingSnapshot = true;
|
||||
|
||||
Long result = presetVariableHelperSpy.getSnapshotDataStoreId(2l, 1L);
|
||||
Long result = presetVariableHelperSpy.getSnapshotDataStoreId(2L, 1L);
|
||||
|
||||
Assert.assertEquals(expected, result);
|
||||
|
||||
|
|
@ -1129,8 +1089,6 @@ public class PresetVariableHelperTest {
|
|||
|
||||
assertPresetVariableIdAndName(expected, result);
|
||||
Assert.assertEquals(expected.getTag(), result.getTag());
|
||||
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("id", "name", "tag"), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -1155,7 +1113,7 @@ public class PresetVariableHelperTest {
|
|||
Mockito.doReturn(expected.getId()).when(vmSnapshotVoMock).getUuid();
|
||||
Mockito.doReturn(expected.getName()).when(vmSnapshotVoMock).getName();
|
||||
Mockito.doReturn(expected.getTags()).when(presetVariableHelperSpy).getPresetVariableValueResourceTags(Mockito.anyLong(), Mockito.any(ResourceObjectType.class));
|
||||
Mockito.doReturn(expected.getVmSnapshotType()).when(vmSnapshotVoMock).getType();
|
||||
Mockito.doReturn(VMSnapshot.Type.valueOf(expected.getVmSnapshotType())).when(vmSnapshotVoMock).getType();
|
||||
|
||||
Mockito.doReturn(UsageTypes.VM_SNAPSHOT).when(usageVoMock).getUsageType();
|
||||
|
||||
|
|
@ -1166,8 +1124,6 @@ public class PresetVariableHelperTest {
|
|||
Assert.assertEquals(expected.getTags(), result.getTags());
|
||||
Assert.assertEquals(expected.getVmSnapshotType(), result.getVmSnapshotType());
|
||||
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("id", "name", "tags", "vmSnapshotType"), result);
|
||||
|
||||
Mockito.verify(presetVariableHelperSpy).getPresetVariableValueResourceTags(Mockito.anyLong(), Mockito.eq(ResourceObjectType.VMSnapshot));
|
||||
}
|
||||
|
||||
|
|
@ -1200,9 +1156,6 @@ public class PresetVariableHelperTest {
|
|||
|
||||
if (typeInt == UsageTypes.RUNNING_VM) {
|
||||
Assert.assertEquals(expected.getComputingResources(), result.getComputingResources());
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("computeOffering", "computingResources"), result);
|
||||
} else {
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("computeOffering"), result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -1228,7 +1181,7 @@ public class PresetVariableHelperTest {
|
|||
|
||||
@Test
|
||||
public void getDetailByNameTestReturnsValue() {
|
||||
int expected = Integer.valueOf(getVmDetailsForTests().get(0).getValue());
|
||||
int expected = Integer.parseInt(getVmDetailsForTests().get(0).getValue());
|
||||
int result = presetVariableHelperSpy.getDetailByName(getVmDetailsForTests(), "test_with_value", expected);
|
||||
Assert.assertEquals(expected, result);
|
||||
}
|
||||
|
|
@ -1295,8 +1248,6 @@ public class PresetVariableHelperTest {
|
|||
Assert.assertEquals(expected.getVirtualSize(), result.getVirtualSize());
|
||||
Assert.assertEquals(expected.getBackupOffering(), result.getBackupOffering());
|
||||
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("size", "virtualSize", "backupOffering"), result);
|
||||
|
||||
Mockito.verify(presetVariableHelperSpy).getPresetVariableValueBackupOffering(Mockito.anyLong());
|
||||
}
|
||||
|
||||
|
|
@ -1311,11 +1262,10 @@ public class PresetVariableHelperTest {
|
|||
Mockito.doReturn(expected.getName()).when(backupOfferingVoMock).getName();
|
||||
Mockito.doReturn(expected.getExternalId()).when(backupOfferingVoMock).getExternalId();
|
||||
|
||||
BackupOffering result = presetVariableHelperSpy.getPresetVariableValueBackupOffering(1l);
|
||||
BackupOffering result = presetVariableHelperSpy.getPresetVariableValueBackupOffering(1L);
|
||||
|
||||
assertPresetVariableIdAndName(expected, result);
|
||||
Assert.assertEquals(expected.getExternalId(), result.getExternalId());
|
||||
validateFieldNamesToIncludeInToString(Arrays.asList("id", "name", "externalId"), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -1,34 +0,0 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.quota.activationrule.presetvariables;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class RoleTest {
|
||||
|
||||
@Test
|
||||
public void setTagsTestAddFieldTagsToCollection() {
|
||||
Role variable = new Role();
|
||||
variable.setType(null);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("type"));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.quota.activationrule.presetvariables;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class StorageTest {
|
||||
|
||||
@Test
|
||||
public void setTagsTestAddFieldTagsToCollection() {
|
||||
Storage variable = new Storage();
|
||||
variable.setTags(null);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("tags"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setScopeTestAddFieldScopeToCollection() {
|
||||
Storage variable = new Storage();
|
||||
variable.setScope(null);;
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("scope"));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,175 +0,0 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package org.apache.cloudstack.quota.activationrule.presetvariables;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ValueTest {
|
||||
|
||||
@Test
|
||||
public void setIdTestAddFieldIdToCollection() {
|
||||
Value variable = new Value();
|
||||
variable.setId(null);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("id"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setNameTestAddFieldNameToCollection() {
|
||||
Value variable = new Value();
|
||||
variable.setName(null);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("name"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setHostTestAddFieldHostToCollection() {
|
||||
Value variable = new Value();
|
||||
variable.setHost(null);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("host"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setOsNameTestAddFieldOsNameToCollection() {
|
||||
Value variable = new Value();
|
||||
variable.setOsName(null);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("osName"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAccountResourcesTestAddFieldAccountResourcesToCollection() {
|
||||
Value variable = new Value();
|
||||
variable.setAccountResources(null);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("accountResources"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setTagsTestAddFieldTagsToCollection() {
|
||||
Value variable = new Value();
|
||||
variable.setTags(null);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("tags"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setTagTestAddFieldTagToCollection() {
|
||||
Value variable = new Value();
|
||||
variable.setTag(null);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("tag"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setSizeTestAddFieldSizeToCollection() {
|
||||
Value variable = new Value();
|
||||
variable.setSize(null);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("size"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setProvisioningTypeTestAddFieldProvisioningTypeToCollection() {
|
||||
Value variable = new Value();
|
||||
variable.setProvisioningType(null);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("provisioningType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setSnapshotTypeTestAddFieldSnapshotTypeToCollection() {
|
||||
Value variable = new Value();
|
||||
variable.setSnapshotType(null);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("snapshotType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setVmSnapshotTypeTestAddFieldVmSnapshotTypeToCollection() {
|
||||
Value variable = new Value();
|
||||
variable.setVmSnapshotType(null);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("vmSnapshotType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setComputeOfferingTestAddFieldComputeOfferingToCollection() {
|
||||
Value variable = new Value();
|
||||
variable.setComputeOffering(null);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("computeOffering"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setTemplateTestAddFieldTemplateToCollection() {
|
||||
Value variable = new Value();
|
||||
variable.setTemplate(null);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("template"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setDiskOfferingTestAddFieldDiskOfferingToCollection() {
|
||||
Value variable = new Value();
|
||||
variable.setDiskOffering(null);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("diskOffering"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setStorageTestAddFieldStorageToCollection() {
|
||||
Value variable = new Value();
|
||||
variable.setStorage(null);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("storage"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setComputingResourcesTestAddFieldComputingResourcesToCollection() {
|
||||
Value variable = new Value();
|
||||
variable.setComputingResources(null);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("computingResources"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setVirtualSizeTestAddFieldVirtualSizeToCollection() {
|
||||
Value variable = new Value();
|
||||
variable.setVirtualSize(null);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("virtualSize"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setBackupOfferingTestAddFieldBackupOfferingToCollection() {
|
||||
Value variable = new Value();
|
||||
variable.setBackupOffering(null);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("backupOffering"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setHypervisorTypeTestAddFieldHypervisorTypeToCollection() {
|
||||
Value variable = new Value();
|
||||
variable.setHypervisorType(null);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("hypervisorType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setVolumeFormatTestAddFieldVolumeFormatToCollection() {
|
||||
Value variable = new Value();
|
||||
variable.setVolumeFormat(null);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("volumeFormat"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setStateTestAddFieldStateToCollection() {
|
||||
Value variable = new Value();
|
||||
variable.setState(null);
|
||||
Assert.assertTrue(variable.fieldNamesToIncludeInToString.contains("state"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -44,8 +44,10 @@ import org.apache.cloudstack.api.response.ApiDiscoveryResponse;
|
|||
import org.apache.cloudstack.api.response.ApiParameterResponse;
|
||||
import org.apache.cloudstack.api.response.ApiResponseResponse;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.resourcedetail.UserDetailVO;
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.reflections.ReflectionUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
|
@ -56,6 +58,7 @@ import com.cloud.serializer.Param;
|
|||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountService;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.UserAccount;
|
||||
import com.cloud.utils.ReflectUtil;
|
||||
import com.cloud.utils.component.ComponentLifecycleBase;
|
||||
import com.cloud.utils.component.PluggableService;
|
||||
|
|
@ -67,6 +70,7 @@ public class ApiDiscoveryServiceImpl extends ComponentLifecycleBase implements A
|
|||
List<APIChecker> _apiAccessCheckers = null;
|
||||
List<PluggableService> _services = null;
|
||||
protected static Map<String, ApiDiscoveryResponse> s_apiNameDiscoveryResponseMap = null;
|
||||
public static final List<String> APIS_ALLOWED_FOR_PASSWORD_CHANGE = Arrays.asList("login", "logout", "updateUser", "listApis");
|
||||
|
||||
@Inject
|
||||
AccountService accountService;
|
||||
|
|
@ -287,12 +291,20 @@ public class ApiDiscoveryServiceImpl extends ComponentLifecycleBase implements A
|
|||
ReflectionToStringBuilderUtils.reflectOnlySelectedFields(account, "accountName", "uuid")));
|
||||
}
|
||||
|
||||
if (role.getRoleType() == RoleType.Admin && role.getId() == RoleType.Admin.getId()) {
|
||||
logger.info(String.format("Account [%s] is Root Admin, all APIs are allowed.",
|
||||
ReflectionToStringBuilderUtils.reflectOnlySelectedFields(account, "accountName", "uuid")));
|
||||
// Limit APIs on first login requiring password change
|
||||
UserAccount userAccount = accountService.getUserAccountById(user.getId());
|
||||
Map<String, String> userAccDetails = userAccount.getDetails();
|
||||
if (MapUtils.isNotEmpty(userAccDetails) && !userAccDetails.containsKey(UserDetailVO.OauthLogin) &&
|
||||
"true".equalsIgnoreCase(userAccDetails.get(UserDetailVO.PasswordChangeRequired))) {
|
||||
apisAllowed = APIS_ALLOWED_FOR_PASSWORD_CHANGE;
|
||||
} else {
|
||||
for (APIChecker apiChecker : _apiAccessCheckers) {
|
||||
apisAllowed = apiChecker.getApisAllowedToUser(role, user, apisAllowed);
|
||||
if (role.getRoleType() == RoleType.Admin && role.getId() == RoleType.Admin.getId()) {
|
||||
logger.info(String.format("Account [%s] is Root Admin, all APIs are allowed.",
|
||||
ReflectionToStringBuilderUtils.reflectOnlySelectedFields(account, "accountName", "uuid")));
|
||||
} else {
|
||||
for (APIChecker apiChecker : _apiAccessCheckers) {
|
||||
apisAllowed = apiChecker.getApisAllowedToUser(role, user, apisAllowed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ import com.cloud.user.Account;
|
|||
import com.cloud.user.AccountService;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.UserAccount;
|
||||
import com.cloud.user.UserAccountVO;
|
||||
import com.cloud.user.UserVO;
|
||||
|
||||
import org.apache.cloudstack.acl.APIChecker;
|
||||
|
|
@ -29,6 +31,8 @@ import org.apache.cloudstack.acl.RoleService;
|
|||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.acl.RoleVO;
|
||||
import org.apache.cloudstack.api.response.ApiDiscoveryResponse;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
|
@ -39,11 +43,15 @@ import org.mockito.Spy;
|
|||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.cloudstack.resourcedetail.UserDetailVO.PasswordChangeRequired;
|
||||
import static org.apache.cloudstack.resourcedetail.UserDetailVO.Setup2FADetail;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyList;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ApiDiscoveryTest {
|
||||
|
|
@ -66,12 +74,17 @@ public class ApiDiscoveryTest {
|
|||
@InjectMocks
|
||||
ApiDiscoveryServiceImpl discoveryServiceSpy;
|
||||
|
||||
@Mock
|
||||
UserAccount mockUserAccount;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
discoveryServiceSpy.s_apiNameDiscoveryResponseMap = apiNameDiscoveryResponseMapMock;
|
||||
discoveryServiceSpy._apiAccessCheckers = apiAccessCheckersMock;
|
||||
|
||||
Mockito.when(discoveryServiceSpy._apiAccessCheckers.iterator()).thenReturn(Arrays.asList(apiCheckerMock).iterator());
|
||||
Mockito.when(mockUserAccount.getDetails()).thenReturn(null);
|
||||
Mockito.when(accountServiceMock.getUserAccountById(anyLong())).thenReturn(mockUserAccount);
|
||||
}
|
||||
|
||||
private User getTestUser() {
|
||||
|
|
@ -131,4 +144,29 @@ public class ApiDiscoveryTest {
|
|||
|
||||
Mockito.verify(apiCheckerMock, Mockito.times(1)).getApisAllowedToUser(any(Role.class), any(User.class), anyList());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listApisForUserWithoutEnforcedPwdChange() throws PermissionDeniedException {
|
||||
RoleVO userRoleVO = new RoleVO(4L, "name", RoleType.User, "description");
|
||||
Map<String, String> userDetails = new HashMap<>();
|
||||
userDetails.put(Setup2FADetail, UserAccountVO.Setup2FAstatus.ENABLED.name());
|
||||
Mockito.when(mockUserAccount.getDetails()).thenReturn(userDetails);
|
||||
Mockito.when(accountServiceMock.getAccount(Mockito.anyLong())).thenReturn(getNormalAccount());
|
||||
Mockito.when(roleServiceMock.findRole(Mockito.anyLong())).thenReturn(userRoleVO);
|
||||
discoveryServiceSpy.listApis(getTestUser(), null);
|
||||
Mockito.verify(apiCheckerMock, Mockito.times(1)).getApisAllowedToUser(any(Role.class), any(User.class), anyList());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listApisForUserEnforcedPwdChange() throws PermissionDeniedException {
|
||||
RoleVO userRoleVO = new RoleVO(4L, "name", RoleType.User, "description");
|
||||
Map<String, String> userDetails = new HashMap<>();
|
||||
userDetails.put(PasswordChangeRequired, "true");
|
||||
Mockito.when(mockUserAccount.getDetails()).thenReturn(userDetails);
|
||||
Mockito.when(accountServiceMock.getAccount(Mockito.anyLong())).thenReturn(getNormalAccount());
|
||||
Mockito.when(roleServiceMock.findRole(Mockito.anyLong())).thenReturn(userRoleVO);
|
||||
Mockito.when(apiNameDiscoveryResponseMapMock.get(Mockito.anyString())).thenReturn(Mockito.mock(ApiDiscoveryResponse.class));
|
||||
ListResponse<ApiDiscoveryResponse> response = (ListResponse<ApiDiscoveryResponse>) discoveryServiceSpy.listApis(getTestUser(), null);
|
||||
Assert.assertEquals(4, response.getResponses().size());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,7 +70,6 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
|
@ -297,7 +296,8 @@ public class NASBackupProvider extends AdapterBase implements BackupProvider, Co
|
|||
}
|
||||
|
||||
private Pair<Boolean, String> restoreVMBackup(VirtualMachine vm, Backup backup) {
|
||||
List<String> backedVolumesUUIDs = backup.getBackedUpVolumes().stream()
|
||||
List<Backup.VolumeInfo> backedVolumes = backup.getBackedUpVolumes();
|
||||
List<String> backedVolumesUUIDs = backedVolumes.stream()
|
||||
.sorted(Comparator.comparingLong(Backup.VolumeInfo::getDeviceId))
|
||||
.map(Backup.VolumeInfo::getUuid)
|
||||
.collect(Collectors.toList());
|
||||
|
|
@ -320,6 +320,7 @@ public class NASBackupProvider extends AdapterBase implements BackupProvider, Co
|
|||
Pair<List<PrimaryDataStoreTO>, List<String>> volumePoolsAndPaths = getVolumePoolsAndPaths(restoreVolumes);
|
||||
restoreCommand.setRestoreVolumePools(volumePoolsAndPaths.first());
|
||||
restoreCommand.setRestoreVolumePaths(volumePoolsAndPaths.second());
|
||||
restoreCommand.setBackupFiles(getBackupFiles(backedVolumes));
|
||||
restoreCommand.setVmExists(vm.getRemoved() == null);
|
||||
restoreCommand.setVmState(vm.getState());
|
||||
restoreCommand.setMountTimeout(NASBackupRestoreMountTimeout.value());
|
||||
|
|
@ -335,6 +336,14 @@ public class NASBackupProvider extends AdapterBase implements BackupProvider, Co
|
|||
return new Pair<>(answer.getResult(), answer.getDetails());
|
||||
}
|
||||
|
||||
private List<String> getBackupFiles(List<Backup.VolumeInfo> backedVolumes) {
|
||||
List<String> backupFiles = new ArrayList<>();
|
||||
for (Backup.VolumeInfo backedVolume : backedVolumes) {
|
||||
backupFiles.add(backedVolume.getPath());
|
||||
}
|
||||
return backupFiles;
|
||||
}
|
||||
|
||||
private Pair<List<PrimaryDataStoreTO>, List<String>> getVolumePoolsAndPaths(List<VolumeVO> volumes) {
|
||||
List<PrimaryDataStoreTO> volumePools = new ArrayList<>();
|
||||
List<String> volumePaths = new ArrayList<>();
|
||||
|
|
@ -373,7 +382,13 @@ public class NASBackupProvider extends AdapterBase implements BackupProvider, Co
|
|||
final StoragePoolVO pool = primaryDataStoreDao.findByUuid(dataStoreUuid);
|
||||
final HostVO hostVO = hostDao.findByIp(hostIp);
|
||||
|
||||
LOG.debug("Restoring vm volume {} from backup {} on the NAS Backup Provider", backupVolumeInfo, backup);
|
||||
Backup.VolumeInfo matchingVolume = getBackedUpVolumeInfo(backup.getBackedUpVolumes(), volume.getUuid());
|
||||
if (matchingVolume == null) {
|
||||
throw new CloudRuntimeException(String.format("Unable to find volume %s in the list of backed up volumes for backup %s, cannot proceed with restore", volume.getUuid(), backup));
|
||||
}
|
||||
Long backedUpVolumeSize = matchingVolume.getSize();
|
||||
|
||||
LOG.debug("Restoring vm volume {} from backup {} on the NAS Backup Provider", volume, backup);
|
||||
BackupRepository backupRepository = getBackupRepository(backup);
|
||||
|
||||
VolumeVO restoredVolume = new VolumeVO(Volume.Type.DATADISK, null, backup.getZoneId(),
|
||||
|
|
@ -391,7 +406,7 @@ public class NASBackupProvider extends AdapterBase implements BackupProvider, Co
|
|||
restoredVolume.setPoolType(pool.getPoolType());
|
||||
restoredVolume.setPath(restoredVolume.getUuid());
|
||||
restoredVolume.setState(Volume.State.Copying);
|
||||
restoredVolume.setSize(backupVolumeInfo.getSize());
|
||||
restoredVolume.setSize(backedUpVolumeSize);
|
||||
restoredVolume.setDiskOfferingId(diskOffering.getId());
|
||||
if (pool.getPoolType() != Storage.StoragePoolType.RBD) {
|
||||
restoredVolume.setFormat(Storage.ImageFormat.QCOW2);
|
||||
|
|
@ -411,8 +426,8 @@ public class NASBackupProvider extends AdapterBase implements BackupProvider, Co
|
|||
restoreCommand.setMountOptions(backupRepository.getMountOptions());
|
||||
restoreCommand.setVmExists(null);
|
||||
restoreCommand.setVmState(vmNameAndState.second());
|
||||
restoreCommand.setRestoreVolumeUUID(backupVolumeInfo.getUuid());
|
||||
restoreCommand.setMountTimeout(NASBackupRestoreMountTimeout.value());
|
||||
restoreCommand.setBackupFiles(Collections.singletonList(matchingVolume.getPath()));
|
||||
|
||||
BackupAnswer answer;
|
||||
try {
|
||||
|
|
@ -442,10 +457,11 @@ public class NASBackupProvider extends AdapterBase implements BackupProvider, Co
|
|||
return backupRepository;
|
||||
}
|
||||
|
||||
private Optional<Backup.VolumeInfo> getBackedUpVolumeInfo(List<Backup.VolumeInfo> backedUpVolumes, String volumeUuid) {
|
||||
private Backup.VolumeInfo getBackedUpVolumeInfo(List<Backup.VolumeInfo> backedUpVolumes, String volumeUuid) {
|
||||
return backedUpVolumes.stream()
|
||||
.filter(v -> v.getUuid().equals(volumeUuid))
|
||||
.findFirst();
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.backup;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.dc.dao.ClusterDao;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.Status;
|
||||
|
|
@ -134,6 +135,9 @@ public class NetworkerBackupProvider extends AdapterBase implements BackupProvid
|
|||
@Inject
|
||||
private DiskOfferingDao diskOfferingDao;
|
||||
|
||||
@Inject
|
||||
private AgentManager agentMgr;
|
||||
|
||||
private static String getUrlDomain(String url) throws URISyntaxException {
|
||||
URI uri;
|
||||
try {
|
||||
|
|
@ -251,8 +255,13 @@ public class NetworkerBackupProvider extends AdapterBase implements BackupProvid
|
|||
String nstRegex = "\\bcompleted savetime=([0-9]{10})";
|
||||
Pattern saveTimePattern = Pattern.compile(nstRegex);
|
||||
|
||||
if (host == null) {
|
||||
LOG.warn("Unable to take backup, host is null");
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
Pair<Boolean, String> response = SshHelper.sshExecute(host.getPrivateIpAddress(), 22,
|
||||
Pair<Boolean, String> response = SshHelper.sshExecute(host.getPrivateIpAddress(), agentMgr.getHostSshPort(host),
|
||||
username, null, password, command, 120000, 120000, 3600000);
|
||||
if (!response.first()) {
|
||||
LOG.error("Backup Script failed on HYPERVISOR {} due to: {}", host, response.second());
|
||||
|
|
@ -271,9 +280,13 @@ public class NetworkerBackupProvider extends AdapterBase implements BackupProvid
|
|||
return null;
|
||||
}
|
||||
private boolean executeRestoreCommand(HostVO host, String username, String password, String command) {
|
||||
if (host == null) {
|
||||
LOG.warn("Unable to restore backup, host is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
Pair<Boolean, String> response = SshHelper.sshExecute(host.getPrivateIpAddress(), 22,
|
||||
Pair<Boolean, String> response = SshHelper.sshExecute(host.getPrivateIpAddress(), agentMgr.getHostSshPort(host),
|
||||
username, null, password, command, 120000, 120000, 3600000);
|
||||
|
||||
if (!response.first()) {
|
||||
|
|
|
|||
|
|
@ -493,7 +493,7 @@ public class RabbitMQEventBus extends ManagerBase implements EventBus {
|
|||
|
||||
@Override
|
||||
public synchronized boolean stop() {
|
||||
if (s_connection.isOpen()) {
|
||||
if (s_connection != null && s_connection.isOpen()) {
|
||||
for (String subscriberId : s_subscribers.keySet()) {
|
||||
Ternary<String, Channel, EventSubscriber> subscriberDetails = s_subscribers.get(subscriberId);
|
||||
Channel channel = subscriberDetails.second();
|
||||
|
|
|
|||
|
|
@ -72,10 +72,10 @@ public class LibvirtRestoreBackupCommandWrapper extends CommandWrapper<RestoreBa
|
|||
List<String> backedVolumeUUIDs = command.getBackupVolumesUUIDs();
|
||||
List<PrimaryDataStoreTO> restoreVolumePools = command.getRestoreVolumePools();
|
||||
List<String> restoreVolumePaths = command.getRestoreVolumePaths();
|
||||
String restoreVolumeUuid = command.getRestoreVolumeUUID();
|
||||
Integer mountTimeout = command.getMountTimeout() * 1000;
|
||||
int timeout = command.getWait();
|
||||
KVMStoragePoolManager storagePoolMgr = serverResource.getStoragePoolMgr();
|
||||
List<String> backupFiles = command.getBackupFiles();
|
||||
|
||||
String newVolumeId = null;
|
||||
try {
|
||||
|
|
@ -83,14 +83,15 @@ public class LibvirtRestoreBackupCommandWrapper extends CommandWrapper<RestoreBa
|
|||
if (Objects.isNull(vmExists)) {
|
||||
PrimaryDataStoreTO volumePool = restoreVolumePools.get(0);
|
||||
String volumePath = restoreVolumePaths.get(0);
|
||||
String backupFile = backupFiles.get(0);
|
||||
int lastIndex = volumePath.lastIndexOf("/");
|
||||
newVolumeId = volumePath.substring(lastIndex + 1);
|
||||
restoreVolume(storagePoolMgr, backupPath, volumePool, volumePath, diskType, restoreVolumeUuid,
|
||||
restoreVolume(storagePoolMgr, backupPath, volumePool, volumePath, diskType, backupFile,
|
||||
new Pair<>(vmName, command.getVmState()), mountDirectory, timeout);
|
||||
} else if (Boolean.TRUE.equals(vmExists)) {
|
||||
restoreVolumesOfExistingVM(storagePoolMgr, restoreVolumePools, restoreVolumePaths, backedVolumeUUIDs, backupPath, mountDirectory, timeout);
|
||||
restoreVolumesOfExistingVM(storagePoolMgr, restoreVolumePools, restoreVolumePaths, backedVolumeUUIDs, backupPath, backupFiles, mountDirectory, timeout);
|
||||
} else {
|
||||
restoreVolumesOfDestroyedVMs(storagePoolMgr, restoreVolumePools, restoreVolumePaths, vmName, backupPath, mountDirectory, timeout);
|
||||
restoreVolumesOfDestroyedVMs(storagePoolMgr, restoreVolumePools, restoreVolumePaths, backupPath, backupFiles, mountDirectory, timeout);
|
||||
}
|
||||
} catch (CloudRuntimeException e) {
|
||||
String errorMessage = e.getMessage() != null ? e.getMessage() : "";
|
||||
|
|
@ -109,19 +110,22 @@ public class LibvirtRestoreBackupCommandWrapper extends CommandWrapper<RestoreBa
|
|||
}
|
||||
}
|
||||
|
||||
private void restoreVolumesOfExistingVM(KVMStoragePoolManager storagePoolMgr, List<PrimaryDataStoreTO> restoreVolumePools, List<String> restoreVolumePaths, List<String> backedVolumesUUIDs,
|
||||
String backupPath, String mountDirectory, int timeout) {
|
||||
private void restoreVolumesOfExistingVM(KVMStoragePoolManager storagePoolMgr, List<PrimaryDataStoreTO> restoreVolumePools,
|
||||
List<String> restoreVolumePaths, List<String> backedVolumesUUIDs,
|
||||
String backupPath, List<String> backupFiles, String mountDirectory, int timeout) {
|
||||
String diskType = "root";
|
||||
try {
|
||||
for (int idx = 0; idx < restoreVolumePaths.size(); idx++) {
|
||||
PrimaryDataStoreTO restoreVolumePool = restoreVolumePools.get(idx);
|
||||
String restoreVolumePath = restoreVolumePaths.get(idx);
|
||||
String backupFile = backupFiles.get(idx);
|
||||
String backupVolumeUuid = backedVolumesUUIDs.get(idx);
|
||||
Pair<String, String> bkpPathAndVolUuid = getBackupPath(mountDirectory, null, backupPath, diskType, backupVolumeUuid);
|
||||
String fullPath = getBackupPath(mountDirectory, backupPath, backupFile, diskType);
|
||||
diskType = "datadisk";
|
||||
verifyBackupFile(bkpPathAndVolUuid.first(), bkpPathAndVolUuid.second());
|
||||
if (!replaceVolumeWithBackup(storagePoolMgr, restoreVolumePool, restoreVolumePath, bkpPathAndVolUuid.first(), timeout)) {
|
||||
throw new CloudRuntimeException(String.format("Unable to restore contents from the backup volume [%s].", bkpPathAndVolUuid.second()));
|
||||
|
||||
verifyBackupFile(fullPath, backupVolumeUuid);
|
||||
if (!replaceVolumeWithBackup(storagePoolMgr, restoreVolumePool, restoreVolumePath, fullPath, timeout)) {
|
||||
throw new CloudRuntimeException(String.format("Unable to restore contents from the backup volume [%s].", backupVolumeUuid));
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
|
|
@ -130,17 +134,20 @@ public class LibvirtRestoreBackupCommandWrapper extends CommandWrapper<RestoreBa
|
|||
}
|
||||
}
|
||||
|
||||
private void restoreVolumesOfDestroyedVMs(KVMStoragePoolManager storagePoolMgr, List<PrimaryDataStoreTO> volumePools, List<String> volumePaths, String vmName, String backupPath, String mountDirectory, int timeout) {
|
||||
private void restoreVolumesOfDestroyedVMs(KVMStoragePoolManager storagePoolMgr, List<PrimaryDataStoreTO> volumePools,
|
||||
List<String> volumePaths, String backupPath, List<String> backupFiles, String mountDirectory, int timeout) {
|
||||
String diskType = "root";
|
||||
try {
|
||||
for (int i = 0; i < volumePaths.size(); i++) {
|
||||
PrimaryDataStoreTO volumePool = volumePools.get(i);
|
||||
String volumePath = volumePaths.get(i);
|
||||
Pair<String, String> bkpPathAndVolUuid = getBackupPath(mountDirectory, volumePath, backupPath, diskType, null);
|
||||
String backupFile = backupFiles.get(i);
|
||||
String bkpPath = getBackupPath(mountDirectory, backupPath, backupFile, diskType);
|
||||
String volumeUuid = volumePath.substring(volumePath.lastIndexOf(File.separator) + 1);
|
||||
diskType = "datadisk";
|
||||
verifyBackupFile(bkpPathAndVolUuid.first(), bkpPathAndVolUuid.second());
|
||||
if (!replaceVolumeWithBackup(storagePoolMgr, volumePool, volumePath, bkpPathAndVolUuid.first(), timeout)) {
|
||||
throw new CloudRuntimeException(String.format("Unable to restore contents from the backup volume [%s].", bkpPathAndVolUuid.second()));
|
||||
verifyBackupFile(bkpPath, volumeUuid);
|
||||
if (!replaceVolumeWithBackup(storagePoolMgr, volumePool, volumePath, bkpPath, timeout)) {
|
||||
throw new CloudRuntimeException(String.format("Unable to restore contents from the backup volume [%s].", volumeUuid));
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
|
|
@ -149,14 +156,17 @@ public class LibvirtRestoreBackupCommandWrapper extends CommandWrapper<RestoreBa
|
|||
}
|
||||
}
|
||||
|
||||
private void restoreVolume(KVMStoragePoolManager storagePoolMgr, String backupPath, PrimaryDataStoreTO volumePool, String volumePath, String diskType, String volumeUUID,
|
||||
private void restoreVolume(KVMStoragePoolManager storagePoolMgr, String backupPath, PrimaryDataStoreTO volumePool, String volumePath, String diskType, String backupFile,
|
||||
Pair<String, VirtualMachine.State> vmNameAndState, String mountDirectory, int timeout) {
|
||||
Pair<String, String> bkpPathAndVolUuid;
|
||||
String bkpPath;
|
||||
String volumeUuid;
|
||||
try {
|
||||
bkpPathAndVolUuid = getBackupPath(mountDirectory, volumePath, backupPath, diskType, volumeUUID);
|
||||
verifyBackupFile(bkpPathAndVolUuid.first(), bkpPathAndVolUuid.second());
|
||||
if (!replaceVolumeWithBackup(storagePoolMgr, volumePool, volumePath, bkpPathAndVolUuid.first(), timeout, true)) {
|
||||
throw new CloudRuntimeException(String.format("Unable to restore contents from the backup volume [%s].", bkpPathAndVolUuid.second()));
|
||||
bkpPath = getBackupPath(mountDirectory, backupPath, backupFile, diskType);
|
||||
volumeUuid = volumePath.substring(volumePath.lastIndexOf(File.separator) + 1);
|
||||
verifyBackupFile(bkpPath, volumeUuid);
|
||||
if (!replaceVolumeWithBackup(storagePoolMgr, volumePool, volumePath, bkpPath, timeout, true)) {
|
||||
throw new CloudRuntimeException(String.format("Unable to restore contents from the backup volume [%s].", volumeUuid));
|
||||
|
||||
}
|
||||
if (VirtualMachine.State.Running.equals(vmNameAndState.second())) {
|
||||
if (!attachVolumeToVm(storagePoolMgr, vmNameAndState.first(), volumePool, volumePath)) {
|
||||
|
|
@ -177,7 +187,7 @@ public class LibvirtRestoreBackupCommandWrapper extends CommandWrapper<RestoreBa
|
|||
try {
|
||||
mountDirectory = Files.createTempDirectory(mountDirectory).toString();
|
||||
} catch (IOException e) {
|
||||
logger.error(String.format("Failed to create the tmp mount directory {} for restore", mountDirectory), e);
|
||||
logger.error("Failed to create the tmp mount directory {} for restore", mountDirectory, e);
|
||||
throw new CloudRuntimeException("Failed to create the tmp mount directory for restore on the KVM host");
|
||||
}
|
||||
|
||||
|
|
@ -195,7 +205,7 @@ public class LibvirtRestoreBackupCommandWrapper extends CommandWrapper<RestoreBa
|
|||
|
||||
int exitValue = Script.runSimpleBashScriptForExitValue(mount, mountTimeout, false);
|
||||
if (exitValue != 0) {
|
||||
logger.error(String.format("Failed to mount repository {} of type {} to the directory {}", backupRepoAddress, backupRepoType, mountDirectory));
|
||||
logger.error("Failed to mount repository {} of type {} to the directory {}", backupRepoAddress, backupRepoType, mountDirectory);
|
||||
throw new CloudRuntimeException("Failed to mount the backup repository on the KVM host");
|
||||
}
|
||||
return mountDirectory;
|
||||
|
|
@ -205,7 +215,7 @@ public class LibvirtRestoreBackupCommandWrapper extends CommandWrapper<RestoreBa
|
|||
String umountCmd = String.format(UMOUNT_COMMAND, backupDirectory);
|
||||
int exitValue = Script.runSimpleBashScriptForExitValue(umountCmd);
|
||||
if (exitValue != 0) {
|
||||
logger.error(String.format("Failed to unmount backup directory {}", backupDirectory));
|
||||
logger.error("Failed to unmount backup directory {}", backupDirectory);
|
||||
throw new CloudRuntimeException("Failed to unmount the backup directory");
|
||||
}
|
||||
}
|
||||
|
|
@ -214,17 +224,16 @@ public class LibvirtRestoreBackupCommandWrapper extends CommandWrapper<RestoreBa
|
|||
try {
|
||||
Files.deleteIfExists(Paths.get(backupDirectory));
|
||||
} catch (IOException e) {
|
||||
logger.error(String.format("Failed to delete backup directory: %s", backupDirectory), e);
|
||||
logger.error("Failed to delete backup directory: {}}", backupDirectory, e);
|
||||
throw new CloudRuntimeException("Failed to delete the backup directory");
|
||||
}
|
||||
}
|
||||
|
||||
private Pair<String, String> getBackupPath(String mountDirectory, String volumePath, String backupPath, String diskType, String volumeUuid) {
|
||||
private String getBackupPath(String mountDirectory, String backupPath, String backupFile, String diskType) {
|
||||
String bkpPath = String.format(FILE_PATH_PLACEHOLDER, mountDirectory, backupPath);
|
||||
String volUuid = Objects.isNull(volumeUuid) ? volumePath.substring(volumePath.lastIndexOf(File.separator) + 1) : volumeUuid;
|
||||
String backupFileName = String.format("%s.%s.qcow2", diskType.toLowerCase(Locale.ROOT), volUuid);
|
||||
String backupFileName = String.format("%s.%s.qcow2", diskType.toLowerCase(Locale.ROOT), backupFile);
|
||||
bkpPath = String.format(FILE_PATH_PLACEHOLDER, bkpPath, backupFileName);
|
||||
return new Pair<>(bkpPath, volUuid);
|
||||
return bkpPath;
|
||||
}
|
||||
|
||||
private boolean checkBackupFileImage(String backupPath) {
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ public class LibvirtRestoreBackupCommandWrapperTest {
|
|||
PrimaryDataStoreTO primaryDataStore = Mockito.mock(PrimaryDataStoreTO.class);
|
||||
when(command.getRestoreVolumePools()).thenReturn(Arrays.asList(primaryDataStore));
|
||||
when(command.getRestoreVolumePaths()).thenReturn(Arrays.asList("/var/lib/libvirt/images/volume-123"));
|
||||
when(command.getRestoreVolumeUUID()).thenReturn("volume-123");
|
||||
when(command.getBackupFiles()).thenReturn(Arrays.asList("volume-123"));
|
||||
when(command.getVmState()).thenReturn(VirtualMachine.State.Running);
|
||||
when(command.getMountTimeout()).thenReturn(30);
|
||||
|
||||
|
|
@ -112,6 +112,7 @@ public class LibvirtRestoreBackupCommandWrapperTest {
|
|||
when(command.getRestoreVolumePools()).thenReturn(Arrays.asList(primaryDataStore));
|
||||
when(command.getRestoreVolumePaths()).thenReturn(Arrays.asList("/var/lib/libvirt/images/volume-123"));
|
||||
when(command.getBackupVolumesUUIDs()).thenReturn(Arrays.asList("volume-123"));
|
||||
when(command.getBackupFiles()).thenReturn(Arrays.asList("volume-123"));
|
||||
when(command.getMountTimeout()).thenReturn(30);
|
||||
|
||||
try (MockedStatic<Files> filesMock = mockStatic(Files.class)) {
|
||||
|
|
@ -149,6 +150,7 @@ public class LibvirtRestoreBackupCommandWrapperTest {
|
|||
PrimaryDataStoreTO primaryDataStore = Mockito.mock(PrimaryDataStoreTO.class);
|
||||
when(command.getRestoreVolumePools()).thenReturn(Arrays.asList(primaryDataStore));
|
||||
when(command.getRestoreVolumePaths()).thenReturn(Arrays.asList("/var/lib/libvirt/images/volume-123"));
|
||||
when(command.getBackupFiles()).thenReturn(Arrays.asList("volume-123"));
|
||||
when(command.getMountTimeout()).thenReturn(30);
|
||||
|
||||
try (MockedStatic<Files> filesMock = mockStatic(Files.class)) {
|
||||
|
|
@ -186,7 +188,7 @@ public class LibvirtRestoreBackupCommandWrapperTest {
|
|||
PrimaryDataStoreTO primaryDataStore = Mockito.mock(PrimaryDataStoreTO.class);
|
||||
when(command.getRestoreVolumePools()).thenReturn(Arrays.asList(primaryDataStore));
|
||||
when(command.getRestoreVolumePaths()).thenReturn(Arrays.asList("/var/lib/libvirt/images/volume-123"));
|
||||
when(command.getRestoreVolumeUUID()).thenReturn("volume-123");
|
||||
when(command.getBackupFiles()).thenReturn(Arrays.asList("volume-123"));
|
||||
when(command.getVmState()).thenReturn(VirtualMachine.State.Running);
|
||||
when(command.getMountTimeout()).thenReturn(30);
|
||||
|
||||
|
|
@ -227,7 +229,7 @@ public class LibvirtRestoreBackupCommandWrapperTest {
|
|||
PrimaryDataStoreTO primaryDataStore = Mockito.mock(PrimaryDataStoreTO.class);
|
||||
when(command.getRestoreVolumePools()).thenReturn(Arrays.asList(primaryDataStore));
|
||||
lenient().when(command.getRestoreVolumePaths()).thenReturn(Arrays.asList("/var/lib/libvirt/images/volume-123"));
|
||||
lenient().when(command.getRestoreVolumeUUID()).thenReturn("volume-123");
|
||||
when(command.getBackupFiles()).thenReturn(Arrays.asList("volume-123"));
|
||||
lenient().when(command.getVmState()).thenReturn(VirtualMachine.State.Running);
|
||||
lenient().when(command.getMountTimeout()).thenReturn(30);
|
||||
|
||||
|
|
@ -263,7 +265,7 @@ public class LibvirtRestoreBackupCommandWrapperTest {
|
|||
PrimaryDataStoreTO primaryDataStore = Mockito.mock(PrimaryDataStoreTO.class);
|
||||
when(command.getRestoreVolumePools()).thenReturn(Arrays.asList(primaryDataStore));
|
||||
when(command.getRestoreVolumePaths()).thenReturn(Arrays.asList("/var/lib/libvirt/images/volume-123"));
|
||||
when(command.getRestoreVolumeUUID()).thenReturn("volume-123");
|
||||
when(command.getBackupFiles()).thenReturn(Arrays.asList("volume-123"));
|
||||
when(command.getVmState()).thenReturn(VirtualMachine.State.Running);
|
||||
when(command.getMountTimeout()).thenReturn(30);
|
||||
|
||||
|
|
@ -309,7 +311,7 @@ public class LibvirtRestoreBackupCommandWrapperTest {
|
|||
PrimaryDataStoreTO primaryDataStore = Mockito.mock(PrimaryDataStoreTO.class);
|
||||
when(command.getRestoreVolumePools()).thenReturn(Arrays.asList(primaryDataStore));
|
||||
when(command.getRestoreVolumePaths()).thenReturn(Arrays.asList("/var/lib/libvirt/images/volume-123"));
|
||||
when(command.getRestoreVolumeUUID()).thenReturn("volume-123");
|
||||
when(command.getBackupFiles()).thenReturn(Arrays.asList("volume-123"));
|
||||
when(command.getVmState()).thenReturn(VirtualMachine.State.Running);
|
||||
when(command.getMountTimeout()).thenReturn(30);
|
||||
|
||||
|
|
@ -357,7 +359,7 @@ public class LibvirtRestoreBackupCommandWrapperTest {
|
|||
PrimaryDataStoreTO primaryDataStore = Mockito.mock(PrimaryDataStoreTO.class);
|
||||
when(command.getRestoreVolumePools()).thenReturn(Arrays.asList(primaryDataStore));
|
||||
when(command.getRestoreVolumePaths()).thenReturn(Arrays.asList("/var/lib/libvirt/images/volume-123"));
|
||||
when(command.getRestoreVolumeUUID()).thenReturn("volume-123");
|
||||
when(command.getBackupFiles()).thenReturn(Arrays.asList("volume-123"));
|
||||
when(command.getVmState()).thenReturn(VirtualMachine.State.Running);
|
||||
when(command.getMountTimeout()).thenReturn(30);
|
||||
|
||||
|
|
@ -407,7 +409,7 @@ public class LibvirtRestoreBackupCommandWrapperTest {
|
|||
PrimaryDataStoreTO primaryDataStore = Mockito.mock(PrimaryDataStoreTO.class);
|
||||
when(command.getRestoreVolumePools()).thenReturn(Arrays.asList(primaryDataStore));
|
||||
when(command.getRestoreVolumePaths()).thenReturn(Arrays.asList("/var/lib/libvirt/images/volume-123"));
|
||||
when(command.getRestoreVolumeUUID()).thenReturn("volume-123");
|
||||
when(command.getBackupFiles()).thenReturn(Arrays.asList("volume-123"));
|
||||
when(command.getVmState()).thenReturn(VirtualMachine.State.Running);
|
||||
when(command.getMountTimeout()).thenReturn(30);
|
||||
|
||||
|
|
@ -461,7 +463,7 @@ public class LibvirtRestoreBackupCommandWrapperTest {
|
|||
PrimaryDataStoreTO primaryDataStore = Mockito.mock(PrimaryDataStoreTO.class);
|
||||
when(command.getRestoreVolumePools()).thenReturn(Arrays.asList(primaryDataStore));
|
||||
lenient().when(command.getRestoreVolumePaths()).thenReturn(Arrays.asList("/var/lib/libvirt/images/volume-123"));
|
||||
lenient().when(command.getRestoreVolumeUUID()).thenReturn("volume-123");
|
||||
when(command.getBackupFiles()).thenReturn(Arrays.asList("volume-123"));
|
||||
lenient().when(command.getVmState()).thenReturn(VirtualMachine.State.Running);
|
||||
lenient().when(command.getMountTimeout()).thenReturn(30);
|
||||
|
||||
|
|
@ -499,6 +501,7 @@ public class LibvirtRestoreBackupCommandWrapperTest {
|
|||
"/var/lib/libvirt/images/volume-456"
|
||||
));
|
||||
when(command.getBackupVolumesUUIDs()).thenReturn(Arrays.asList("volume-123", "volume-456"));
|
||||
when(command.getBackupFiles()).thenReturn(Arrays.asList("volume-123", "volume-456"));
|
||||
when(command.getMountTimeout()).thenReturn(30);
|
||||
|
||||
try (MockedStatic<Files> filesMock = mockStatic(Files.class)) {
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ public final class CitrixModifyStoragePoolCommandWrapper extends CommandWrapper<
|
|||
if (capacity == -1) {
|
||||
final String msg = "Pool capacity is -1! pool: " + pool.getHost() + pool.getPath();
|
||||
logger.warn(msg);
|
||||
return new Answer(command, false, msg);
|
||||
return new ModifyStoragePoolAnswer(command, false, msg);
|
||||
}
|
||||
final Map<String, TemplateProp> tInfo = new HashMap<String, TemplateProp>();
|
||||
final ModifyStoragePoolAnswer answer = new ModifyStoragePoolAnswer(command, capacity, available, tInfo);
|
||||
|
|
@ -68,12 +68,12 @@ public final class CitrixModifyStoragePoolCommandWrapper extends CommandWrapper<
|
|||
final String msg = "ModifyStoragePoolCommand add XenAPIException:" + e.toString() + " host:" + citrixResourceBase.getHost().getUuid() + " pool: " + pool.getHost()
|
||||
+ pool.getPath();
|
||||
logger.warn(msg, e);
|
||||
return new Answer(command, false, msg);
|
||||
return new ModifyStoragePoolAnswer(command, false, msg);
|
||||
} catch (final Exception e) {
|
||||
final String msg = "ModifyStoragePoolCommand add XenAPIException:" + e.getMessage() + " host:" + citrixResourceBase.getHost().getUuid() + " pool: "
|
||||
+ pool.getHost() + pool.getPath();
|
||||
logger.warn(msg, e);
|
||||
return new Answer(command, false, msg);
|
||||
return new ModifyStoragePoolAnswer(command, false, msg);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
|
|
@ -85,17 +85,17 @@ public final class CitrixModifyStoragePoolCommandWrapper extends CommandWrapper<
|
|||
if (result == null || !result.split("#")[1].equals("0")) {
|
||||
throw new CloudRuntimeException("Unable to remove heartbeat file entry for SR " + srUuid + " due to " + result);
|
||||
}
|
||||
return new Answer(command, true, "success");
|
||||
return new ModifyStoragePoolAnswer(command, true, "success");
|
||||
} catch (final XenAPIException e) {
|
||||
final String msg = "ModifyStoragePoolCommand remove XenAPIException:" + e.toString() + " host:" + citrixResourceBase.getHost().getUuid() + " pool: "
|
||||
+ pool.getHost() + pool.getPath();
|
||||
logger.warn(msg, e);
|
||||
return new Answer(command, false, msg);
|
||||
return new ModifyStoragePoolAnswer(command, false, msg);
|
||||
} catch (final Exception e) {
|
||||
final String msg = "ModifyStoragePoolCommand remove XenAPIException:" + e.getMessage() + " host:" + citrixResourceBase.getHost().getUuid() + " pool: "
|
||||
+ pool.getHost() + pool.getPath();
|
||||
logger.warn(msg, e);
|
||||
return new Answer(command, false, msg);
|
||||
return new ModifyStoragePoolAnswer(command, false, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package org.apache.cloudstack.metrics;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
|
@ -26,6 +27,7 @@ import java.util.stream.Collectors;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.ca.CAManager;
|
||||
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
||||
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
|
@ -133,6 +135,8 @@ public class PrometheusExporterImpl extends ManagerBase implements PrometheusExp
|
|||
private ResourceCountDao _resourceCountDao;
|
||||
@Inject
|
||||
private HostTagsDao _hostTagsDao;
|
||||
@Inject
|
||||
private CAManager caManager;
|
||||
|
||||
public PrometheusExporterImpl() {
|
||||
super();
|
||||
|
|
@ -216,6 +220,9 @@ public class PrometheusExporterImpl extends ManagerBase implements PrometheusExp
|
|||
}
|
||||
|
||||
metricsList.add(new ItemHostVM(zoneName, zoneUuid, host.getName(), host.getUuid(), host.getPrivateIpAddress(), vmDao.listByHostId(host.getId()).size()));
|
||||
|
||||
addSSLCertificateExpirationMetrics(metricsList, zoneName, zoneUuid, host);
|
||||
|
||||
final CapacityVO coreCapacity = capacityDao.findByHostIdType(host.getId(), Capacity.CAPACITY_TYPE_CPU_CORE);
|
||||
|
||||
if (coreCapacity == null && !host.isInMaintenanceStates()){
|
||||
|
|
@ -253,6 +260,18 @@ public class PrometheusExporterImpl extends ManagerBase implements PrometheusExp
|
|||
addHostTagsMetrics(metricsList, dcId, zoneName, zoneUuid, totalHosts, upHosts, downHosts, total, up, down);
|
||||
}
|
||||
|
||||
private void addSSLCertificateExpirationMetrics(List<Item> metricsList, String zoneName, String zoneUuid, HostVO host) {
|
||||
if (caManager == null || caManager.getActiveCertificatesMap() == null) {
|
||||
return;
|
||||
}
|
||||
X509Certificate cert = caManager.getActiveCertificatesMap().getOrDefault(host.getPrivateIpAddress(), null);
|
||||
if (cert == null) {
|
||||
return;
|
||||
}
|
||||
long certExpiryEpoch = cert.getNotAfter().getTime() / 1000; // Convert to epoch seconds
|
||||
metricsList.add(new ItemHostCertExpiry(zoneName, zoneUuid, host.getName(), host.getUuid(), host.getPrivateIpAddress(), certExpiryEpoch));
|
||||
}
|
||||
|
||||
private String markTagMaps(HostVO host, Map<String, Integer> totalHosts, Map<String, Integer> upHosts, Map<String, Integer> downHosts) {
|
||||
List<HostTagVO> hostTagVOS = _hostTagsDao.getHostTags(host.getId());
|
||||
List<String> hostTags = new ArrayList<>();
|
||||
|
|
@ -1137,4 +1156,28 @@ public class PrometheusExporterImpl extends ManagerBase implements PrometheusExp
|
|||
return String.format("%s{zone=\"%s\",cpu=\"%d\",memory=\"%d\"} %d", name, zoneName, cpu, memory, total);
|
||||
}
|
||||
}
|
||||
|
||||
class ItemHostCertExpiry extends Item {
|
||||
String zoneName;
|
||||
String zoneUuid;
|
||||
String hostName;
|
||||
String hostUuid;
|
||||
String hostIp;
|
||||
long expiryTimestamp;
|
||||
|
||||
public ItemHostCertExpiry(final String zoneName, final String zoneUuid, final String hostName, final String hostUuid, final String hostIp, final long expiry) {
|
||||
super("cloudstack_host_cert_expiry_timestamp", "Host certificate expiry timestamp in seconds since epoch", "gauge");
|
||||
this.zoneName = zoneName;
|
||||
this.zoneUuid = zoneUuid;
|
||||
this.hostName = hostName;
|
||||
this.hostUuid = hostUuid;
|
||||
this.hostIp = hostIp;
|
||||
this.expiryTimestamp = expiry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toMetricsString() {
|
||||
return String.format("%s{zone=\"%s\",hostname=\"%s\",ip=\"%s\"} %d", name, zoneName, hostName, hostIp, expiryTimestamp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,108 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.metrics;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class PrometheusExporterImplTest {
|
||||
|
||||
private static final String TEST_ZONE_NAME = "zone1";
|
||||
private static final String TEST_ZONE_UUID = "zone-uuid-1";
|
||||
private static final String TEST_HOST_NAME = "host1";
|
||||
private static final String TEST_HOST_UUID = "host-uuid-1";
|
||||
private static final String TEST_HOST_IP = "192.168.1.10";
|
||||
private static final long CERT_EXPIRY_TIME = 1735689600000L; // 2025-01-01 00:00:00 UTC
|
||||
private static final long CERT_EXPIRY_EPOCH = CERT_EXPIRY_TIME / 1000;
|
||||
|
||||
@Test
|
||||
public void testItemHostCertExpiryFormat() {
|
||||
PrometheusExporterImpl exporter = new PrometheusExporterImpl();
|
||||
PrometheusExporterImpl.ItemHostCertExpiry item = exporter.new ItemHostCertExpiry(
|
||||
TEST_ZONE_NAME,
|
||||
TEST_ZONE_UUID,
|
||||
TEST_HOST_NAME,
|
||||
TEST_HOST_UUID,
|
||||
TEST_HOST_IP,
|
||||
CERT_EXPIRY_EPOCH
|
||||
);
|
||||
|
||||
String metricsString = item.toMetricsString();
|
||||
String expected = String.format(
|
||||
"cloudstack_host_cert_expiry_timestamp{zone=\"%s\",hostname=\"%s\",ip=\"%s\"} %d",
|
||||
TEST_ZONE_NAME,
|
||||
TEST_HOST_NAME,
|
||||
TEST_HOST_IP,
|
||||
CERT_EXPIRY_EPOCH
|
||||
);
|
||||
assertEquals("Certificate expiry metric format should match expected format", expected, metricsString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testItemHostCertExpiryContainsCorrectMetricName() {
|
||||
PrometheusExporterImpl exporter = new PrometheusExporterImpl();
|
||||
PrometheusExporterImpl.ItemHostCertExpiry item = exporter.new ItemHostCertExpiry(
|
||||
TEST_ZONE_NAME,
|
||||
TEST_ZONE_UUID,
|
||||
TEST_HOST_NAME,
|
||||
TEST_HOST_UUID,
|
||||
TEST_HOST_IP,
|
||||
CERT_EXPIRY_EPOCH
|
||||
);
|
||||
|
||||
String metricsString = item.toMetricsString();
|
||||
assertTrue("Metric should contain correct metric name",
|
||||
metricsString.contains("cloudstack_host_cert_expiry_timestamp"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testItemHostCertExpiryContainsAllLabels() {
|
||||
PrometheusExporterImpl exporter = new PrometheusExporterImpl();
|
||||
PrometheusExporterImpl.ItemHostCertExpiry item = exporter.new ItemHostCertExpiry(
|
||||
TEST_ZONE_NAME,
|
||||
TEST_ZONE_UUID,
|
||||
TEST_HOST_NAME,
|
||||
TEST_HOST_UUID,
|
||||
TEST_HOST_IP,
|
||||
CERT_EXPIRY_EPOCH
|
||||
);
|
||||
|
||||
String metricsString = item.toMetricsString();
|
||||
assertTrue("Metric should contain zone label", metricsString.contains("zone=\"" + TEST_ZONE_NAME + "\""));
|
||||
assertTrue("Metric should contain hostname label", metricsString.contains("hostname=\"" + TEST_HOST_NAME + "\""));
|
||||
assertTrue("Metric should contain ip label", metricsString.contains("ip=\"" + TEST_HOST_IP + "\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testItemHostCertExpiryContainsTimestampValue() {
|
||||
PrometheusExporterImpl exporter = new PrometheusExporterImpl();
|
||||
PrometheusExporterImpl.ItemHostCertExpiry item = exporter.new ItemHostCertExpiry(
|
||||
TEST_ZONE_NAME,
|
||||
TEST_ZONE_UUID,
|
||||
TEST_HOST_NAME,
|
||||
TEST_HOST_UUID,
|
||||
TEST_HOST_IP,
|
||||
CERT_EXPIRY_EPOCH
|
||||
);
|
||||
|
||||
String metricsString = item.toMetricsString();
|
||||
assertTrue("Metric should contain correct timestamp value",
|
||||
metricsString.endsWith(" " + CERT_EXPIRY_EPOCH));
|
||||
}
|
||||
}
|
||||
|
|
@ -131,7 +131,7 @@ public class MockAccountManager extends ManagerBase implements AccountManager {
|
|||
}
|
||||
|
||||
@Override
|
||||
public User createUser(String arg0, String arg1, String arg2, String arg3, String arg4, String arg5, String arg6, Long arg7, String arg8) {
|
||||
public User createUser(String arg0, String arg1, String arg2, String arg3, String arg4, String arg5, String arg6, Long arg7, String arg8, boolean arg9) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ import org.apache.cloudstack.api.auth.APIAuthenticationType;
|
|||
import org.apache.cloudstack.api.auth.APIAuthenticator;
|
||||
import org.apache.cloudstack.api.auth.PluggableAPIAuthenticator;
|
||||
import org.apache.cloudstack.api.response.LoginCmdResponse;
|
||||
import org.apache.cloudstack.resourcedetail.UserDetailVO;
|
||||
import org.apache.cloudstack.resourcedetail.dao.UserDetailsDao;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
|
@ -74,6 +76,9 @@ public class OauthLoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthent
|
|||
@Inject
|
||||
ApiServerService _apiServer;
|
||||
|
||||
@Inject
|
||||
UserDetailsDao userDetailsDao;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -157,8 +162,10 @@ public class OauthLoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthent
|
|||
if (userAccount != null && User.Source.SAML2 == userAccount.getSource()) {
|
||||
throw new CloudAuthenticationException("User is not allowed CloudStack login");
|
||||
}
|
||||
return ApiResponseSerializer.toSerializedString(_apiServer.loginUser(session, userAccount.getUsername(), null, domainId, domain, remoteAddress, params),
|
||||
serializedResponse = ApiResponseSerializer.toSerializedString(_apiServer.loginUser(session, userAccount.getUsername(), null, domainId, domain, remoteAddress, params),
|
||||
responseType);
|
||||
userDetailsDao.addDetail(userAccount.getId(), UserDetailVO.OauthLogin, "true", false);
|
||||
return serializedResponse;
|
||||
} catch (final CloudAuthenticationException ex) {
|
||||
ApiServlet.invalidateHttpSession(session, "fall through to API key,");
|
||||
String msg = String.format("%s", ex.getMessage() != null ?
|
||||
|
|
@ -177,12 +184,8 @@ public class OauthLoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthent
|
|||
|
||||
protected Long getDomainIdFromParams(Map<String, Object[]> params, StringBuilder auditTrailSb, String responseType) {
|
||||
String[] domainIdArr = (String[])params.get(ApiConstants.DOMAIN_ID);
|
||||
|
||||
if (domainIdArr == null) {
|
||||
domainIdArr = (String[])params.get(ApiConstants.DOMAIN__ID);
|
||||
}
|
||||
Long domainId = null;
|
||||
if ((domainIdArr != null) && (domainIdArr.length > 0)) {
|
||||
if (domainIdArr != null && domainIdArr.length > 0) {
|
||||
try {
|
||||
//check if UUID is passed in for domain
|
||||
domainId = _apiServer.fetchDomainId(domainIdArr[0]);
|
||||
|
|
|
|||
|
|
@ -158,11 +158,17 @@ public class SAML2LoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthent
|
|||
String domainPath = null;
|
||||
|
||||
if (params.containsKey(ApiConstants.IDP_ID)) {
|
||||
idpId = ((String[])params.get(ApiConstants.IDP_ID))[0];
|
||||
String[] idpIds = (String[])params.get(ApiConstants.IDP_ID);
|
||||
if (idpIds != null && idpIds.length > 0) {
|
||||
idpId = idpIds[0];
|
||||
}
|
||||
}
|
||||
|
||||
if (params.containsKey(ApiConstants.DOMAIN)) {
|
||||
domainPath = ((String[])params.get(ApiConstants.DOMAIN))[0];
|
||||
String[] domainPaths = (String[])params.get(ApiConstants.DOMAIN);
|
||||
if (domainPaths != null && domainPaths.length > 0) {
|
||||
domainPath = domainPaths[0];
|
||||
}
|
||||
}
|
||||
|
||||
if (domainPath != null && !domainPath.isEmpty()) {
|
||||
|
|
|
|||
4
pom.xml
4
pom.xml
|
|
@ -1087,6 +1087,10 @@
|
|||
<exclude>utils/testsmallfileinactive</exclude>
|
||||
<exclude>**/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker</exclude>
|
||||
<exclude>.github/workflows/dependabot.yaml</exclude>
|
||||
<exclude>.gitattributes</exclude>
|
||||
<exclude>.github/workflows/*.md</exclude>
|
||||
<exclude>.github/workflows/*.lock.ya?ml</exclude>
|
||||
<exclude>.github/aw/**</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
|
|
|||
|
|
@ -116,9 +116,11 @@ import org.apache.cloudstack.framework.messagebus.MessageBus;
|
|||
import org.apache.cloudstack.framework.messagebus.MessageDispatcher;
|
||||
import org.apache.cloudstack.framework.messagebus.MessageHandler;
|
||||
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
|
||||
import org.apache.cloudstack.resourcedetail.UserDetailVO;
|
||||
import org.apache.cloudstack.user.UserPasswordResetManager;
|
||||
import org.apache.cloudstack.utils.identity.ManagementServerNode;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.commons.lang3.EnumUtils;
|
||||
import org.apache.http.ConnectionClosedException;
|
||||
import org.apache.http.HttpException;
|
||||
|
|
@ -194,6 +196,7 @@ import com.cloud.utils.net.NetUtils;
|
|||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import static com.cloud.user.AccountManagerImpl.apiKeyAccess;
|
||||
import static org.apache.cloudstack.api.ApiConstants.PASSWORD_CHANGE_REQUIRED;
|
||||
import static org.apache.cloudstack.user.UserPasswordResetManager.UserPasswordResetEnabled;
|
||||
|
||||
@Component
|
||||
|
|
@ -1227,6 +1230,9 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
|
|||
if (ApiConstants.MANAGEMENT_SERVER_ID.equalsIgnoreCase(attrName)) {
|
||||
response.setManagementServerId(attrObj.toString());
|
||||
}
|
||||
if (PASSWORD_CHANGE_REQUIRED.equalsIgnoreCase(attrName) && attrObj instanceof Boolean) {
|
||||
response.setPasswordChangeRequired((Boolean) attrObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
response.setResponseName("loginresponse");
|
||||
|
|
@ -1327,6 +1333,13 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
|
|||
final String sessionKey = Base64.encodeBase64URLSafeString(sessionKeyBytes);
|
||||
session.setAttribute(ApiConstants.SESSIONKEY, sessionKey);
|
||||
|
||||
Map<String, String> userAccDetails = userAcct.getDetails();
|
||||
if (MapUtils.isNotEmpty(userAccDetails)) {
|
||||
String needPwdChangeStr = userAccDetails.get(UserDetailVO.PasswordChangeRequired);
|
||||
if ("true".equalsIgnoreCase(needPwdChangeStr)) {
|
||||
session.setAttribute(PASSWORD_CHANGE_REQUIRED, true);
|
||||
}
|
||||
}
|
||||
return createLoginResponse(session);
|
||||
}
|
||||
throw new CloudAuthenticationException("Failed to authenticate user " + username + " in domain " + domainId + "; please provide valid credentials");
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import javax.servlet.http.HttpServletResponse;
|
|||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import com.cloud.api.auth.DefaultForgotPasswordAPIAuthenticatorCmd;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.ApiServerService;
|
||||
|
|
@ -200,7 +201,6 @@ public class ApiServlet extends HttpServlet {
|
|||
LOGGER.warn(message);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void processRequestInContext(final HttpServletRequest req, final HttpServletResponse resp) {
|
||||
|
|
@ -273,7 +273,6 @@ public class ApiServlet extends HttpServlet {
|
|||
}
|
||||
|
||||
if (command != null && !command.equals(ValidateUserTwoFactorAuthenticationCodeCmd.APINAME)) {
|
||||
|
||||
APIAuthenticator apiAuthenticator = authManager.getAPIAuthenticator(command);
|
||||
if (apiAuthenticator != null) {
|
||||
auditTrailSb.append("command=");
|
||||
|
|
@ -309,7 +308,9 @@ public class ApiServlet extends HttpServlet {
|
|||
} catch (ServerApiException e) {
|
||||
httpResponseCode = e.getErrorCode().getHttpCode();
|
||||
responseString = e.getMessage();
|
||||
LOGGER.debug("Authentication failure: " + e.getMessage());
|
||||
if (!DefaultForgotPasswordAPIAuthenticatorCmd.APINAME.equalsIgnoreCase(command) || StringUtils.isNotBlank(username)) {
|
||||
LOGGER.debug("Authentication failure: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (apiAuthenticator.getAPIType() == APIAuthenticationType.LOGOUT_API) {
|
||||
|
|
@ -390,7 +391,7 @@ public class ApiServlet extends HttpServlet {
|
|||
}
|
||||
}
|
||||
|
||||
if (! requestChecksoutAsSane(resp, auditTrailSb, responseType, params, session, command, userId, account, accountObj))
|
||||
if (!requestChecksoutAsSane(resp, auditTrailSb, responseType, params, session, command, userId, account, accountObj))
|
||||
return;
|
||||
} else {
|
||||
CallContext.register(accountMgr.getSystemUser(), accountMgr.getSystemAccount());
|
||||
|
|
@ -422,7 +423,6 @@ public class ApiServlet extends HttpServlet {
|
|||
apiServer.getSerializedApiError(HttpServletResponse.SC_UNAUTHORIZED, "unable to verify user credentials and/or request signature", params,
|
||||
responseType);
|
||||
HttpUtils.writeHttpResponse(resp, serializedResponse, HttpServletResponse.SC_UNAUTHORIZED, responseType, ApiServer.JSONcontentType.value());
|
||||
|
||||
}
|
||||
} catch (final ServerApiException se) {
|
||||
final String serializedResponseText = apiServer.getSerializedApiError(se, params, responseType);
|
||||
|
|
@ -653,6 +653,9 @@ public class ApiServlet extends HttpServlet {
|
|||
if (LOGGER.isTraceEnabled()) {
|
||||
LOGGER.trace(msg);
|
||||
}
|
||||
if (session == null) {
|
||||
return;
|
||||
}
|
||||
session.invalidate();
|
||||
} catch (final IllegalStateException ise) {
|
||||
if (LOGGER.isTraceEnabled()) {
|
||||
|
|
|
|||
|
|
@ -44,13 +44,13 @@ import java.net.InetAddress;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@APICommand(name = "forgotPassword",
|
||||
@APICommand(name = DefaultForgotPasswordAPIAuthenticatorCmd.APINAME,
|
||||
description = "Sends an email to the user with a token to reset the password using resetPassword command.",
|
||||
since = "4.20.0.0",
|
||||
requestHasSensitiveInfo = true,
|
||||
responseObject = SuccessResponse.class)
|
||||
public class DefaultForgotPasswordAPIAuthenticatorCmd extends BaseCmd implements APIAuthenticator {
|
||||
|
||||
public static final String APINAME = "forgotPassword";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
|
|
@ -108,10 +108,12 @@ public class DefaultForgotPasswordAPIAuthenticatorCmd extends BaseCmd implements
|
|||
if (userDomain != null) {
|
||||
domainId = userDomain.getId();
|
||||
} else {
|
||||
logger.debug("Unable to find the domain from the path {}", domain);
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, String.format("Unable to find the domain from the path %s", domain));
|
||||
}
|
||||
final UserAccount userAccount = _accountService.getActiveUserAccount(username[0], domainId);
|
||||
if (userAccount != null && List.of(User.Source.SAML2, User.Source.OAUTH2, User.Source.LDAP).contains(userAccount.getSource())) {
|
||||
logger.debug("Forgot Password is not allowed for the user {} from source {}", username[0], userAccount.getSource());
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Forgot Password is not allowed for this user");
|
||||
}
|
||||
boolean success = _apiServer.forgotPassword(userAccount, userDomain);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ import org.apache.cloudstack.api.auth.APIAuthenticationType;
|
|||
import org.apache.cloudstack.api.auth.APIAuthenticator;
|
||||
import org.apache.cloudstack.api.auth.PluggableAPIAuthenticator;
|
||||
import org.apache.cloudstack.api.response.LoginCmdResponse;
|
||||
import org.apache.cloudstack.resourcedetail.UserDetailVO;
|
||||
import org.apache.cloudstack.resourcedetail.dao.UserDetailsDao;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
|
@ -47,7 +49,6 @@ import java.net.InetAddress;
|
|||
@APICommand(name = "login", description = "Logs a user into the CloudStack. A successful login attempt will generate a JSESSIONID cookie value that can be passed in subsequent Query command calls until the \"logout\" command has been issued or the session has expired.", requestHasSensitiveInfo = true, responseObject = LoginCmdResponse.class, entityType = {})
|
||||
public class DefaultLoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthenticator {
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -66,6 +67,9 @@ public class DefaultLoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthe
|
|||
@Inject
|
||||
ApiServerService _apiServer;
|
||||
|
||||
@Inject
|
||||
UserDetailsDao userDetailsDao;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -107,17 +111,13 @@ public class DefaultLoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthe
|
|||
if (HTTPMethod.valueOf(req.getMethod()) != HTTPMethod.POST) {
|
||||
throw new ServerApiException(ApiErrorCode.METHOD_NOT_ALLOWED, "Please use HTTP POST to authenticate using this API");
|
||||
}
|
||||
|
||||
// FIXME: ported from ApiServlet, refactor and cleanup
|
||||
final String[] username = (String[])params.get(ApiConstants.USERNAME);
|
||||
final String[] password = (String[])params.get(ApiConstants.PASSWORD);
|
||||
String[] domainIdArr = (String[])params.get(ApiConstants.DOMAIN_ID);
|
||||
|
||||
if (domainIdArr == null) {
|
||||
domainIdArr = (String[])params.get(ApiConstants.DOMAIN__ID);
|
||||
}
|
||||
final String[] domainName = (String[])params.get(ApiConstants.DOMAIN);
|
||||
final String[] domainIdArr = (String[])params.get(ApiConstants.DOMAIN_ID);
|
||||
Long domainId = null;
|
||||
if ((domainIdArr != null) && (domainIdArr.length > 0)) {
|
||||
if (domainIdArr != null && domainIdArr.length > 0) {
|
||||
try {
|
||||
//check if UUID is passed in for domain
|
||||
domainId = _apiServer.fetchDomainId(domainIdArr[0]);
|
||||
|
|
@ -135,6 +135,7 @@ public class DefaultLoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthe
|
|||
}
|
||||
|
||||
String domain = null;
|
||||
final String[] domainName = (String[])params.get(ApiConstants.DOMAIN);
|
||||
domain = getDomainName(auditTrailSb, domainName, domain);
|
||||
|
||||
String serializedResponse = null;
|
||||
|
|
@ -151,8 +152,10 @@ public class DefaultLoginAPIAuthenticatorCmd extends BaseCmd implements APIAuthe
|
|||
if (userAccount != null && User.Source.SAML2 == userAccount.getSource()) {
|
||||
throw new CloudAuthenticationException("User is not allowed CloudStack login");
|
||||
}
|
||||
return ApiResponseSerializer.toSerializedString(_apiServer.loginUser(session, username[0], pwd, domainId, domain, remoteAddress, params),
|
||||
serializedResponse = ApiResponseSerializer.toSerializedString(_apiServer.loginUser(session, username[0], pwd, domainId, domain, remoteAddress, params),
|
||||
responseType);
|
||||
userDetailsDao.removeDetail(userAccount.getId(), UserDetailVO.OauthLogin);
|
||||
return serializedResponse;
|
||||
} catch (final CloudAuthenticationException ex) {
|
||||
ApiServlet.invalidateHttpSession(session, "fall through to API key,");
|
||||
// TODO: fall through to API key, or just fail here w/ auth error? (HTTP 401)
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ import java.util.Map;
|
|||
responseObject = SuccessResponse.class)
|
||||
public class DefaultResetPasswordAPIAuthenticatorCmd extends BaseCmd implements APIAuthenticator {
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
|||
import org.apache.cloudstack.framework.config.ConfigDepot;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
import org.apache.cloudstack.framework.config.Configurable;
|
||||
import org.apache.cloudstack.framework.config.ValidatedConfigKey;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationGroupDao;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationSubGroupDao;
|
||||
|
|
@ -764,6 +765,12 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
|||
throw new InvalidParameterValueException(validationMsg);
|
||||
}
|
||||
|
||||
ConfigKey<?> configKey = _configDepot.get(name);
|
||||
if (configKey instanceof ValidatedConfigKey) {
|
||||
ValidatedConfigKey<?> validatedConfigKey = (ValidatedConfigKey<?>) configKey;
|
||||
validatedConfigKey.validateValue(value);
|
||||
}
|
||||
|
||||
// If scope of the parameter is given then it needs to be updated in the
|
||||
// corresponding details table,
|
||||
// if scope is mentioned as global or not mentioned then it is normal
|
||||
|
|
|
|||
|
|
@ -272,7 +272,12 @@ public abstract class LibvirtServerDiscoverer extends DiscovererBase implements
|
|||
}
|
||||
}
|
||||
|
||||
sshConnection = new Connection(agentIp, 22);
|
||||
int port = uri.getPort();
|
||||
if (port <= 0) {
|
||||
port = AgentManager.KVMHostDiscoverySshPort.valueIn(clusterId);
|
||||
}
|
||||
|
||||
sshConnection = new Connection(agentIp, port);
|
||||
|
||||
sshConnection.connect(null, 60000, 60000);
|
||||
|
||||
|
|
@ -380,6 +385,9 @@ public abstract class LibvirtServerDiscoverer extends DiscovererBase implements
|
|||
Map<String, String> hostDetails = connectedHost.getDetails();
|
||||
hostDetails.put("password", password);
|
||||
hostDetails.put("username", username);
|
||||
if (uri.getPort() > 0) {
|
||||
hostDetails.put(Host.HOST_SSH_PORT, String.valueOf(uri.getPort()));
|
||||
}
|
||||
_hostDao.saveDetails(connectedHost);
|
||||
return resources;
|
||||
} catch (DiscoveredWithErrorException e) {
|
||||
|
|
|
|||
|
|
@ -851,7 +851,6 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
|||
_clusterDetailsDao.persist(cluster_cpu_detail);
|
||||
_clusterDetailsDao.persist(cluster_memory_detail);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uri = validatedHostUrl(url, hypervisorType);
|
||||
|
|
@ -945,7 +944,6 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
|||
hosts.add(host);
|
||||
}
|
||||
discoverer.postDiscovery(hosts, _nodeId);
|
||||
|
||||
}
|
||||
logger.info("server resources successfully discovered by " + discoverer.getName());
|
||||
return hosts;
|
||||
|
|
@ -3149,15 +3147,26 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
|||
private HostVO getNewHost(StartupCommand[] startupCommands) {
|
||||
StartupCommand startupCommand = startupCommands[0];
|
||||
|
||||
HostVO host = findHostByGuid(startupCommand.getGuid());
|
||||
String fullGuid = startupCommand.getGuid();
|
||||
logger.debug(String.format("Trying to find Host by guid %s", fullGuid));
|
||||
HostVO host = findHostByGuid(fullGuid);
|
||||
|
||||
if (host != null) {
|
||||
logger.debug(String.format("Found Host by guid %s: %s", fullGuid, host));
|
||||
return host;
|
||||
}
|
||||
|
||||
host = findHostByGuid(startupCommand.getGuidWithoutResource());
|
||||
String guidPrefix = startupCommand.getGuidWithoutResource();
|
||||
logger.debug(String.format("Trying to find Host by guid prefix %s", guidPrefix));
|
||||
host = findHostByGuidPrefix(guidPrefix);
|
||||
|
||||
return host; // even when host == null!
|
||||
if (host != null) {
|
||||
logger.debug(String.format("Found Host by guid prefix %s: %s", guidPrefix, host));
|
||||
return host;
|
||||
}
|
||||
|
||||
logger.debug(String.format("Could not find Host by guid %s", fullGuid));
|
||||
return null;
|
||||
}
|
||||
|
||||
protected HostVO createHostVO(final StartupCommand[] cmds, final ServerResource resource, final Map<String, String> details, List<String> hostTags,
|
||||
|
|
@ -3862,7 +3871,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
|||
*/
|
||||
protected void connectAndRestartAgentOnHost(HostVO host, String username, String password, String privateKey) {
|
||||
final com.trilead.ssh2.Connection connection = SSHCmdHelper.acquireAuthorizedConnection(
|
||||
host.getPrivateIpAddress(), 22, username, password, privateKey);
|
||||
host.getPrivateIpAddress(), _agentMgr.getHostSshPort(host), username, password, privateKey);
|
||||
if (connection == null) {
|
||||
throw new CloudRuntimeException(String.format("SSH to agent is enabled, but failed to connect to %s via IP address [%s].", host, host.getPrivateIpAddress()));
|
||||
}
|
||||
|
|
@ -4209,6 +4218,15 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
|||
public HostVO findHostByGuid(final String guid) {
|
||||
final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
|
||||
sc.and(sc.entity().getGuid(), Op.EQ, guid);
|
||||
sc.and(sc.entity().getRemoved(), Op.NULL);
|
||||
return sc.find();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HostVO findHostByGuidPrefix(String guid) {
|
||||
final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
|
||||
sc.and(sc.entity().getGuid(), Op.LIKE, guid + "%");
|
||||
sc.and(sc.entity().getRemoved(), Op.NULL);
|
||||
return sc.find();
|
||||
}
|
||||
|
||||
|
|
@ -4216,6 +4234,7 @@ public class ResourceManagerImpl extends ManagerBase implements ResourceManager,
|
|||
public HostVO findHostByName(final String name) {
|
||||
final QueryBuilder<HostVO> sc = QueryBuilder.create(HostVO.class);
|
||||
sc.and(sc.entity().getName(), Op.EQ, name);
|
||||
sc.and(sc.entity().getRemoved(), Op.NULL);
|
||||
return sc.find();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ import javax.crypto.spec.SecretKeySpec;
|
|||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.network.vpc.VpcVO;
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.acl.SecurityChecker;
|
||||
import org.apache.cloudstack.affinity.AffinityGroupProcessor;
|
||||
|
|
@ -2651,12 +2652,21 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||
}
|
||||
|
||||
if (associatedNetworkId != null) {
|
||||
_accountMgr.checkAccess(caller, null, false, networkDao.findById(associatedNetworkId));
|
||||
sc.setParameters("associatedNetworkIdEq", associatedNetworkId);
|
||||
NetworkVO associatedNetwork = networkDao.findById(associatedNetworkId);
|
||||
|
||||
if (associatedNetwork != null) {
|
||||
_accountMgr.checkAccess(caller, null, false, associatedNetwork);
|
||||
sc.setParameters("associatedNetworkIdEq", associatedNetworkId);
|
||||
}
|
||||
}
|
||||
|
||||
if (vpcId != null) {
|
||||
_accountMgr.checkAccess(caller, null, false, _vpcDao.findById(vpcId));
|
||||
sc.setParameters("vpcId", vpcId);
|
||||
VpcVO vpc = _vpcDao.findById(vpcId);
|
||||
|
||||
if (vpc != null) {
|
||||
_accountMgr.checkAccess(caller, null, false, vpc);
|
||||
sc.setParameters("vpcId", vpcId);
|
||||
}
|
||||
}
|
||||
|
||||
addrs = _publicIpAddressDao.search(sc, searchFilter); // Allocated
|
||||
|
|
@ -2673,12 +2683,15 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
|
|||
}
|
||||
if (associatedNetworkId != null) {
|
||||
NetworkVO guestNetwork = networkDao.findById(associatedNetworkId);
|
||||
if (zoneId == null) {
|
||||
zoneId = guestNetwork.getDataCenterId();
|
||||
} else if (zoneId != guestNetwork.getDataCenterId()) {
|
||||
throw new InvalidParameterValueException("Please specify a valid associated network id in the specified zone.");
|
||||
|
||||
if (guestNetwork != null) {
|
||||
if (zoneId == null) {
|
||||
zoneId = guestNetwork.getDataCenterId();
|
||||
} else if (zoneId != guestNetwork.getDataCenterId()) {
|
||||
throw new InvalidParameterValueException("Please specify a valid associated network id in the specified zone.");
|
||||
}
|
||||
owner = _accountDao.findById(guestNetwork.getAccountId());
|
||||
}
|
||||
owner = _accountDao.findById(guestNetwork.getAccountId());
|
||||
}
|
||||
List<DataCenterVO> dcList = new ArrayList<>();
|
||||
if (zoneId == null){
|
||||
|
|
|
|||
|
|
@ -221,7 +221,6 @@ import com.cloud.vm.VirtualMachineProfileImpl;
|
|||
import com.cloud.vm.VmDetailConstants;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
|
|
@ -1395,9 +1394,16 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||
else {
|
||||
vmInstanceVOList = _vmInstanceDao.listNonExpungedByTemplate(templateId);
|
||||
}
|
||||
if(!cmd.isForced() && CollectionUtils.isNotEmpty(vmInstanceVOList)) {
|
||||
final String message = String.format("Unable to delete Template: %s because Instance: [%s] are using it.", template, Joiner.on(",").join(vmInstanceVOList));
|
||||
logger.warn(message);
|
||||
if (!cmd.isForced() && CollectionUtils.isNotEmpty(vmInstanceVOList)) {
|
||||
String message = String.format("Unable to delete template [%s] because there are [%d] VM instances using it.", template, vmInstanceVOList.size());
|
||||
String instancesListMessage = String.format(" Instances list: [%s].", StringUtils.join(vmInstanceVOList, ","));
|
||||
|
||||
logger.warn("{}{}", message, instancesListMessage);
|
||||
|
||||
if (_accountMgr.isRootAdmin(caller.getAccountId())) {
|
||||
message += instancesListMessage;
|
||||
}
|
||||
|
||||
throw new InvalidParameterValueException(message);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
// under the License.
|
||||
package com.cloud.user;
|
||||
|
||||
import static org.apache.cloudstack.resourcedetail.UserDetailVO.PasswordChangeRequired;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.URLEncoder;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
|
@ -87,7 +89,6 @@ import org.apache.cloudstack.webhook.WebhookHelper;
|
|||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
|
||||
|
|
@ -180,6 +181,7 @@ import com.cloud.utils.NumbersUtil;
|
|||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.Ternary;
|
||||
import com.cloud.utils.UuidUtils;
|
||||
import com.cloud.utils.StringUtils;
|
||||
import com.cloud.utils.component.ComponentContext;
|
||||
import com.cloud.utils.component.Manager;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
|
|
@ -227,7 +229,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
@Inject
|
||||
private InstanceGroupDao _vmGroupDao;
|
||||
@Inject
|
||||
private UserAccountDao _userAccountDao;
|
||||
private UserAccountDao userAccountDao;
|
||||
@Inject
|
||||
private VolumeDao _volumeDao;
|
||||
@Inject
|
||||
|
|
@ -591,11 +593,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
if (acct == null) {
|
||||
return false; //account is deleted or does not exist
|
||||
}
|
||||
if ((isRootAdmin(accountId)) || (isDomainAdmin(accountId)) || (isResourceDomainAdmin(accountId))) {
|
||||
return true;
|
||||
} else if (acct.getType() == Account.Type.READ_ONLY_ADMIN) {
|
||||
return true;
|
||||
}
|
||||
return (isRootAdmin(accountId)) || (isDomainAdmin(accountId)) || (isResourceDomainAdmin(accountId)) || (acct.getType() == Account.Type.READ_ONLY_ADMIN);
|
||||
|
||||
}
|
||||
return false;
|
||||
|
|
@ -650,10 +648,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
@Override
|
||||
public boolean isNormalUser(long accountId) {
|
||||
AccountVO acct = _accountDao.findById(accountId);
|
||||
if (acct != null && acct.getType() == Account.Type.NORMAL) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return acct != null && acct.getType() == Account.Type.NORMAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -684,10 +679,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
if (account == null) {
|
||||
return false; //account is deleted or does not exist
|
||||
}
|
||||
if (isRootAdmin(accountId) || (account.getType() == Account.Type.ADMIN)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return isRootAdmin(accountId) || (account.getType() == Account.Type.ADMIN);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -718,7 +710,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
for (ControlledEntity entity : entities) {
|
||||
if (ownerId == null) {
|
||||
ownerId = entity.getAccountId();
|
||||
} else if (ownerId.longValue() != entity.getAccountId()) {
|
||||
} else if (! ownerId.equals(entity.getAccountId())) {
|
||||
throw new PermissionDeniedException("Entity " + entity + " and entity " + prevEntity + " belong to different accounts");
|
||||
}
|
||||
prevEntity = entity;
|
||||
|
|
@ -744,7 +736,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
domainId = account != null ? account.getDomainId() : -1;
|
||||
}
|
||||
if (entity.getAccountId() != -1 && domainId != -1 && !(entity instanceof VirtualMachineTemplate)
|
||||
&& !(entity instanceof Network && accessType != null && (accessType == AccessType.UseEntry || accessType == AccessType.OperateEntry))
|
||||
&& !(entity instanceof Network && (accessType == AccessType.UseEntry || accessType == AccessType.OperateEntry))
|
||||
&& !(entity instanceof AffinityGroup) && !(entity instanceof VirtualRouter)
|
||||
&& !(entity instanceof DnsServer)) {
|
||||
List<ControlledEntity> toBeChecked = domains.get(entity.getDomainId());
|
||||
|
|
@ -828,7 +820,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
|
||||
// Currently just for resource domain admin
|
||||
List<DataCenterVO> dcList = _dcDao.findZonesByDomainId(account.getDomainId());
|
||||
if (dcList != null && dcList.size() != 0) {
|
||||
if (CollectionUtils.isNotEmpty(dcList)) {
|
||||
return dcList.get(0).getId();
|
||||
} else {
|
||||
throw new CloudRuntimeException("Failed to find any private zone for Resource domain admin.");
|
||||
|
|
@ -843,23 +835,23 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
@Override
|
||||
public void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
UserAccountVO user = null;
|
||||
user = _userAccountDao.lockRow(id, true);
|
||||
user = userAccountDao.lockRow(id, true);
|
||||
user.setLoginAttempts(attempts);
|
||||
if (toDisable) {
|
||||
user.setState(State.DISABLED.toString());
|
||||
}
|
||||
_userAccountDao.update(id, user);
|
||||
userAccountDao.update(id, user);
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to update login attempts for user {}", () -> _userAccountDao.findById(id));
|
||||
logger.error("Failed to update login attempts for user {}", () -> userAccountDao.findById(id));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean doSetUserStatus(long userId, State state) {
|
||||
UserVO userForUpdate = _userDao.createForUpdate();
|
||||
userForUpdate.setState(state);
|
||||
return _userDao.update(Long.valueOf(userId), userForUpdate);
|
||||
return _userDao.update(userId, userForUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -868,7 +860,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
AccountVO acctForUpdate = _accountDao.createForUpdate();
|
||||
acctForUpdate.setState(State.ENABLED);
|
||||
acctForUpdate.setNeedsCleanup(false);
|
||||
success = _accountDao.update(Long.valueOf(accountId), acctForUpdate);
|
||||
success = _accountDao.update(accountId, acctForUpdate);
|
||||
return success;
|
||||
}
|
||||
|
||||
|
|
@ -881,7 +873,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
} else if (account.getState().equals(State.ENABLED)) {
|
||||
AccountVO acctForUpdate = _accountDao.createForUpdate();
|
||||
acctForUpdate.setState(State.LOCKED);
|
||||
success = _accountDao.update(Long.valueOf(accountId), acctForUpdate);
|
||||
success = _accountDao.update(accountId, acctForUpdate);
|
||||
} else {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Attempting to lock a non-enabled account {}, current state is {}, locking failed.", account, account.getState());
|
||||
|
|
@ -995,7 +987,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
}
|
||||
|
||||
// Destroy VM Snapshots
|
||||
List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.listByAccountId(Long.valueOf(accountId));
|
||||
List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.listByAccountId(accountId);
|
||||
for (VMSnapshot vmSnapshot : vmSnapshots) {
|
||||
try {
|
||||
_vmSnapshotMgr.deleteVMSnapshot(vmSnapshot.getId());
|
||||
|
|
@ -1017,8 +1009,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
try {
|
||||
_vmMgr.destroyVm(vm.getId(), false);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
logger.warn("Failed destroying instance {} as part of account deletion.", vm);
|
||||
logger.warn("Failed destroying instance {} as part of account deletion.", vm, e);
|
||||
}
|
||||
}
|
||||
// no need to catch exception at this place as expunging vm
|
||||
|
|
@ -1076,7 +1067,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
logger.debug("Deleting networks for account {}", account);
|
||||
List<NetworkVO> networks = _networkDao.listByOwner(accountId);
|
||||
if (networks != null) {
|
||||
Collections.sort(networks, new Comparator<>() {
|
||||
networks.sort(new Comparator<>() {
|
||||
@Override
|
||||
public int compare(NetworkVO network1, NetworkVO network2) {
|
||||
if (network1.getGuestType() != network2.getGuestType() && Network.GuestType.Isolated.equals(network2.getGuestType())) {
|
||||
|
|
@ -1247,7 +1238,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
} else {
|
||||
AccountVO acctForUpdate = _accountDao.createForUpdate();
|
||||
acctForUpdate.setState(State.DISABLED);
|
||||
success = _accountDao.update(Long.valueOf(accountId), acctForUpdate);
|
||||
success = _accountDao.update(accountId, acctForUpdate);
|
||||
|
||||
if (success) {
|
||||
boolean disableAccountResult = false;
|
||||
|
|
@ -1341,11 +1332,11 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
// Check permissions
|
||||
checkAccess(getCurrentCallingAccount(), domain);
|
||||
|
||||
if (!userAllowMultipleAccounts.valueInScope(ConfigKey.Scope.Domain, domainId) && !_userAccountDao.validateUsernameInDomain(userName, domainId)) {
|
||||
if (!userAllowMultipleAccounts.valueInScope(ConfigKey.Scope.Domain, domainId) && !userAccountDao.validateUsernameInDomain(userName, domainId)) {
|
||||
throw new InvalidParameterValueException(String.format("The user %s already exists in domain %s", userName, domain));
|
||||
}
|
||||
|
||||
if (networkDomain != null && networkDomain.length() > 0) {
|
||||
if (StringUtils.isNotEmpty(networkDomain)) {
|
||||
if (!NetUtils.verifyDomainName(networkDomain)) {
|
||||
throw new InvalidParameterValueException(
|
||||
"Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
|
||||
|
|
@ -1397,7 +1388,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
CallContext.current().putContextParameter(User.class, userId);
|
||||
|
||||
// check success
|
||||
return _userAccountDao.findById(userId);
|
||||
return userAccountDao.findById(userId);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1511,12 +1502,24 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User")
|
||||
public UserVO createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID,
|
||||
User.Source source) {
|
||||
User.Source source) {
|
||||
return createUser(userName, password, firstName, lastName, email, timeZone, accountName, domainId, userUUID, source, false);
|
||||
}
|
||||
|
||||
|
||||
@ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User")
|
||||
public UserVO createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID,
|
||||
User.Source source, boolean isPasswordChangeRequired) {
|
||||
// default domain to ROOT if not specified
|
||||
if (domainId == null) {
|
||||
domainId = Domain.ROOT_DOMAIN;
|
||||
}
|
||||
|
||||
if (isPasswordChangeRequired && (source == User.Source.SAML2 || source == User.Source.SAML2DISABLED || source == User.Source.LDAP)) {
|
||||
logger.warn("Enforcing password change is not permitted for source [{}].", source);
|
||||
throw new InvalidParameterValueException("CloudStack does not support enforcing password change for SAML or LDAP users.");
|
||||
}
|
||||
|
||||
Domain domain = _domainMgr.getDomain(domainId);
|
||||
if (domain == null) {
|
||||
throw new CloudRuntimeException("The domain " + domainId + " does not exist; unable to create user");
|
||||
|
|
@ -1535,7 +1538,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
throw new PermissionDeniedException(String.format("Account: %s is a system account, can't add a user to it", account));
|
||||
}
|
||||
|
||||
if (!userAllowMultipleAccounts.valueInScope(ConfigKey.Scope.Domain, domainId) && !_userAccountDao.validateUsernameInDomain(userName, domainId)) {
|
||||
if (!userAllowMultipleAccounts.valueInScope(ConfigKey.Scope.Domain, domainId) && !userAccountDao.validateUsernameInDomain(userName, domainId)) {
|
||||
throw new CloudRuntimeException("The user " + userName + " already exists in domain " + domainId);
|
||||
}
|
||||
List<UserVO> duplicatedUsers = _userDao.findUsersByName(userName);
|
||||
|
|
@ -1547,14 +1550,21 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
verifyCallerPrivilegeForUserOrAccountOperations(account);
|
||||
UserVO user;
|
||||
user = createUser(account.getId(), userName, password, firstName, lastName, email, timeZone, userUUID, source);
|
||||
if (isPasswordChangeRequired) {
|
||||
long callerAccountId = CallContext.current().getCallingAccountId();
|
||||
if ((isRootAdmin(callerAccountId) || isDomainAdmin(callerAccountId))) {
|
||||
_userDetailsDao.addDetail(user.getId(), PasswordChangeRequired, "true", false);
|
||||
}
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_USER_CREATE, eventDescription = "creating User")
|
||||
public UserVO createUser(String userName, String password, String firstName, String lastName, String email, String timeZone, String accountName, Long domainId, String userUUID) {
|
||||
public UserVO createUser(String userName, String password, String firstName, String lastName, String email,
|
||||
String timeZone, String accountName, Long domainId, String userUUID, boolean isPasswordChangeRequired) {
|
||||
|
||||
return createUser(userName, password, firstName, lastName, email, timeZone, accountName, domainId, userUUID, User.Source.UNKNOWN);
|
||||
return createUser(userName, password, firstName, lastName, email, timeZone, accountName, domainId, userUUID, User.Source.UNKNOWN, isPasswordChangeRequired);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -1588,8 +1598,39 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
if (mandate2FA != null && mandate2FA) {
|
||||
user.setUser2faEnabled(true);
|
||||
}
|
||||
validateAndUpdatePasswordChangeRequired(caller, updateUserCmd, user, account);
|
||||
_userDao.update(user.getId(), user);
|
||||
return _userAccountDao.findById(user.getId());
|
||||
return userAccountDao.findById(user.getId());
|
||||
}
|
||||
|
||||
private void validateAndUpdatePasswordChangeRequired(User caller, UpdateUserCmd updateUserCmd, UserVO user, Account account) {
|
||||
if (updateUserCmd.isPasswordChangeRequired()) {
|
||||
if (user.getState() != State.ENABLED || account.getState() != State.ENABLED) {
|
||||
throw new CloudRuntimeException("CloudStack does not support enforcing password change for locked/disabled User or Account.");
|
||||
}
|
||||
|
||||
User.Source userSource = user.getSource();
|
||||
if (userSource == User.Source.SAML2 || userSource == User.Source.SAML2DISABLED || userSource == User.Source.LDAP) {
|
||||
logger.warn("Enforcing password change is not permitted for source [{}].", user.getSource());
|
||||
throw new InvalidParameterValueException("CloudStack does not support enforcing password change for SAML or LDAP users.");
|
||||
}
|
||||
}
|
||||
|
||||
boolean isCallerSameAsUser = user.getId() == caller.getId();
|
||||
boolean isPasswordResetRequired = updateUserCmd.isPasswordChangeRequired() && !isCallerSameAsUser;
|
||||
// Admins only can enforce passwordChangeRequired for user
|
||||
if (isRootAdmin(caller.getAccountId()) || isDomainAdmin(caller.getAccountId())) {
|
||||
if (isPasswordResetRequired) {
|
||||
_userDetailsDao.addDetail(user.getId(), PasswordChangeRequired, "true", false);
|
||||
}
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(updateUserCmd.getPassword())) {
|
||||
// Remove passwordChangeRequired if user updating own pwd or admin has not enforced it
|
||||
if (isCallerSameAsUser || !isPasswordResetRequired) {
|
||||
_userDetailsDao.removeDetail(user.getId(), PasswordChangeRequired);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -1871,10 +1912,9 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
if (isApiKeyBlank && isSecretKeyBlank) {
|
||||
return;
|
||||
}
|
||||
Pair<User, Account> apiKeyOwner = _accountDao.findUserAccountByApiKey(apiKey);
|
||||
UserAccount apiKeyOwner = userAccountDao.getUserByApiKey(apiKey);
|
||||
if (apiKeyOwner != null) {
|
||||
User userThatHasTheProvidedApiKey = apiKeyOwner.first();
|
||||
if (userThatHasTheProvidedApiKey.getId() != user.getId()) {
|
||||
if (apiKeyOwner.getId() != user.getId()) {
|
||||
throw new InvalidParameterValueException(String.format("The API key [%s] already exists in the system. Please provide a unique key.", apiKey));
|
||||
}
|
||||
}
|
||||
|
|
@ -1962,7 +2002,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
CallContext.current().putContextParameter(User.class, user.getUuid());
|
||||
|
||||
// user successfully disabled
|
||||
return _userAccountDao.findById(userId);
|
||||
return userAccountDao.findById(userId);
|
||||
} else {
|
||||
throw new CloudRuntimeException(String.format("Unable to disable user %s", user));
|
||||
}
|
||||
|
|
@ -2016,7 +2056,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
|
||||
CallContext.current().putContextParameter(User.class, user.getUuid());
|
||||
|
||||
return _userAccountDao.findById(userId);
|
||||
return userAccountDao.findById(userId);
|
||||
} else {
|
||||
throw new CloudRuntimeException(String.format("Unable to enable user %s", user));
|
||||
}
|
||||
|
|
@ -2057,7 +2097,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
boolean success;
|
||||
if (user.getState().equals(State.LOCKED)) {
|
||||
// already locked...no-op
|
||||
return _userAccountDao.findById(userId);
|
||||
return userAccountDao.findById(userId);
|
||||
} else if (user.getState().equals(State.ENABLED)) {
|
||||
success = doSetUserStatus(user.getId(), State.LOCKED);
|
||||
|
||||
|
|
@ -2084,7 +2124,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
|
||||
CallContext.current().putContextParameter(User.class, user.getUuid());
|
||||
|
||||
return _userAccountDao.findById(userId);
|
||||
return userAccountDao.findById(userId);
|
||||
} else {
|
||||
throw new CloudRuntimeException(String.format("Unable to lock user %s", user));
|
||||
}
|
||||
|
|
@ -2612,7 +2652,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
|
||||
return owner;
|
||||
} else if (!isAdmin(caller.getId()) && accountName != null && domainId != null) {
|
||||
if (!accountName.equals(caller.getAccountName()) || domainId.longValue() != caller.getDomainId()) {
|
||||
if (!accountName.equals(caller.getAccountName()) || domainId != caller.getDomainId()) {
|
||||
throw new PermissionDeniedException("Can't create/list resources for account " + accountName + " in domain " + domainId + ", permission denied");
|
||||
} else {
|
||||
return caller;
|
||||
|
|
@ -2637,12 +2677,12 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
|
||||
@Override
|
||||
public UserAccount getActiveUserAccount(String username, Long domainId) {
|
||||
return _userAccountDao.getUserAccount(username, domainId);
|
||||
return userAccountDao.getUserAccount(username, domainId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserAccount> getActiveUserAccountByEmail(String email, Long domainId) {
|
||||
List<UserAccountVO> userAccountByEmail = _userAccountDao.getUserAccountByEmail(email, domainId);
|
||||
List<UserAccountVO> userAccountByEmail = userAccountDao.getUserAccountByEmail(email, domainId);
|
||||
List<UserAccount> userAccounts = userAccountByEmail.stream()
|
||||
.map(userAccountVO -> (UserAccount) userAccountVO)
|
||||
.collect(Collectors.toList());
|
||||
|
|
@ -2686,7 +2726,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
public void markUserRegistered(long userId) {
|
||||
UserVO userForUpdate = _userDao.createForUpdate();
|
||||
userForUpdate.setRegistered(true);
|
||||
_userDao.update(Long.valueOf(userId), userForUpdate);
|
||||
_userDao.update(userId, userForUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -2741,7 +2781,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
throw new CloudRuntimeException(String.format("Failed to create account name %s in domain id=%s", accountName, _domainMgr.getDomain(domainId)));
|
||||
}
|
||||
|
||||
Long accountId = account.getId();
|
||||
long accountId = account.getId();
|
||||
|
||||
if (details != null) {
|
||||
_accountDetailsDao.persist(accountId, details);
|
||||
|
|
@ -2790,7 +2830,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
|
||||
@Override
|
||||
public void logoutUser(long userId) {
|
||||
UserAccount userAcct = _userAccountDao.findById(userId);
|
||||
UserAccount userAcct = userAccountDao.findById(userId);
|
||||
if (userAcct != null) {
|
||||
ActionEventUtils.onActionEvent(userId, userAcct.getAccountId(), userAcct.getDomainId(), EventTypes.EVENT_USER_LOGOUT, "user has logged out", userId, ApiCommandResourceType.User.toString());
|
||||
} // else log some kind of error event? This likely means the user doesn't exist, or has been deleted...
|
||||
|
|
@ -2832,11 +2872,11 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
final Boolean ApiSourceCidrChecksEnabled = ApiServiceConfiguration.ApiSourceCidrChecksEnabled.value();
|
||||
|
||||
if (ApiSourceCidrChecksEnabled) {
|
||||
logger.debug("CIDRs from which account '" + account.toString() + "' is allowed to perform API calls: " + accessAllowedCidrs);
|
||||
logger.debug("CIDRs from which account '{}' is allowed to perform API calls: {}", account.toString(), accessAllowedCidrs);
|
||||
|
||||
// Block when is not in the list of allowed IPs
|
||||
if (!NetUtils.isIpInCidrList(loginIpAddress, accessAllowedCidrs.split(","))) {
|
||||
logger.warn("Request by account '" + account.toString() + "' was denied since " + loginIpAddress.toString().replace("/", "") + " does not match " + accessAllowedCidrs);
|
||||
logger.warn("Request by account '{}' was denied since {} does not match {}", account.toString(), loginIpAddress.toString().replace("/", ""), accessAllowedCidrs);
|
||||
throw new CloudAuthenticationException("Failed to authenticate user '" + username + "' in domain '" + domain.getPath() + "' from ip "
|
||||
+ loginIpAddress.toString().replace("/", "") + "; please provide valid credentials");
|
||||
}
|
||||
|
|
@ -2850,6 +2890,8 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
logger.debug(String.format("User: %s in domain %d has successfully logged in, auth time duration - %d ms", username, domainId, validUserLastAuthTimeDurationInMs));
|
||||
}
|
||||
|
||||
user.setDetails(_userDetailsDao.listDetailsKeyPairs(user.getId()));
|
||||
|
||||
return user;
|
||||
} else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
|
@ -2868,6 +2910,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
try {
|
||||
Thread.sleep(waitTimeDurationInMs);
|
||||
} catch (final InterruptedException e) {
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2879,7 +2922,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Attempting to log in user: " + username + " in domain " + domainId);
|
||||
}
|
||||
UserAccount userAccount = _userAccountDao.getUserAccount(username, domainId);
|
||||
UserAccount userAccount = userAccountDao.getUserAccount(username, domainId);
|
||||
|
||||
boolean authenticated = false;
|
||||
HashSet<ActionOnFailedAuthentication> actionsOnFailedAuthenticaion = new HashSet<>();
|
||||
|
|
@ -2909,11 +2952,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
|
||||
if (authenticated) {
|
||||
Domain domain = _domainMgr.getDomain(domainId);
|
||||
String domainName = null;
|
||||
if (domain != null) {
|
||||
domainName = domain.getName();
|
||||
}
|
||||
userAccount = _userAccountDao.getUserAccount(username, domainId);
|
||||
userAccount = userAccountDao.getUserAccount(username, domainId);
|
||||
|
||||
if (!userAccount.getState().equalsIgnoreCase(Account.State.ENABLED.toString()) || !userAccount.getAccountState().equalsIgnoreCase(Account.State.ENABLED.toString())) {
|
||||
if (logger.isInfoEnabled()) {
|
||||
|
|
@ -2973,11 +3012,9 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
|
||||
// - build a request string with sorted params, make sure it's all lowercase
|
||||
// - sign the request, verify the signature is the same
|
||||
List<String> parameterNames = new ArrayList<>();
|
||||
|
||||
for (Object paramNameObj : requestParameters.keySet()) {
|
||||
parameterNames.add((String)paramNameObj); // put the name in a list that we'll sort later
|
||||
}
|
||||
// put the name in a list that we'll sort later
|
||||
List<String> parameterNames = new ArrayList<>(requestParameters.keySet());
|
||||
|
||||
Collections.sort(parameterNames);
|
||||
|
||||
|
|
@ -3009,7 +3046,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
if (unsignedRequestBuffer.length() != 0) {
|
||||
unsignedRequestBuffer.append("&");
|
||||
}
|
||||
unsignedRequestBuffer.append(paramName).append("=").append(URLEncoder.encode(paramValue, "UTF-8"));
|
||||
unsignedRequestBuffer.append(paramName).append("=").append(URLEncoder.encode(paramValue, com.cloud.utils.StringUtils.getPreferredCharset()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3032,7 +3069,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
if (!equalSig) {
|
||||
logger.info("User signature: " + signature + " is not equaled to computed signature: " + computedSignature);
|
||||
} else {
|
||||
user = _userAccountDao.getUserAccount(username, domainId);
|
||||
user = userAccountDao.getUserAccount(username, domainId);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
logger.error("Exception authenticating user", ex);
|
||||
|
|
@ -3060,7 +3097,14 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
|
||||
@Override
|
||||
public Pair<User, Account> findUserByApiKey(String apiKey) {
|
||||
return _accountDao.findUserAccountByApiKey(apiKey);
|
||||
UserAccount userAccount = userAccountDao.getUserByApiKey(apiKey);
|
||||
if (userAccount != null) {
|
||||
User user = _userDao.getUser(userAccount.getId());
|
||||
Account account = _accountDao.findById(userAccount.getAccountId());
|
||||
return new Pair<>(user, account);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -3194,14 +3238,14 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
UserVO updatedUser = _userDao.createForUpdate();
|
||||
|
||||
String encodedKey;
|
||||
Pair<User, Account> userAcct;
|
||||
UserAccount userAcct;
|
||||
int retryLimit = 10;
|
||||
do {
|
||||
// FIXME: what algorithm should we use for API keys?
|
||||
KeyGenerator generator = KeyGenerator.getInstance("HmacSHA1");
|
||||
SecretKey key = generator.generateKey();
|
||||
encodedKey = Base64.encodeBase64URLSafeString(key.getEncoded());
|
||||
userAcct = _accountDao.findUserAccountByApiKey(encodedKey);
|
||||
userAcct = userAccountDao.getUserByApiKey(encodedKey);
|
||||
retryLimit--;
|
||||
} while ((userAcct != null) && (retryLimit >= 0));
|
||||
|
||||
|
|
@ -3212,7 +3256,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
_userDao.update(userId, updatedUser);
|
||||
return encodedKey;
|
||||
} catch (NoSuchAlgorithmException ex) {
|
||||
logger.error("error generating secret key for user {}", _userAccountDao.findById(userId), ex);
|
||||
logger.error("error generating secret key for user {}", userAccountDao.findById(userId), ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -3239,7 +3283,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
_userDao.update(userId, updatedUser);
|
||||
return encodedKey;
|
||||
} catch (NoSuchAlgorithmException ex) {
|
||||
logger.error("error generating secret key for user {}", _userAccountDao.findById(userId), ex);
|
||||
logger.error("error generating secret key for user {}", userAccountDao.findById(userId), ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -3450,12 +3494,12 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
|
||||
@Override
|
||||
public UserAccount getUserByApiKey(String apiKey) {
|
||||
return _userAccountDao.getUserByApiKey(apiKey);
|
||||
return userAccountDao.getUserByApiKey(apiKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> listAclGroupsByAccount(Long accountId) {
|
||||
if (_querySelectors == null || _querySelectors.size() == 0) {
|
||||
if (CollectionUtils.isEmpty(_querySelectors)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
|
|
@ -3510,7 +3554,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
|
||||
@Override
|
||||
public UserAccount getUserAccountById(Long userId) {
|
||||
UserAccount userAccount = _userAccountDao.findById(userId);
|
||||
UserAccount userAccount = userAccountDao.findById(userId);
|
||||
Map<String, String> details = _userDetailsDao.listDetailsKeyPairs(userId);
|
||||
userAccount.setDetails(details);
|
||||
|
||||
|
|
@ -3699,7 +3743,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
}
|
||||
|
||||
protected UserTwoFactorAuthenticationSetupResponse enableTwoFactorAuthentication(Long userId, String providerName) {
|
||||
UserAccountVO userAccount = _userAccountDao.findById(userId);
|
||||
UserAccountVO userAccount = userAccountDao.findById(userId);
|
||||
UserVO userVO = _userDao.findById(userId);
|
||||
Long domainId = userAccount.getDomainId();
|
||||
if (Boolean.FALSE.equals(enableUserTwoFactorAuthentication.valueIn(domainId)) && Boolean.FALSE.equals(mandateUserTwoFactorAuthentication.valueIn(domainId))) {
|
||||
|
|
@ -3791,11 +3835,11 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
if (userDetailVO != null) {
|
||||
_userDetailsDao.remove(userDetailVO.getId());
|
||||
}
|
||||
UserAccountVO userAccountVO = _userAccountDao.findById(user.getId());
|
||||
UserAccountVO userAccountVO = userAccountDao.findById(user.getId());
|
||||
userAccountVO.setUser2faEnabled(false);
|
||||
userAccountVO.setUser2faProvider(null);
|
||||
userAccountVO.setKeyFor2fa(null);
|
||||
_userAccountDao.update(user.getId(), userAccountVO);
|
||||
userAccountDao.update(user.getId(), userAccountVO);
|
||||
return userAccountVO;
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1728,10 +1728,10 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
|
|||
if (StringUtils.isEmpty(name)) {
|
||||
throw new CloudRuntimeException("Invalid backup provider name provided");
|
||||
}
|
||||
if (!backupProvidersMap.containsKey(name)) {
|
||||
throw new CloudRuntimeException("Failed to find backup provider by the name: " + name);
|
||||
}
|
||||
return backupProvidersMap.get(name);
|
||||
if (!backupProvidersMap.containsKey(name)) {
|
||||
throw new CloudRuntimeException("Failed to find backup provider by the name: " + name);
|
||||
}
|
||||
return backupProvidersMap.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -139,23 +139,23 @@ public class HeuristicRuleHelper {
|
|||
* @param presetVariables used for injecting in the JS interpreter.
|
||||
*/
|
||||
protected void injectPresetVariables(JsInterpreter jsInterpreter, PresetVariables presetVariables) {
|
||||
jsInterpreter.injectVariable("secondaryStorages", presetVariables.getSecondaryStorages().toString());
|
||||
jsInterpreter.injectVariable("secondaryStorages", presetVariables.getSecondaryStorages());
|
||||
|
||||
if (presetVariables.getTemplate() != null) {
|
||||
jsInterpreter.injectVariable("template", presetVariables.getTemplate().toString());
|
||||
jsInterpreter.injectVariable("iso", presetVariables.getTemplate().toString());
|
||||
jsInterpreter.injectVariable("template", presetVariables.getTemplate());
|
||||
jsInterpreter.injectVariable("iso", presetVariables.getTemplate());
|
||||
}
|
||||
|
||||
if (presetVariables.getSnapshot() != null) {
|
||||
jsInterpreter.injectVariable("snapshot", presetVariables.getSnapshot().toString());
|
||||
jsInterpreter.injectVariable("snapshot", presetVariables.getSnapshot());
|
||||
}
|
||||
|
||||
if (presetVariables.getVolume() != null) {
|
||||
jsInterpreter.injectVariable("volume", presetVariables.getVolume().toString());
|
||||
jsInterpreter.injectVariable("volume", presetVariables.getVolume());
|
||||
}
|
||||
|
||||
if (presetVariables.getAccount() != null) {
|
||||
jsInterpreter.injectVariable("account", presetVariables.getAccount().toString());
|
||||
jsInterpreter.injectVariable("account", presetVariables.getAccount());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -185,8 +185,8 @@ public class HeuristicRuleHelper {
|
|||
Template template = new Template();
|
||||
|
||||
template.setName(templateVO.getName());
|
||||
template.setFormat(templateVO.getFormat());
|
||||
template.setHypervisorType(templateVO.getHypervisorType());
|
||||
template.setFormat(templateVO.getFormat().toString());
|
||||
template.setHypervisorType(templateVO.getHypervisorType().toString());
|
||||
|
||||
return template;
|
||||
}
|
||||
|
|
@ -195,7 +195,7 @@ public class HeuristicRuleHelper {
|
|||
Volume volumePresetVariable = new Volume();
|
||||
|
||||
volumePresetVariable.setName(volumeVO.getName());
|
||||
volumePresetVariable.setFormat(volumeVO.getFormat());
|
||||
volumePresetVariable.setFormat(volumeVO.getFormat().toString());
|
||||
volumePresetVariable.setSize(volumeVO.getSize());
|
||||
|
||||
return volumePresetVariable;
|
||||
|
|
@ -206,7 +206,7 @@ public class HeuristicRuleHelper {
|
|||
|
||||
snapshot.setName(snapshotInfo.getName());
|
||||
snapshot.setSize(snapshotInfo.getSize());
|
||||
snapshot.setHypervisorType(snapshotInfo.getHypervisorType());
|
||||
snapshot.setHypervisorType(snapshotInfo.getHypervisorType().toString());
|
||||
|
||||
return snapshot;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ public class Account extends GenericHeuristicPresetVariable {
|
|||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
fieldNamesToIncludeInToString.add("id");
|
||||
}
|
||||
|
||||
public Domain getDomain() {
|
||||
|
|
@ -36,6 +35,5 @@ public class Account extends GenericHeuristicPresetVariable {
|
|||
|
||||
public void setDomain(Domain domain) {
|
||||
this.domain = domain;
|
||||
fieldNamesToIncludeInToString.add("domain");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,5 @@ public class Domain extends GenericHeuristicPresetVariable {
|
|||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
fieldNamesToIncludeInToString.add("id");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,15 +16,11 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.storage.heuristics.presetvariables;
|
||||
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
public class GenericHeuristicPresetVariable {
|
||||
|
||||
protected transient Set<String> fieldNamesToIncludeInToString = new HashSet<>();
|
||||
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
|
|
@ -33,15 +29,10 @@ public class GenericHeuristicPresetVariable {
|
|||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
fieldNamesToIncludeInToString.add("name");
|
||||
}
|
||||
|
||||
/***
|
||||
* Converts the preset variable into a valid JSON object that will be injected into the JS interpreter.
|
||||
* This method should not be overridden or changed.
|
||||
*/
|
||||
@Override
|
||||
public final String toString() {
|
||||
return ReflectionToStringBuilderUtils.reflectOnlySelectedFields(this, fieldNamesToIncludeInToString.toArray(new String[0]));
|
||||
public String toString() {
|
||||
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ public class SecondaryStorage extends GenericHeuristicPresetVariable {
|
|||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
fieldNamesToIncludeInToString.add("id");
|
||||
}
|
||||
|
||||
public Long getUsedDiskSize() {
|
||||
|
|
@ -41,7 +40,6 @@ public class SecondaryStorage extends GenericHeuristicPresetVariable {
|
|||
|
||||
public void setUsedDiskSize(Long usedDiskSize) {
|
||||
this.usedDiskSize = usedDiskSize;
|
||||
fieldNamesToIncludeInToString.add("usedDiskSize");
|
||||
}
|
||||
|
||||
public Long getTotalDiskSize() {
|
||||
|
|
@ -50,7 +48,6 @@ public class SecondaryStorage extends GenericHeuristicPresetVariable {
|
|||
|
||||
public void setTotalDiskSize(Long totalDiskSize) {
|
||||
this.totalDiskSize = totalDiskSize;
|
||||
fieldNamesToIncludeInToString.add("totalDiskSize");
|
||||
}
|
||||
|
||||
public String getProtocol() {
|
||||
|
|
@ -59,6 +56,5 @@ public class SecondaryStorage extends GenericHeuristicPresetVariable {
|
|||
|
||||
public void setProtocol(String protocol) {
|
||||
this.protocol = protocol;
|
||||
fieldNamesToIncludeInToString.add("protocol");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,13 +16,11 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.storage.heuristics.presetvariables;
|
||||
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
|
||||
public class Snapshot extends GenericHeuristicPresetVariable {
|
||||
|
||||
private Long size;
|
||||
|
||||
private Hypervisor.HypervisorType hypervisorType;
|
||||
private String hypervisorType;
|
||||
|
||||
public Long getSize() {
|
||||
return size;
|
||||
|
|
@ -30,15 +28,13 @@ public class Snapshot extends GenericHeuristicPresetVariable {
|
|||
|
||||
public void setSize(Long size) {
|
||||
this.size = size;
|
||||
fieldNamesToIncludeInToString.add("size");
|
||||
}
|
||||
|
||||
public Hypervisor.HypervisorType getHypervisorType() {
|
||||
public String getHypervisorType() {
|
||||
return hypervisorType;
|
||||
}
|
||||
|
||||
public void setHypervisorType(Hypervisor.HypervisorType hypervisorType) {
|
||||
public void setHypervisorType(String hypervisorType) {
|
||||
this.hypervisorType = hypervisorType;
|
||||
fieldNamesToIncludeInToString.add("hypervisorType");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue