Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
e8e5820
KNIB
May 30, 2025
8a94dcb
fix minor cherry pick error
JoaoJandre Mar 6, 2026
0cc9b33
Merge remote-tracking branch 'origin/main' into new-native-backup-pro…
JoaoJandre Mar 9, 2026
4b1fcec
fix end of files
JoaoJandre Mar 10, 2026
bfdcf47
Add backup validation
Mar 13, 2026
d69ab99
Merge remote-tracking branch 'origin/main' into new-native-backup-pro…
JoaoJandre Mar 16, 2026
c0cc044
add RATs
JoaoJandre Mar 16, 2026
fe64ef4
Merge remote-tracking branch 'origin/main' into new-native-backup-pro…
JoaoJandre Mar 19, 2026
0327571
- remove native backup offering APIs
JoaoJandre Mar 25, 2026
aad4701
fix tests
JoaoJandre Mar 25, 2026
0d38d85
add finishBackupChain command
JoaoJandre Apr 1, 2026
4642dd7
knib -> kboss
JoaoJandre Apr 1, 2026
68848cc
Merge remote-tracking branch 'origin/main' into new-native-backup-pro…
JoaoJandre Apr 2, 2026
1a8a783
disable validation vm nic
JoaoJandre Apr 2, 2026
bf55b7b
fix rat
JoaoJandre Apr 2, 2026
0b84f3a
add json sanitization
JoaoJandre Apr 2, 2026
2f0f260
small fix on cleanup
JoaoJandre Apr 2, 2026
1484edb
Add tests to KbossBackupProviderTest
JoaoJandre Apr 7, 2026
184a45f
Merge remote-tracking branch 'origin/main' into new-native-backup-pro…
JoaoJandre Apr 10, 2026
756ea85
add InternalBackupServiceImplTest
JoaoJandre Apr 10, 2026
4db575c
Add tests to Service Job Controllers
JoaoJandre Apr 14, 2026
04c1064
Merge remote-tracking branch 'origin/main' into new-native-backup-pro…
JoaoJandre Apr 14, 2026
c44455a
post merge fixes
JoaoJandre Apr 14, 2026
0454e8c
fix rat
JoaoJandre Apr 14, 2026
5f38aaa
fix build
JoaoJandre Apr 14, 2026
ed4b986
Add more tests
JoaoJandre Apr 16, 2026
57a4601
even more tests
JoaoJandre Apr 17, 2026
44f2393
Merge remote-tracking branch 'origin/main' into new-native-backup-pro…
JoaoJandre Apr 17, 2026
22c5bb3
fix checkstyle
JoaoJandre Apr 17, 2026
9f20c8d
Very minor refactor
Apr 20, 2026
0428948
fix checkstyle
JoaoJandre Apr 20, 2026
f4cf4f9
another minor refactor
JoaoJandre Apr 20, 2026
8306d7b
smoke tests
JoaoJandre Apr 22, 2026
82c9a0c
Address reviews
JoaoJandre Apr 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Merge remote-tracking branch 'origin/main' into new-native-backup-pro…
…vider
  • Loading branch information
JoaoJandre committed Mar 9, 2026
commit 0cc9b3382270493c743ee65064221360fa542873
Original file line number Diff line number Diff line change
Expand Up @@ -590,5 +590,9 @@ List<TemplateResponse> createTemplateResponses(ResponseView view, VirtualMachine

ConsoleSessionResponse createConsoleSessionResponse(ConsoleSession consoleSession, ResponseView responseView);

ApiKeyPairResponse createKeyPairResponse(ApiKeyPair keyPair);

ListResponse<BaseRolePermissionResponse> createKeypairPermissionsResponse(List<ApiKeyPairPermission> permissions);

NativeBackupOfferingResponse createNativeBackupOfferingResponse(NativeBackupOffering offering);
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,55 @@ CREATE TABLE IF NOT EXISTS `cloud`.`webhook_filter` (
CONSTRAINT `fk_webhook_filter__webhook_id` FOREIGN KEY(`webhook_id`) REFERENCES `webhook`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- "api_keypair" table for API and secret keys
CREATE TABLE IF NOT EXISTS `cloud`.`api_keypair` (
`id` bigint(20) unsigned NOT NULL auto_increment,
`uuid` varchar(40) UNIQUE NOT NULL,
`name` varchar(255) NOT NULL,
`domain_id` bigint(20) unsigned NOT NULL,
`account_id` bigint(20) unsigned NOT NULL,
`user_id` bigint(20) unsigned NOT NULL,
`start_date` datetime,
`end_date` datetime,
`description` varchar(100),
`api_key` varchar(255) NOT NULL,
`secret_key` varchar(255) NOT NULL,
`created` datetime NOT NULL,
`removed` datetime,
PRIMARY KEY (`id`),
CONSTRAINT `fk_api_keypair__user_id` FOREIGN KEY(`user_id`) REFERENCES `cloud`.`user`(`id`),
CONSTRAINT `fk_api_keypair__account_id` FOREIGN KEY(`account_id`) REFERENCES `cloud`.`account`(`id`),
CONSTRAINT `fk_api_keypair__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `cloud`.`domain`(`id`)
);

-- "api_keypair_permissions" table for API key pairs permissions
CREATE TABLE IF NOT EXISTS `cloud`.`api_keypair_permissions` (
`id` bigint(20) unsigned NOT NULL auto_increment,
`uuid` varchar(40) UNIQUE,
`sort_order` bigint(20) unsigned NOT NULL DEFAULT 0,
`rule` varchar(255) NOT NULL,
`api_keypair_id` bigint(20) unsigned NOT NULL,
`permission` varchar(255) NOT NULL,
`description` varchar(255),
PRIMARY KEY (`id`),
CONSTRAINT `fk_keypair_permissions__api_keypair_id` FOREIGN KEY(`api_keypair_id`) REFERENCES `cloud`.`api_keypair`(`id`)
);

-- Populate "api_keypair" table with existing user API keys
INSERT INTO `cloud`.`api_keypair` (uuid, user_id, domain_id, account_id, api_key, secret_key, created, name)
SELECT UUID(), user.id, account.domain_id, account.id, user.api_key, user.secret_key, NOW(), 'Active key pair'
FROM `cloud`.`user` AS user
JOIN `cloud`.`account` AS account ON user.account_id = account.id
WHERE user.api_key IS NOT NULL AND user.secret_key IS NOT NULL;

-- Drop API keys from user table
ALTER TABLE `cloud`.`user` DROP COLUMN api_key, DROP COLUMN secret_key;

-- Grant access to the "deleteUserKeys" API to the "User", "Domain Admin" and "Resource Admin" roles, similarly to the "registerUserKeys" API
CALL `cloud`.`IDEMPOTENT_UPDATE_API_PERMISSION`('User', 'deleteUserKeys', 'ALLOW');
CALL `cloud`.`IDEMPOTENT_UPDATE_API_PERMISSION`('Domain Admin', 'deleteUserKeys', 'ALLOW');
CALL `cloud`.`IDEMPOTENT_UPDATE_API_PERMISSION`('Resource Admin', 'deleteUserKeys', 'ALLOW');

-- KNIB

CREATE TABLE IF NOT EXISTS `cloud`.`native_backup_pool_ref` (
Expand Down
75 changes: 75 additions & 0 deletions server/src/main/java/com/cloud/api/ApiResponseHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -5729,6 +5729,81 @@ public ConsoleSessionResponse createConsoleSessionResponse(ConsoleSession consol
return consoleSessionResponse;
}

@Override
public ApiKeyPairResponse createKeyPairResponse(ApiKeyPair keyPair) {
ApiKeyPairResponse apiKeyPairResponse = new ApiKeyPairResponse();

populateApiKeyPairInApiKeyPairResponse(keyPair, apiKeyPairResponse);
populateUserInApiKeyPairResponse(keyPair, apiKeyPairResponse);

AccountVO account = accountDao.findByIdIncludingRemoved(keyPair.getAccountId());
apiKeyPairResponse.setAccountId(account.getUuid());
apiKeyPairResponse.setAccountName(account.getAccountName());
apiKeyPairResponse.setAccountType(account.getType().toString());

populateDomainInApiKeyPairResponse(account.getDomainId(), apiKeyPairResponse);
populateRoleInApiKeyPairResponse(account.getRoleId(), apiKeyPairResponse);

return apiKeyPairResponse;
}

protected void populateRoleInApiKeyPairResponse(Long roleId, ApiKeyPairResponse apiKeyPairResponse) {
RoleVO roleVO = roleDao.findById(roleId);
apiKeyPairResponse.setRoleId(roleVO.getUuid());
apiKeyPairResponse.setRoleName(roleVO.getName());
apiKeyPairResponse.setRoleType(roleVO.getRoleType().name());
}

protected static void populateApiKeyPairInApiKeyPairResponse(ApiKeyPair keyPair, ApiKeyPairResponse apiKeyPairResponse) {
apiKeyPairResponse.setName(keyPair.getName());
apiKeyPairResponse.setApiKey(keyPair.getApiKey());
apiKeyPairResponse.setSecretKey(keyPair.getSecretKey());
apiKeyPairResponse.setDescription(keyPair.getDescription());
apiKeyPairResponse.setId(keyPair.getUuid());
apiKeyPairResponse.setCreated(keyPair.getCreated());
apiKeyPairResponse.setStartDate(keyPair.getStartDate());
apiKeyPairResponse.setEndDate(keyPair.getEndDate());

ApiKeyPairState state = ApiKeyPairState.ENABLED;
if (keyPair.getRemoved() != null) {
state = ApiKeyPairState.REMOVED;
} else if (keyPair.hasEndDatePassed()) {
state = ApiKeyPairState.EXPIRED;
}
apiKeyPairResponse.setState(state);
}

protected void populateUserInApiKeyPairResponse(ApiKeyPair keyPair, ApiKeyPairResponse apiKeyPairResponse) {
User user = ApiDBUtils.findUserById(keyPair.getUserId());
apiKeyPairResponse.setUserId(user.getUuid());
apiKeyPairResponse.setUsername(user.getUsername());
}

protected void populateDomainInApiKeyPairResponse(Long domainId, ApiKeyPairResponse apiKeyPairResponse) {
DomainVO domainVO = domainDao.findById(domainId);
apiKeyPairResponse.setDomainId(domainVO.getUuid());
apiKeyPairResponse.setDomainName(domainVO.getName());
StringBuilder domainPath = new StringBuilder("ROOT");
(domainPath.append(domainVO.getPath())).deleteCharAt(domainPath.length() - 1);
apiKeyPairResponse.setDomainPath(domainPath.toString());
}

@Override
public ListResponse<BaseRolePermissionResponse> createKeypairPermissionsResponse(final List<ApiKeyPairPermission> permissions) {
final ListResponse<BaseRolePermissionResponse> response = new ListResponse<>();
final List<BaseRolePermissionResponse> permissionResponses = new ArrayList<>();
for (final ApiKeyPairPermission permission : permissions) {
BaseRolePermissionResponse permissionResponse = new BaseRolePermissionResponse();
permissionResponse.setRule(permission.getRule());
permissionResponse.setRulePermission(permission.getPermission());
permissionResponse.setDescription(permission.getDescription());
permissionResponse.setObjectName("keypermission");
permissionResponses.add(permissionResponse);
}
response.setResponses(permissionResponses);
return response;
}

@Override
public NativeBackupOfferingResponse createNativeBackupOfferingResponse(NativeBackupOffering offering) {
return new NativeBackupOfferingResponse(offering.getUuid(), offering.getName(), offering.isCompress(), offering.isValidate(), offering.isAllowQuickRestore(),
Expand Down
10 changes: 10 additions & 0 deletions server/src/main/java/com/cloud/api/query/QueryManagerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@

import javax.inject.Inject;

import com.cloud.network.PublicIpQuarantine;
import com.cloud.network.dao.PublicIpQuarantineDao;
import com.cloud.network.vo.PublicIpQuarantineVO;
import com.cloud.user.UserVO;
import org.apache.cloudstack.acl.RoleService;
import org.apache.cloudstack.acl.RoleVO;
import org.apache.cloudstack.acl.dao.RoleDao;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.Pod;
Expand Down Expand Up @@ -658,6 +665,9 @@ public class QueryManagerImpl extends MutualExclusiveIdsManagerBase implements Q
@Inject
ExtensionHelper extensionHelper;

@Inject
RoleDao roleDao;

@Inject
private NativeBackupOfferingDao nativeBackupOfferingDao;

Expand Down
Loading
You are viewing a condensed version of this merge commit. You can view the full changes here.