Skip to content

Conversation

@dhlaluku
Copy link

@dhlaluku dhlaluku commented May 24, 2018

Description

This a new feature for CloudStack to provide functionality for the admin user to execute network-utility commands (ping, traceroute, arping) directly on the system VMs. The initial scope is for a Root Admin using this tools with VR, SSVM and the CPVM.

FS: https://cwiki.apache.org/confluence/display/CLOUDSTACK/CloudStack+Remote+Diagnostics+API

Types of changes

  • New feature (a non-breaking change which adds functionality)

Checklist:

  • I have read the CONTRIBUTING document.
  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
    Testing
  • I have added tests to cover my changes.
  • All relevant new and existing integration tests have passed.
  • A full integration test suite with all test that can run on my environment has passed.

@dhlaluku dhlaluku requested a review from rohityadavcloud May 24, 2018 14:02
@dhlaluku dhlaluku force-pushed the remoteDiganosisAPI branch from 6f9cb8b to c9d4458 Compare May 31, 2018 10:41
command.setAccessDetail(NetworkElementCommand.ROUTER_IP, routerControlHelper.getRouterControlIp(router.getId()));
command.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());

// String routerAccessIP = command.getRouterAccessIp();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please remove commented code

@@ -0,0 +1,43 @@
/*
* // Licensed to the Apache Software Foundation (ASF) under one
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

double comment ;)

@@ -0,0 +1,29 @@
/*
* // Licensed to the Apache Software Foundation (ASF) under one
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nested comment

@@ -0,0 +1,114 @@
/*
* // Licensed to the Apache Software Foundation (ASF) under one
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nested comment

@@ -0,0 +1,53 @@
/*
* // Licensed to the Apache Software Foundation (ASF) under one
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nest

@@ -0,0 +1,30 @@
/*
* // Licensed to the Apache Software Foundation (ASF) under one
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nest

@@ -0,0 +1,115 @@
/*
* // Licensed to the Apache Software Foundation (ASF) under one
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nest

# specific language governing permissions and limitations
# under the License.

$1 $2 -c 5
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so is this inteded for more than just 'ping'? passing $1 seems like it is intended but it is senseless given the script name 'ping_remotely.sh'

if (origAnswer instanceof ExecuteDiagnosisAnswer) {
answer = (ExecuteDiagnosisAnswer) origAnswer;
} else {
s_logger.warn("Unable to update router " + router.getHostName() + "status");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c&p? I would expect amessage about remote execution

Copy link
Member

@DaanHoogland DaanHoogland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as a user of this feature, ... ;)

//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.ID,
description = "The ID of the System VM instance",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"... to diagnose" ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed

private Long id;

@Parameter(name = ApiConstants.IP_ADDRESS,
description = "Destination IP address to ping",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Destination address IP to test conection to"

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed

description = "The type of command to be executed inside the System VM instance, e.g. ping, tracert or arping",
required = true,
type = CommandType.STRING)
private String type;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how are these validated?

Copy link
Author

@dhlaluku dhlaluku Jun 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using Preconditions with an enum that throws an IllegalArgument exception.

private String type;

@Parameter(name = ApiConstants.PARAMS,
description = "Additional command line options",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a little word on how these are processed/used?

Copy link
Author

@dhlaluku dhlaluku Jun 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The aim of this was to allow a user to specify optional arguments like they normally would when using the command from the terminal.

If a user passes an Illegal argument for a specific command type, then script execution will fail and stderr will be propagated back as API response

authorized = RoleType.Admin)
public class RemoteDiagnosticsCmd extends BaseCmd {

public static final String APINAME = "remoteDiganosis";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remoteDiagnosis is a better name IMNSHO, but it must coincide with the actual API name

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed name to executeDiagnostics following ACS API naming conventions.

@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException,
ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
Preconditions.checkState(RemoteDiagnosticsService.DiagnosisType.contains(getType()), "%s is " +
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as an enum this is not very flexible. consider making it a registry?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Under consideration.

@Param(description = "Script execution result")
private String details;

@SerializedName(ApiConstants.RESULT)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we had discussed return value/exit code instead of success status?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have included the exit code to be returned by the python script.

private Boolean success;

@SerializedName("command")
@Param(description = "Command passed to script")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this description doesn't tell me what I expect to read here. Is it the exact RemoteDiagnosticsCmd.type? or the cmd line as eventually executed remotely, including the standard and extra parameters, or even path?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put this the for debug purposes, I will remove it in the final product. But this is the command line is eventually executed remotely.

E.g. command = ping 8.8.8.8 -c 5

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, that might be usefull for an administrator in more elaborate cases as well

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed this field in the API response.

@EntityReference(value = VirtualMachine.class)
public class RemoteDiagnosticsResponse extends BaseResponse {
@SerializedName(ApiConstants.DETAILS)
@Param(description = "Script execution result")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is stdout on remote, right?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. It represents both stdout and stderr.

Copy link
Member

@DaanHoogland DaanHoogland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

neat code

@@ -0,0 +1,136 @@
/*
* // Licensed to the Apache Software Foundation (ASF) under one
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still nested comment

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed.

@@ -0,0 +1,66 @@
/*
* // Licensed to the Apache Software Foundation (ASF) under one
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nested comment

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed

@@ -0,0 +1,45 @@
/*
* // Licensed to the Apache Software Foundation (ASF) under one
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nested comment

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved

public interface RemoteDiagnosticsService {
RemoteDiagnosticsResponse executeDiagnosisToolInSystemVm(RemoteDiagnosticsCmd cmd) throws AgentUnavailableException, InvalidParameterValueException;

enum DiagnosisType {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to see this as a registry, for instance by means of a comma separated configuration value

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Under consideration


public static boolean contains(String cmd){
try{
valueOf(cmd);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might we go for ignore case?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactored enum


public static final String VR_CFG = "vr_cfg.sh";

// New script for use by remoteDiagnosis API
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these both to be used? or is this part of a transition?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Part of transition, final product will make use of a python based script


import com.cloud.agent.api.Answer;

public class ExecuteDiagnosisAnswer extends Answer {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so this one stuck to the more beautiful name.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed.

@@ -0,0 +1,121 @@
/*
* // Licensed to the Apache Software Foundation (ASF) under one
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nested comment

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed


private static String setupRemoteCommand(String diagnosisType, String destinationIpAddress, String optionalArguments){
if (optionalArguments != null){
return String.format("%s %s", diagnosisType, destinationIpAddress+" "+optionalArguments);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so the optional arguments are always last. for some commands that will exclude options. thought the trend is to allow for any argument on any place in teh command line. This is possible place for augmentation.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am working on refactoring this entire method during migration to python based script. I aim at parsing all arguments passed for each command type.

if (optionalArguments != null){
return String.format("%s %s", diagnosisType, destinationIpAddress+" "+optionalArguments);
}
return String.format("%s %s", diagnosisType, destinationIpAddress);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

second occurence of the same string, extract to a constant? for instance named COMMAND_LINE_TEMPLATE.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@dhlaluku dhlaluku requested review from rohityadavcloud and removed request for rohityadavcloud June 5, 2018 14:35
Copy link
Member

@rohityadavcloud rohityadavcloud left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address outstanding issues, let's syncup to discuss some of the items.

import javax.inject.Inject;

@APICommand(name = RemoteDiagnosticsCmd.APINAME,
since = "4.11",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change since to 4.12.0.0.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed

authorized = {RoleType.Admin})
public class RemoteDiagnosticsCmd extends BaseCmd {
private static final Logger s_logger = Logger.getLogger(RemoteDiagnosticsCmd.class);
public static final String APINAME = "remoteDiganostics";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix typo in APINAME to remoteDiagnostics, or consider above ^^

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amended API command name to executeDiagnostics following CS naming convention.

/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, required = true, entityType = RemoteDiagnosticsResponse.class,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of RemoteDiagnosticsResponse could be misleading, let's discuss this issue over syncup.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be UserVmResponse (sort of a hack, as the annotation leads to all the user/system vms), or perhaps SystemVmResponse. You'll need to check if this works.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UserVmResponse shows guest VM instances only. SystemVmResponse or DomainRouterResponse do not show anything, will revisit and investigate further.

private Long id;

@Parameter(name = ApiConstants.IP_ADDRESS, type = CommandType.STRING, required = true,
description = "Destination IP address to test connection to")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change description to say - IP/address i.e. the address could be an IP or (domain) address.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved

private String address;

@Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, required = true,
description = "The type of diagnostics command to be executed on the System VM instance, e.g. ping, tracert or arping")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the description, instead of giving example, state the current list of comma-separated enums that can be used.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved


from nose.plugins.attrib import attr

class TestRemoteDiagnosticsInSystemVMs(cloudstackTestCase):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll review this next time in detail after rest of the code reviews have been addressed.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ready for review

domainid=cls.account.domainid,
serviceofferingid=cls.service_offering.id
)
cls.cleanup = [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You also want to cleanup the vm that was created.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved

def setUp(self):
self.apiclient = self.testClient.getApiClient()
self.hypervisor = self.testClient.getHypervisorInfo()
return
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to return after end of the method. Remove it from here and rest of the methods.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved

self.hypervisor = self.testClient.getHypervisorInfo()
return

def tearDown(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You probably want to remove self.cleanup. Also add newline after pass. Run your python file via pep8 or pylint etc.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved

'cloudian': 'Cloudian',
'Sioc' : 'Sioc'
'Sioc' : 'Sioc',
'remoteDiganostics': 'Virtual Machine'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename as 'Diagnostics': 'Diagnostics'. When you build cloudstack, go to tools/apidocs/target and open the generated html to see how APIs are grouped in sections.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved

}

@Override
public String getConfigComponentName() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this as well.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved

// under the License.
//


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove extra new line.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved

Mockito.when(vmInstanceDao.findByIdTypes(remoteDiagnosticsCmd.getId(), VirtualMachine.Type.ConsoleProxy,
VirtualMachine.Type.DomainRouter, VirtualMachine.Type.SecondaryStorageVm)).thenReturn(null);
diagnosticsService.executeDiagnosticsToolInSystemVm(remoteDiagnosticsCmd);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mock and check the answer

return cmd

else:
return cmd + " -c 4"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default options for each type/command.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved

@@ -0,0 +1,173 @@
# Licensed to the Apache Software Foundation (ASF) under one
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplify/Rename the file to test_diagnostics.py

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed file.

Copy link
Member

@DaanHoogland DaanHoogland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

biggest comment is the that logging of exceptions is usually done on catching and not before throwing. lot's of comments, nothing lethal, though

public DiagnosticsType getType() {
DiagnosticsType diagnosticsType = DiagnosticsType.getCommand(type);
if (diagnosticsType == null) {
LOGGER.warn("An Invalid diagnostics command type passed: " + type);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need to log this here as you are throwing it and it will be caught and logged elsewhere

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved

public String getOptionalArguments() {
final String EMPTY_STRING = "";

if (optionalArguments == null || optionalArguments.isEmpty()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do this a lot as well, but it's better to use CollectionUtils.isEmpty()

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is not much difference in terms of performance, but adopted since it provides cleaner code

final Pattern pattern = Pattern.compile(regex);
final boolean hasInvalidChar = pattern.matcher(optionalArguments).find();
if (!hasInvalidChar) {
LOGGER.error("An Invalid character has been passed as an optional parameter");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again, you don't need to log what you throw. In this case I would include the offensive parameter for convenience of the operator.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved

response.setStdout(answerMap.get("STDOUT"));
response.setStderr(answerMap.get("STDERR"));
response.setExitCode(answerMap.get("EXITCODE"));
response.setResult(answerMap.get("SUCCESS"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as discussed: considder not returning success but only exitcode.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed success return

response.setStderr(answerMap.get("STDERR"));
response.setExitCode(answerMap.get("EXITCODE"));
response.setResult(answerMap.get("SUCCESS"));
response.setObjectName("diagnostics");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should the name contain some noun or verb indicating that it contains the resiult of a test/diagnostic command-run?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe involve Paul in that discussion

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed it to diagnostics results

import com.cloud.utils.db.TransactionLegacy;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.VirtualMachine.PowerState;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if only the order of imports has changed you better revert this

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

import com.cloud.utils.component.Manager;
import com.cloud.vm.VirtualMachine.PowerState;

import java.util.HashMap;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if only the order of imports has changed you better revert this

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

final VMInstanceVO vmInstance = instanceDao.findByIdTypes(vmId, VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.DomainRouter, VirtualMachine.Type.SecondaryStorageVm);

if (vmInstance == null) {
LOGGER.error("Invalid system vm id provided " + vmId);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

both logging and throwing is not needed, also you would use a single string object to use for both ;)

final Long hostId = vmInstance.getHostId();

if (hostId == null) {
LOGGER.warn("Unable to find host for virtual machine instance: " + vmInstance.getInstanceName());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you throw an exception it is at least an error, not a warning.
you can reuse one string for both
is it really needed to bot log and throw?

throw new CloudRuntimeException("Failed to execute diagnostics command: " + answer.getDetails());
}
} catch (OperationTimedoutException e) {
LOGGER.warn("Timed Out", e);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a warning should be an error that can be handled. throwing and warning seem kind of contradictory

final DiagnosticsCommand command = new DiagnosticsCommand(cmdType, cmdAddress, optionalArguments);
command.setAccessDetail(NetworkElementCommand.ROUTER_NAME, vmInstance.getInstanceName());
command.setAccessDetail(NetworkElementCommand.ROUTER_IP, routerControlHelper.getRouterControlIp(vmInstance.getId()));
//command.setAccessDetail(NetworkElementCommand.ROUTER_IP, routerControlHelper.getRouterControlIp(vmInstance.getId()));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove comment in code please, git can get it back for you!

final DataCenterVO dcVo = dataCenterDao.findById(vmInstanceVO.getDataCenterId());
String controlIP = null;

// if(vmInstanceVO.getHypervisorType() == Hypervisor.HypervisorType.VMware && dcVo.getNetworkType() == DataCenter.NetworkType.Basic ){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please remove this comment. it has no value

final DiagnosticsCommand command = new DiagnosticsCommand(cmdType, cmdAddress, optionalArguments, vmManager.getExecuteInSequence(vmInstance.getHypervisorType()));

if (vmInstance.getType() == VirtualMachine.Type.DomainRouter) {
command.setAccessDetail(NetworkElementCommand.ROUTER_IP, routerControlHelper.getRouterControlIp(vmInstance.getId()));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the if-else block and replace by something like this:
networkManager.getSystemVMAccessDetails(vm). To use network manager, try something like:

    @Inject
    private NetworkOrchestrationService networkManager;

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved, solution implemented and tested on VMware, KVM and Xenserver

command.setAccessDetail(NetworkElementCommand.ROUTER_IP, nicVO.getIPv4Address());
}
command.setAccessDetail(NetworkElementCommand.ROUTER_NAME, vmInstance.getInstanceName());
// if (vmInstance.getType() == VirtualMachine.Type.DomainRouter) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After testing, the commented code can be removed.

Copy link
Member

@rohityadavcloud rohityadavcloud left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes requested.

'cloudian': 'Cloudian',
'Sioc' : 'Sioc'
'Sioc' : 'Sioc',
'Diagnostics': 'Diagnostics'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can put the API under Misc, unless you think more APIs are going to join this section in apidocs.

Copy link
Author

@dhlaluku dhlaluku Jun 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I anticipate the retrieveDiagnostics API to grouped together with the Remote Diagnostics within the same section viz. Diagnostics in the apidocs.

)

# Validate Traceroute command execution with a non-existent/pingable IP address
cmd.ipaddress = '999.9999.9999.9999.9999'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

try to pass a valid but unreachable IPv4 ip see https://stackoverflow.com/questions/10456044/what-is-a-good-invalid-ip-address-to-use-for-unit-tests
Make changes to other related invalid ips you've used. Ideally, each + and - test should be a separate test case.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes made, using IP address 192.0.2.2 for the - test case. Also separated the + and - test cases for the ping command.

return_code = 127

finally:
print('%s}' % stdout.strip())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improve prefix/container for stdout and stderr with something like STDOUT{%value here}, STDERR{%value here}. Don't assume that closing brace } may not be part of stdout or stderr.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change, using && for parsing

Copy link
Author

@dhlaluku dhlaluku Jun 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This leads to this: exitcode = EXITCODE: {0}

Will parse the details as {} without the preceding STDERR/STDOUT/EXITCODE.
The key values are already provided by/in the API response class.

@InjectMocks
private DiagnosticsServiceImpl diagnosticsService = new DiagnosticsServiceImpl();


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove extra newline.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


@Before
public void setUp() throws Exception {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove setUp if you're not doing anything.


@EntityReference(value = VirtualMachine.class)
public class ExecuteDiagnosticsResponse extends BaseResponse {
@SerializedName("STDOUT")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lowercase the api response keys to stdout, stderr, exitcode.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use api constant class for them, perhaps use the same keys in the class where the details map is created.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

try {
final Map<String, String> answerMap = diagnosticsService.runDiagnosticsCommand(this);
if (answerMap != null || !answerMap.isEmpty()) {
response.setStdout(answerMap.get("STDOUT"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change the .get() to get based on a known constant than a hardcoded string like STDOUT, STDERR and EXITCODE.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

final String EMPTY_STRING = "";

if (optionalArguments == null || optionalArguments.isEmpty()) {
return EMPTY_STRING;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Return "" is fine, than declare a variable and return that.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

final String regex = "^[\\w\\-\\s]+$";
final Pattern pattern = Pattern.compile(regex);
final boolean hasInvalidChar = pattern.matcher(optionalArguments).find();
if (!hasInvalidChar) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Write +/- unit tests for this validation method.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

since = "4.12.0.0")
public class ExecuteDiagnosticsCmd extends BaseCmd {
private static final Logger LOGGER = Logger.getLogger(ExecuteDiagnosticsCmd.class);
public static final String APINAME = "executeDiagnostics";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you consider renaming this to runDiagnostics. Ignore if already discussed with Paul and others.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At this point, might be a bit late. It would require redoing and testing a lot of things i.e unit/marvin test cases etc.

Copy link
Member

@rohityadavcloud rohityadavcloud left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address outstanding issues, then close this PR and send this to apache/cloudstack as a community PR.

Copy link
Author

@dhlaluku dhlaluku left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have resolved all the comments

@dhlaluku dhlaluku closed this Jun 22, 2018
shwstppr pushed a commit that referenced this pull request Mar 8, 2024
* NSX integration - skeletal code

* Fix module not loading on startup

* add upgrade path and daos
\n add nsx controller command

* add support for adding and listing nsx provider to a zone

* add license

* add default VPC offering and update upgrade path

* add global setting to enable nsx plugin

* add delete nsx controller operation

* add nsxresource

* add NSX resource , api client, create tier1 gw

* update db

* update response and add license

* Add support to create and delete nsx tier-1 gateway

* add license

* cleanup and add skeletal code for network creation

* add create/delete segment and UI integration

* add license

* address code smells - part 1

* fix test / build failure

* NSX integration - skeletal code

* Fix module not loading on startup

* add upgrade path and daos
\n add nsx controller command

* add support for adding and listing nsx provider to a zone

* add license

* add default VPC offering and update upgrade path

* add global setting to enable nsx plugin

* add delete nsx controller operation

* add nsxresource

* add NSX resource , api client, create tier1 gw

* update db

* update response and add license

* Add support to create and delete nsx tier-1 gateway

* add license

* cleanup and add skeletal code for network creation

* add create/delete segment and UI integration

* add license

* address code smells - part 1

* fix test / build failure

* add ui changes + update nsx_provider table transport zones + use NSX broadcast domain for add nics to router

* ui: fix password field, and backend changes

* add route advertisement

* update offering

* update offering

* add sleep before deletion of vpc / tier g/w for ports to be removed

* move creation of segments to design phase

* change provider to VPC router for Dhcp & dns service in an nsx offering

* Add public nic for NSX

* reserve first IP (after g/w) of subnet for router nic - NSX

* revert reserving 1st IP in vpc segments

* [NSX] Create a DHCP relay and add it to a VPC tier segment (#107)

* Create DHCP relay command and execute request

* In progress integrate with networking

* Create DHCP relay config on the network VR allocation

* Revert domain router dao changes

* Create DHCP relay con VR nic plug to NSX network

* Link DHCP relay config to segment after creation

* [NSX] Cleanup DHCP Relay config on segment deletion (#108)

* Cleanup DHCP Relay config on segment deletion

* update segment & relay name generators and call delete dhcprelay after deletion of segment

* address comment

* [NSX] Fix DHCP relay config deletion was missing zone name (apache#8068)

* [NSX] Refactor API wrapper operations (apache#8059)

* [NSX] Refactor API wrapper operations

* Big refactor

* Address review comment

* change network cidr to cidr to prevent NPE

* add domain and zone names to the various networks - vpc & tier

---------

Co-authored-by: Pearl Dsilva <[email protected]>

* Nsx unit tests (apache#8090)

* Add tests

* add test for NsxGuestNetworkGuru

* add unit tests for NsxResource

* add unti tests for NsxElement

* cleanup

* [NSX] Refactor API wrapper operations

* update tests

* update tests - add nsxProviderServiceImpl test

* add unit test - NsxServiceImpl

* add license

* Big refactor

* Address review comment

* change network cidr to cidr to prevent NPE

* add domain and zone names to the various networks - vpc & tier

* fix tests

---------

Co-authored-by: nvazquez <[email protected]>

* modify NSX resource naming convention (apache#8095)

* modify NSX resource naming convention

* remove unused imports

* add a setup phase between desgin and implementation of a network for intermediary steps

* add method to all classes

* NSX: Refactor Network & VPC offering (apache#8110)

* [NSX] Refactor API wrapper operations

* Network offering changes for NSX

* fix services and provider combination

* address comments: rename param

* update nsx_mode parameter

---------

Co-authored-by: nvazquez <[email protected]>

* fix test

* [NSX] Allow NSX isolated networks (apache#8132)

* Add network offerings for NSX on isolated networks

* Fix offerings creation

* In progress NSX isolated network

* Fixes

* Fix NIC allocation to router

* NSX: Add Step for Adding Public traffic network for NSX During zone creation (apache#8126)

* NSX: Add Step for Adding Public traffic network for NSX

* address comments and cleanup

* address comment

* remove indent

* NSX: Create and Delete static NAT & Port forward  rules (apache#8131)

* NSX: Create and delete NSX Static Nat rules

* fix issues with static nat

* add static nat

* Support to add and delete Port forward rules

* add license

* fix adding multiple pf rules

* cleanup

* fix lint check

* fix smoke tests

* fix smoke tests

* Nsx add lb rule (apache#8161)

* NSX: Create and delete NSX Static Nat rules

* fix issues with static nat

* add static nat

* Support to add and delete Port forward rules

* add license

* fix adding multiple pf rules

* cleanup

* NSX: Add support to create and delete Load balancer rules

* fix deletion of lb rules

* add header file and update protocol detail

* build failure fix

* [NSX] Add SNAT support (apache#8100)

* In progress add source NAT

* Fix after merge

* Fix tests

* Fix NPE on isolated network deletion

* Reserve source NAT IP when its not passed for NSX VPC

* Create source NAT rule on VR NIC allocation

* Fix update VPC and remove VPC to update and remove SNAT rule

* Fix packaging

* Address review comment

* Fix build

* fix build - unused import

* Add defensive checks

* Add missing design to NSX public guru

---------

Co-authored-by: Pearl Dsilva <[email protected]>

* NSX: Fix VR public NIC allocation (apache#8166)

* NSX: fix LB member addition and deletion and add defensive checks (apache#8167)

* Fix public NIC NPE on broadcast URI

* NSX: Router Public nic to get IP from systemVM Ip range (apache#8172)

* NSX: Router Public nic to get IP from systemVM Ip range

* Fix VR IP address and setSourceNatIp command

* NSX: hide systemVM reserved IP range SourceNAT

* fix test

---------

Co-authored-by: nvazquez <[email protected]>

* fix test failure

* test failure fix

* [NSX] Fix update source NAT IP (apache#8176)

* [NSX] Fix update source NAT IP

* Fix startup

* Fix API result

* NSX - add LB route Advertizement (apache#8192)

* [NSX] Add ACL types support (apache#8224)

* NSX: Create segment group on segment creation

* Add unit tests

* Remove group for segment before removing segment

* Create Distributed Firewall rules

* Remove distributed firewall policy on segment deletion

* Fix policy rule ID and add more unit tests

* Fix DROP action rules and transform tests

* Add new ACL rules

* Fixes

* associate security policies with groups and not to DFW and add deletion of rules

* Fix name convention

---------

Co-authored-by: Pearl Dsilva <[email protected]>

* NSX: Fix creation of VPCs (apache#8320)

* Fix ACL rules creation (apache#8323)

* [NSX] Fix database views (apache#8325)

* NSX: Add CKS Support & Firewall rules for Isolated Networks (apache#8189)

* NSX: Add ALL LB IP to the list of route advertisements in tier1

* NSX: Support Source NAT on NSX Isolated networks

* NSX: Cks Support

* NSX: Create segment group on segment creation

* Add unit tests

* Remove group for segment before removing segment

* Create Distributed Firewall rules

* Remove distributed firewall policy on segment deletion

* Fix policy rule ID and add more unit tests

* Add support for routed NSX Isolated networks \n and non RFC 1918 compliant IPs

* Add support for routed NSX Isolated networks \n and non RFC 1918 compliant IPs

* Add Firewall rules

* build failure - fix unit test

* fix npes

* Add support to delete firewall rules

* update nsx cks offering

* add license

* update order of ports in PF & FW rules

* fix filter for getting transport zones

* CKS support changed - MTU updated, etc

* add LB for CKS on VPC

* address comments

* adapt upstream cks logic for vpc

* rever mtu hack

* update UI changes as per upstream fix

* change display test for CKS n/w offerings for isolated and VPC tiers

* add extra line for linter

* address comment

* revert list change

---------

Co-authored-by: nvazquez <[email protected]>

* fix ui build failure

* [NSX] Address SonarCloud Bugs (apache#8341)

* [NSX] Address SonarCloud Bugs

* Fix NSX API connection issues

* NSX: Add unit tests to increase coverage (apache#8355)

* NSX: Add unit tests

* cleanup unused imports

* add more unit tests

* add tests for publicnsxnetworkguru

* add license

* fix build failures

* address sonar comment

* fix security hotspots

* NSX: Add more unit tests (apache#8381)

* NSX : Unit tests

* remove unused imports

* remove unused import causing build failure

* fix build failures due to unused imports

* fix build failure

* fix test assertion

* remove unused imports

* remove unused import

* Nsx UI zone bug (apache#8398)

* NSX: Attempt to fix NSX Zone creation bug for public networks

* fix zone wizard public traffic issue

* add proper filtering of offerings based on VPC nsx mode

* clean up console logs

* NSX: Fix code smells and reported bugs (apache#8409)

* NSX: Fix code smells and reported bugs

* fox override issue

* remove unused imports

* fix test

* refactor code to reduce complexity

* add lisence

* cleanup

* fix build failure

* fix build failure

* address comments

* test - add config to ignore certain files from test coverage

* test exclusion of classes from test cov

* rever pom changes

* [NSX] Add more unit tests (apache#8431)

* [NSX] Add more unit tests

* More tests

* Fix build errors

* NSX: Prevent creation of L2 and Shared networks for NSX (apache#8463)

* NSX: Prevent creation of L2 and Shared networks for NSX

* add checks to backend to prevent creation of l2 and shared networks in nsx zones and filter only nsx offerings when creating isolated networks

* cleanup

* NSX: Fix code smells (apache#8436)

* NSX: Fix code smells

* Add changes to service creation logic

* CKS: Add action to during firewall rule creation (apache#8498)

* NSX,UI: Deduplicate network list when creating kubernetes clusters (apache#8513)

* NSX: Make LB service selectable in network offering (apache#8512)

* NSX: Make LB service selectable in network offering

* fix label

* address comments

* address comments

* NSX: Add appropriate error message when icmp type is set to -1 for NSX (apache#8504)

* NSX: Add appropriate error message when icmp type is set to -1 for NSX

* address comments

* update text

* fix test

* fix test - build failure

* fix test - build failure

* NSX: Cleanup NSX resources during k8s cluster cleanup (apache#8528)

* fix test failure

* NSX: Improve segment deletion process (apache#8538)

* NSX: Add passive monitor for NSX LB to test whether a server is available (apache#8533)

* NSX: Add passive monitor for NSX LB to test whether a server is available

* Add active monitors too

* fix build failure

* NSX: Add check for ICMP code / type for NSX zones (apache#8542)

* NSX: Fix Routed Mode for Isolated and VPC networks (apache#8534)

* NSX: Fix Routed Mode for Isolated and VPC networks

* NSX: Fix Routed mode - add checks for ports added for FW rules

* clean up code

* fix build failure

* NSX: Add retry logic with sleep to delete segments (apache#8554)

* NSX: Add retry logic with sleep to delete segments

* add logs

* NSX: Fix custom ACL check (#2)

* NSX: Fix custom ACL check

* NSX: Fix custom ACL check

* Nsx vpc routed mode (#5)

* NSX: Fix VPC routed mode

* NSX: VPC route mode

* remove unnecessary changes

* Nsx: Support internal LB (#4)

* NSX: Support internal LB service in NSX

* add lb removal logic

* Fix UI issue hiding internal LB tab

* Refactor method name

---------

Co-authored-by: nvazquez <[email protected]>

* NSX: Improve NSX resource cleanup process (#3)

* Fix unit test

* NSX: Add SourceNAT service to the default Routed offering for VPC (#13)

* Fix VPC restart with cleanup (#12)

* NSX: Fix ACL rule removal on replacement and fix rule order (#11)

* NSX: fix smoke test failure for ACLs (#9)

* Fix unit tests

* Fix NSX plugin pom XML

* NSX: Add support to re-order ACL rules (NSX FW rules) (#14)

* [WIP] NSX: Add support to re-order ACL rules (NSX FW rules)

* fix reordering of acl rules on all networks that it is associated to

* clean up and attempt test fix

* Fix tests

* Remove unused import

* tweak reorder logic

---------

Co-authored-by: nvazquez <[email protected]>

* Fix zone creation issue for internal load balancer

* Fix

* Fix unit test

* fix logger

* fix logger

* fix logger

* NSX: Fix VPC form to ignore source NAT IP when creating VPCs and fix label

* Move SQL changes to the newest schema file

* NSX: Last Fixes

* Fix build

---------

Co-authored-by: nvazquez <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants