Skip to content

Commit a1bb7ae

Browse files
committed
Adding api keys during cluster creation
1 parent 43b27ae commit a1bb7ae

File tree

7 files changed

+101
-141
lines changed

7 files changed

+101
-141
lines changed

engine/schema/src/main/resources/META-INF/db/schema-41400to41500.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,8 @@ ALTER VIEW `cloud`.`image_store_view` AS
222222
`cloud`.`image_store_details` ON image_store_details.store_id = image_store.id;
223223

224224
-- TODO : Move to 416
225-
ALTER TABLE `cloud`.`kubernetes_cluster` ADD COLUMN `autoscaling_enabled` tinyint(1) NOT NULL DEFAULT '0';
225+
ALTER TABLE `cloud`.`kubernetes_cluster` ADD COLUMN `autoscaling_enabled` tinyint(1) unsigned NOT NULL DEFAULT 0;
226226
ALTER TABLE `cloud`.`kubernetes_cluster` ADD COLUMN `minsize` bigint;
227227
ALTER TABLE `cloud`.`kubernetes_cluster` ADD COLUMN `maxsize` bigint;
228228

229-
ALTER TABLE `cloud`.`kubernetes_cluster_vm_map` ADD COLUMN `is_master` tinyint(1) NOT NULL DEFAULT '0';
229+
ALTER TABLE `cloud`.`kubernetes_cluster_vm_map` ADD COLUMN `is_master` tinyint(1) unsigned NOT NULL DEFAULT 0;

plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesCluster.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ enum Event {
3737
StopRequested,
3838
DestroyRequested,
3939
RecoveryRequested,
40+
AutoscaleRequested,
4041
ScaleUpRequested,
4142
ScaleDownRequested,
4243
UpgradeRequested,
@@ -81,6 +82,7 @@ enum State {
8182

8283
s_fsm.addTransition(State.Running, Event.FaultsDetected, State.Alert);
8384

85+
s_fsm.addTransition(State.Running, Event.AutoscaleRequested, State.Scaling);
8486
s_fsm.addTransition(State.Running, Event.ScaleUpRequested, State.Scaling);
8587
s_fsm.addTransition(State.Running, Event.ScaleDownRequested, State.Scaling);
8688
s_fsm.addTransition(State.Scaling, Event.OperationSucceeded, State.Running);

plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java

Lines changed: 14 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,18 @@
2626
import java.util.HashMap;
2727
import java.util.List;
2828
import java.util.Map;
29-
import java.util.UUID;
3029
import java.util.concurrent.ConcurrentHashMap;
3130
import java.util.concurrent.Executors;
3231
import java.util.concurrent.ScheduledExecutorService;
3332
import java.util.concurrent.TimeUnit;
3433
import java.util.regex.Matcher;
3534
import java.util.regex.Pattern;
36-
import java.util.stream.Collectors;
3735

3836
import javax.inject.Inject;
3937
import javax.naming.ConfigurationException;
4038

4139
import org.apache.cloudstack.acl.ControlledEntity;
42-
import org.apache.cloudstack.acl.Role;
43-
import org.apache.cloudstack.acl.RoleService;
44-
import org.apache.cloudstack.acl.RoleType;
45-
import org.apache.cloudstack.acl.Rule;
4640
import org.apache.cloudstack.acl.SecurityChecker;
47-
import org.apache.cloudstack.acl.RolePermissionEntity.Permission;
4841
import org.apache.cloudstack.api.ApiConstants;
4942
import org.apache.cloudstack.api.ApiConstants.VMDetails;
5043
import org.apache.cloudstack.api.ResponseObject.ResponseView;
@@ -141,7 +134,6 @@
141134
import com.cloud.user.Account;
142135
import com.cloud.user.AccountManager;
143136
import com.cloud.user.AccountService;
144-
import com.cloud.user.AccountVO;
145137
import com.cloud.user.SSHKeyPairVO;
146138
import com.cloud.user.User;
147139
import com.cloud.user.UserAccount;
@@ -210,8 +202,6 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
210202
@Inject
211203
protected AccountDao accountDao;
212204
@Inject
213-
protected RoleService roleService;
214-
@Inject
215205
protected AccountService accountService;
216206
@Inject
217207
protected AccountManager accountManager;
@@ -244,45 +234,6 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
244234
@Inject
245235
protected FirewallRulesDao firewallRulesDao;
246236

247-
private Role createKubeadminRole() {
248-
Role kubeadminRole = roleService.createRole(KUBEADMIN_ACCOUNT_NAME, RoleType.Admin, "Default Kubeadmin role");
249-
roleService.createRolePermission(kubeadminRole, new Rule("listKubernetesClusters"), Permission.ALLOW, "");
250-
roleService.createRolePermission(kubeadminRole, new Rule("scaleKubernetesCluster"), Permission.ALLOW, "");
251-
roleService.createRolePermission(kubeadminRole, new Rule("*"), Permission.DENY, "");
252-
return kubeadminRole;
253-
}
254-
255-
private void init() {
256-
257-
// Check and create Kubeadmin role
258-
Role kubeadminRole = null;
259-
List<Role> roles = roleService.findRolesByName(KUBEADMIN_ACCOUNT_NAME);
260-
if (roles == null) {
261-
kubeadminRole = createKubeadminRole();
262-
} else {
263-
roles = roles.stream().filter(x -> x.getDescription() == "Default Kubeadmin role").collect(Collectors.toList());
264-
if (roles.size() != 1 ) {
265-
kubeadminRole = createKubeadminRole();
266-
} else {
267-
kubeadminRole = roles.get(0);
268-
}
269-
}
270-
271-
// Check and create Kubeadmin account
272-
if (accountManager.getActiveAccountByName(KUBEADMIN_ACCOUNT_NAME, 1L) != null) {
273-
return;
274-
}
275-
276-
AccountVO kubeadmin = new AccountVO();
277-
kubeadmin.setAccountName(KUBEADMIN_ACCOUNT_NAME);
278-
kubeadmin.setUuid(UUID.randomUUID().toString());
279-
kubeadmin.setState(Account.State.enabled);
280-
kubeadmin.setDomainId(1);
281-
kubeadmin.setType(RoleType.Admin.getAccountType());
282-
kubeadmin.setRoleId(kubeadminRole.getId());
283-
kubeadmin = accountDao.persist(kubeadmin);
284-
}
285-
286237
private void logMessage(final Level logLevel, final String message, final Exception e) {
287238
if (logLevel == Level.WARN) {
288239
if (e != null) {
@@ -946,11 +897,6 @@ private void validateKubernetesClusterScaleParameters(ScaleKubernetesClusterCmd
946897
throw new InvalidParameterValueException("autoscaling can not be passed along with nodeids or clustersize or service offering");
947898
}
948899

949-
String csUrl = ApiServiceConfiguration.ApiServletPath.value();
950-
if (csUrl == null || csUrl.contains("localhost")) {
951-
throw new InvalidParameterValueException("Global setting endpointe.url has to be set to the Management Server's API end point");
952-
}
953-
954900
if (minSize == null || maxSize == null) {
955901
throw new InvalidParameterValueException("autoscaling requires minsize and maxsize to be passed");
956902
}
@@ -1105,6 +1051,12 @@ public KubernetesCluster createKubernetesCluster(CreateKubernetesClusterCmd cmd)
11051051
logAndThrow(Level.ERROR, "Kubernetes Service plugin is disabled");
11061052
}
11071053

1054+
// Need this for cloudstack-kubernetes-provider && autoscaler
1055+
String csUrl = ApiServiceConfiguration.ApiServletPath.value();
1056+
if (csUrl == null || csUrl.contains("localhost")) {
1057+
throw new InvalidParameterValueException("Global setting endpointe.url has to be set to the Management Server's API end point");
1058+
}
1059+
11081060
validateKubernetesClusterCreateParameters(cmd);
11091061

11101062
final DataCenter zone = dataCenterDao.findById(cmd.getZoneId());
@@ -1190,14 +1142,18 @@ public boolean startKubernetesCluster(long kubernetesClusterId, boolean onCreate
11901142
if (zone == null) {
11911143
logAndThrow(Level.WARN, String.format("Unable to find zone for Kubernetes cluster ID: %s", kubernetesCluster.getUuid()));
11921144
}
1193-
KubernetesClusterStartWorker startWorker =
1194-
new KubernetesClusterStartWorker(kubernetesCluster, this);
1195-
startWorker = ComponentContext.inject(startWorker);
11961145
if (onCreate) {
11971146
// Start for Kubernetes cluster in 'Created' state
1147+
String[] keys = getServiceUserKeys();
1148+
KubernetesClusterStartWorker startWorker =
1149+
new KubernetesClusterStartWorker(kubernetesCluster, this, keys);
1150+
startWorker = ComponentContext.inject(startWorker);
11981151
return startWorker.startKubernetesClusterOnCreate();
11991152
} else {
12001153
// Start for Kubernetes cluster in 'Stopped' state. Resources are already provisioned, just need to be started
1154+
KubernetesClusterStartWorker startWorker =
1155+
new KubernetesClusterStartWorker(kubernetesCluster, this);
1156+
startWorker = ComponentContext.inject(startWorker);
12011157
return startWorker.startStoppedKubernetesCluster();
12021158
}
12031159
}
@@ -1324,8 +1280,7 @@ public KubernetesClusterConfigResponse getKubernetesClusterConfig(GetKubernetesC
13241280
return response;
13251281
}
13261282

1327-
private String[] createServiceAccount() {
1328-
// TODO : Maybe create a service account kubeadmin with restricted permissions and add the user to that instead
1283+
private String[] getServiceUserKeys() {
13291284
Account caller = CallContext.current().getCallingAccount();
13301285
String username = caller.getAccountName() + "-kubeadmin";
13311286
UserAccount kubeadmin = accountService.getActiveUserAccount(username, caller.getDomainId());
@@ -1352,12 +1307,6 @@ public boolean scaleKubernetesCluster(ScaleKubernetesClusterCmd cmd) throws Clou
13521307
}
13531308
validateKubernetesClusterScaleParameters(cmd);
13541309

1355-
Boolean isAutoscalingEnabled = cmd.isAutoscalingEnabled();
1356-
String[] keys = null;
1357-
if (isAutoscalingEnabled != null && isAutoscalingEnabled) {
1358-
keys = createServiceAccount();
1359-
}
1360-
13611310
KubernetesClusterScaleWorker scaleWorker =
13621311
new KubernetesClusterScaleWorker(kubernetesClusterDao.findById(cmd.getId()),
13631312
serviceOfferingDao.findById(cmd.getServiceOfferingId()),
@@ -1366,7 +1315,6 @@ public boolean scaleKubernetesCluster(ScaleKubernetesClusterCmd cmd) throws Clou
13661315
cmd.isAutoscalingEnabled(),
13671316
cmd.getMinSize(),
13681317
cmd.getMaxSize(),
1369-
keys,
13701318
this);
13711319
scaleWorker = ComponentContext.inject(scaleWorker);
13721320
return scaleWorker.scaleCluster();

plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterVO.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,8 @@ public boolean isAutoscalingEnabled() {
316316
return isAutoscalingEnabled;
317317
}
318318

319-
public void setAutoscalingEnabled(boolean isAutoscalingEnabled) {
320-
this.isAutoscalingEnabled = isAutoscalingEnabled;
319+
public void setAutoscalingEnabled(boolean enabled) {
320+
this.isAutoscalingEnabled = enabled;
321321
}
322322

323323
public Long getMinSize() {

plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterActionWorker.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
import org.apache.cloudstack.api.ApiConstants;
3030
import org.apache.cloudstack.ca.CAManager;
31+
import org.apache.cloudstack.config.ApiServiceConfiguration;
3132
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
3233
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
3334
import org.apache.commons.collections.CollectionUtils;
@@ -70,6 +71,7 @@
7071
import com.cloud.utils.exception.CloudRuntimeException;
7172
import com.cloud.utils.fsm.NoTransitionException;
7273
import com.cloud.utils.fsm.StateMachine2;
74+
import com.cloud.utils.ssh.SshHelper;
7375
import com.cloud.vm.UserVmService;
7476
import com.cloud.vm.dao.UserVmDao;
7577
import com.google.common.base.Strings;
@@ -383,4 +385,37 @@ protected boolean stateTransitTo(long kubernetesClusterId, KubernetesCluster.Eve
383385
return false;
384386
}
385387
}
388+
389+
protected boolean createSecret(String[] keys) {
390+
File pkFile = getManagementServerSshPublicKeyFile();
391+
Pair<String, Integer> publicIpSshPort = getKubernetesClusterServerIpSshPort(null);
392+
publicIpAddress = publicIpSshPort.first();
393+
sshPort = publicIpSshPort.second();
394+
395+
List<KubernetesClusterVmMapVO> clusterVMs = getKubernetesClusterVMMaps();
396+
if (CollectionUtils.isEmpty(clusterVMs)) {
397+
return false;
398+
}
399+
400+
final UserVm userVm = userVmDao.findById(clusterVMs.get(0).getVmId());
401+
402+
String hostName = userVm.getHostName();
403+
if (!Strings.isNullOrEmpty(hostName)) {
404+
hostName = hostName.toLowerCase();
405+
}
406+
407+
try {
408+
Pair<Boolean, String> result = SshHelper.sshExecute(publicIpAddress, sshPort, CLUSTER_NODE_VM_USER,
409+
pkFile, null, String.format("sudo kubectl -n kube-system create secret generic cloudstack-secret " +
410+
"--from-literal=api-url='%s' " +
411+
"--from-literal=api-key='%s' " +
412+
"--from-literal=secret-key='%s'", ApiServiceConfiguration.ApiServletPath.value(), keys[0], keys[1]),
413+
10000, 10000, 60000);
414+
return result.first();
415+
} catch (Exception e) {
416+
String msg = String.format("Failed to add cloudstack-secret to Kubernetes cluster: %s", kubernetesCluster.getName());
417+
LOGGER.warn(msg, e);
418+
}
419+
return true;
420+
}
386421
}

0 commit comments

Comments
 (0)