Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@
package com.morpheusdata.core;


import com.morpheusdata.model.ComputeServer;
import com.morpheusdata.model.ComputeServerGroup;
import com.morpheusdata.model.ComputeTypeLayout;
import com.morpheusdata.request.AddServerGroupServersRequest;
import com.morpheusdata.response.ServiceResponse;
import io.reactivex.rxjava3.core.Single;

import java.util.List;

public interface MorpheusComputeServerGroupService extends MorpheusDataService<ComputeServerGroup, ComputeServerGroup>, MorpheusIdentityService<ComputeServerGroup> {
/**
Expand All @@ -26,4 +33,17 @@ public interface MorpheusComputeServerGroupService extends MorpheusDataService<C
* @return An instance of the Compute Server Group Type Service
*/
MorpheusComputeServerGroupTypeService getType();

/**
* Add one or more servers to an existing cluster. Follows the same flow as the
* {@code POST /api/clusters/:id/servers} REST API endpoint, including license checks,
* policy enforcement, and async provisioning.
*
* @param cluster the target cluster (server group)
* @param layout the ComputeTypeLayout to use for provisioning
* @param request the request object describing the server(s) to add
* @return a {@link ServiceResponse} containing the list of provisioned {@link ComputeServer} objects on success
* @since 1.4.0
*/
Single<ServiceResponse<List<ComputeServer>>> addServerGroupServers(ComputeServerGroup cluster, ComputeTypeLayout layout, AddServerGroupServersRequest request);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@
import com.morpheusdata.core.MorpheusSynchronousDataService;
import com.morpheusdata.core.MorpheusSynchronousIdentityService;

import com.morpheusdata.model.ComputeServer;
import com.morpheusdata.model.ComputeServerGroup;
import com.morpheusdata.model.ComputeTypeLayout;
import com.morpheusdata.request.AddServerGroupServersRequest;
import com.morpheusdata.response.ServiceResponse;

import java.util.List;

public interface MorpheusSynchronousComputeServerGroupService extends MorpheusSynchronousDataService<ComputeServerGroup, ComputeServerGroup>, MorpheusSynchronousIdentityService<ComputeServerGroup> {
/**
Expand All @@ -28,4 +34,17 @@ public interface MorpheusSynchronousComputeServerGroupService extends MorpheusSy
* @return An instance of the Compute Server Group Type Service
*/
MorpheusSynchronousComputeServerGroupTypeService getType();

/**
* Add one or more servers to an existing cluster. Follows the same flow as the
* {@code POST /api/clusters/:id/servers} REST API endpoint, including license checks,
* policy enforcement, and async provisioning.
*
* @param cluster the target cluster (server group)
* @param layout the ComputeTypeLayout to use for provisioning
* @param request the request object describing the server(s) to add
* @return a {@link ServiceResponse} containing the list of provisioned {@link ComputeServer} objects on success
* @since 1.4.0
*/
ServiceResponse<List<ComputeServer>> addServerGroupServers(ComputeServerGroup cluster, ComputeTypeLayout layout, AddServerGroupServersRequest request);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* Copyright 2024 Morpheus Data, LLC.
*
* Licensed under the PLUGIN CORE SOURCE LICENSE (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://raw.githubusercontent.com/gomorpheus/morpheus-plugin-core/v1.0.x/LICENSE
*
* 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 com.morpheusdata.request;

import com.morpheusdata.model.ComputeServerInterface;
import com.morpheusdata.model.ComputeServerType;
import com.morpheusdata.model.ServicePlan;
import com.morpheusdata.model.StorageVolume;

import java.util.List;
import java.util.Map;

/**
* Request object for adding server(s) to an existing cluster via
* {@link com.morpheusdata.core.MorpheusComputeServerGroupService#addServerGroupServers}.
*
* @since 1.4.0
*/
public class AddServerGroupServersRequest {

/**
* The type of server to add to the cluster.
*/
public ComputeServerType serverType;

/**
* Optional display name for the server(s). If not provided, a name will be auto-generated
* based on the cluster name and existing node count.
*/
public String serverName;

/**
* Optional hostname for the server(s). Defaults to {@link #serverName} if not provided.
*/
public String hostname;

/**
* The service plan (sizing) to use for the server(s).
*/
public ServicePlan plan;

/**
* Additional configuration options passed to the provisioner.
* May include provider-specific settings such as {@code resourcePoolId}, {@code customOptions}, etc.
*/
public Map<String, Object> config;

/**
* ID of the cloud to provision into. Defaults to the cluster's cloud if not specified.
*/
public Long zoneId;

/**
* ID of the group/site to provision into. Defaults to the cluster's site if not specified.
*/
public Long siteId;

/**
* Number of nodes to add. Defaults to 1.
*/
public Integer nodeCount = 1;

/**
* Storage volumes to attach to the server(s).
*/
public List<StorageVolume> volumes;

/**
* Network interfaces to configure on the server(s).
*/
public List<ComputeServerInterface> networkInterfaces;

/**
* Security group IDs to apply to the server(s).
*/
public List<Long> securityGroupIds;

/**
* Whether to perform license and connectivity checks before provisioning.
* Set to {@code false} to skip these checks. Defaults to {@code true}.
*/
public boolean licenseCheck = true;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.morpheusdata.request

import com.morpheusdata.model.ComputeServerType
import com.morpheusdata.model.ServicePlan
import com.morpheusdata.model.StorageVolume
import com.morpheusdata.model.ComputeServerInterface
import spock.lang.Specification

class AddServerGroupServersRequestSpec extends Specification {

def "defaults are set correctly"() {
when:
def req = new AddServerGroupServersRequest()

then:
req.nodeCount == 1
req.licenseCheck == true
req.serverType == null
req.serverName == null
req.plan == null
req.volumes == null
req.networkInterfaces == null
req.securityGroupIds == null
}

def "fields can be populated"() {
given:
def serverType = new ComputeServerType(id: 10L, code: 'worker')
def plan = new ServicePlan(id: 5L, name: 'Small')
def vol = new StorageVolume(id: 1L)
def nic = new ComputeServerInterface(id: 1L)

when:
def req = new AddServerGroupServersRequest(
serverType: serverType,
serverName: 'worker-3',
hostname: 'worker-3',
plan: plan,
config: [resourcePoolId: 42L],
zoneId: 100L,
siteId: 1L,
nodeCount: 3,
volumes: [vol],
networkInterfaces: [nic],
securityGroupIds: [200L],
licenseCheck: false
)

then:
req.serverType.code == 'worker'
req.serverName == 'worker-3'
req.plan.id == 5L
req.config.resourcePoolId == 42L
req.zoneId == 100L
req.siteId == 1L
req.nodeCount == 3
req.volumes.size() == 1
req.networkInterfaces.size() == 1
req.securityGroupIds == [200L]
req.licenseCheck == false
}

def "licenseCheck can be explicitly disabled"() {
when:
def req = new AddServerGroupServersRequest(licenseCheck: false)

then:
req.licenseCheck == false
}
}
Loading