Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jenkins plugin instance type search #27

Merged
merged 14 commits into from
Dec 29, 2022
Merged
Show file tree
Hide file tree
Changes from 4 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
146 changes: 116 additions & 30 deletions src/main/java/hudson/plugins/spotinst/cloud/SpotinstInstanceWeight.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package hudson.plugins.spotinst.cloud;

import hudson.Extension;
import hudson.model.AutoCompletionCandidates;
import hudson.model.Describable;
import hudson.model.Descriptor;
import hudson.plugins.spotinst.common.AwsInstanceTypeEnum;
import hudson.plugins.spotinst.common.AwsInstanceTypeSearchMethodEnum;
import hudson.plugins.spotinst.common.SpotAwsInstanceTypesHelper;
import hudson.plugins.spotinst.common.SpotinstContext;
import hudson.plugins.spotinst.model.aws.AwsInstanceType;
Expand All @@ -12,8 +14,10 @@
import jenkins.model.Jenkins;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;
import org.kohsuke.stapler.QueryParameter;

import java.util.List;
import java.util.stream.Stream;

import static hudson.plugins.spotinst.api.SpotinstApi.validateToken;

Expand All @@ -23,9 +27,11 @@
public class SpotinstInstanceWeight implements Describable<SpotinstInstanceWeight> {
//region Members
private Integer executors;
private String awsInstanceTypeFromAPI;
private String awsInstanceTypeFromAPISelect;
private String awsInstanceTypeFromAPISearch;
private AwsInstanceTypeSearchMethodEnum searchMethod;
zivmessing marked this conversation as resolved.
Show resolved Hide resolved
//Deprecated
private AwsInstanceTypeEnum awsInstanceType;
private AwsInstanceTypeEnum awsInstanceType;
//endregion

//region Constructors
Expand All @@ -49,6 +55,58 @@ public Descriptor<SpotinstInstanceWeight> getDescriptor() {
}
//endregion

//region Methods
public String getAwsInstanceTypeFromAPI() {
String type = null;
AwsInstanceTypeSearchMethodEnum searchMethod = getSearchMethod();
switch(searchMethod){
case SEARCH:
type = getAwsInstanceTypeFromAPISearch();
break;
case SELECT:
sitay93 marked this conversation as resolved.
Show resolved Hide resolved
default:
type = getAwsInstanceTypeFromAPISelect();
break;
}
return type;
}
//endregion

//region Private Methods
private String getAwsInstanceType(String awsInstanceTypeFromAPI){
String retVal = null;

if (awsInstanceTypeFromAPI != null) {

/*
If the user Previously chosen was a type that not exist in the hard coded list
and did not configure the token right, we will present the chosen type and set the default vCPU to 1
The descriptor of this class will show a warning message will note the user that something is wrong,
and point to authentication fix before saving this configuration.
*/
List<AwsInstanceType> types = SpotAwsInstanceTypesHelper.getAllInstanceTypes();
boolean isTypeInList = types.stream().anyMatch(i -> i.getInstanceType().equals(awsInstanceTypeFromAPI));

if (isTypeInList == false) {
AwsInstanceType instanceType = new AwsInstanceType();
instanceType.setInstanceType(awsInstanceTypeFromAPI);
instanceType.setvCPU(1);
SpotinstContext.getInstance().getAwsInstanceTypes().add(instanceType);
}

retVal = awsInstanceTypeFromAPI;

}
else {
if(awsInstanceType != null){
retVal = awsInstanceType.getValue();
}
}

return retVal;
}
//endregion

//region Classes
@Extension
public static final class DescriptorImpl extends Descriptor<SpotinstInstanceWeight> {
Expand All @@ -58,7 +116,7 @@ public String getDisplayName() {
return "Spot Instance Weight";
}

public ListBoxModel doFillAwsInstanceTypeFromAPIItems() {
public ListBoxModel doFillAwsInstanceTypeFromAPISelectItems() {
ListBoxModel retVal = new ListBoxModel();
List<AwsInstanceType> allInstanceTypes = SpotAwsInstanceTypesHelper.getAllInstanceTypes();

Expand All @@ -71,13 +129,41 @@ public ListBoxModel doFillAwsInstanceTypeFromAPIItems() {
return retVal;
}

public FormValidation doCheckAwsInstanceTypeFromAPI() {
public AutoCompletionCandidates doAutoCompleteAwsInstanceTypeFromAPISearch(@QueryParameter String value) {
AutoCompletionCandidates retVal = new AutoCompletionCandidates();
List<AwsInstanceType> allAwsInstanceTypes = SpotAwsInstanceTypesHelper.getAllInstanceTypes();
zivmessing marked this conversation as resolved.
Show resolved Hide resolved
Stream<String> allTypes = allAwsInstanceTypes.stream()
.map(awsInstanceType -> awsInstanceType.getInstanceType().toLowerCase());
String filterValue = value.toLowerCase();
Object[] matchingTypes = allTypes.filter(type -> type.startsWith(filterValue)).toArray();

for (Object objectType: matchingTypes) {
sitay93 marked this conversation as resolved.
Show resolved Hide resolved
String stringType = objectType.toString();
retVal.add(stringType);
}

return retVal;
}

public FormValidation doCheckAwsInstanceTypeFromAPISelect() {
FormValidation retVal = doCheckAwsInstanceTypeFromAPI();

return retVal;
}

public FormValidation doCheckAwsInstanceTypeFromAPISearch() {
FormValidation retVal = doCheckAwsInstanceTypeFromAPI();

return retVal;
}

private FormValidation doCheckAwsInstanceTypeFromAPI() {
FormValidation retVal = null;

String accountId = SpotinstContext.getInstance().getAccountId();
String token = SpotinstContext.getInstance().getSpotinstToken();
int isValid = validateToken(token, accountId);
Boolean isInstanceTypesListUpdate = SpotAwsInstanceTypesHelper.isInstanceTypesListUpdate();
boolean isInstanceTypesListUpdate = SpotAwsInstanceTypesHelper.isInstanceTypesListUpdate();

if (isValid != 0 || isInstanceTypesListUpdate == false) {
retVal = FormValidation.error(
Expand All @@ -100,41 +186,41 @@ public AwsInstanceTypeEnum getAwsInstanceType() {
}

@DataBoundSetter
public void setAwsInstanceTypeFromAPI(String awsInstanceTypeFromAPI) {
this.awsInstanceTypeFromAPI = awsInstanceTypeFromAPI;
public void setAwsInstanceTypeFromAPISelect(String awsInstanceTypeFromAPISelect) {
this.awsInstanceTypeFromAPISelect = awsInstanceTypeFromAPISelect;
}

public String getAwsInstanceTypeFromAPI() {
String retVal = null;
public String getAwsInstanceTypeFromAPISelect() {
String retVal = getAwsInstanceType(this.awsInstanceTypeFromAPISelect);
return retVal;
}

if (this.awsInstanceTypeFromAPI != null) {
public String getAwsInstanceTypeFromAPISearch() {
String retVal = getAwsInstanceType(this.awsInstanceTypeFromAPISearch);
return retVal;
}

/*
If the user Previously chosen was a type that not exist in the hard coded list
and did not configure the token right, we will present the chosen type and set the default vCPU to 1
The descriptor of this class will show a warning message will note the user that something is wrong,
and point to authentication fix before saving this configuration.
*/
List<AwsInstanceType> types = SpotAwsInstanceTypesHelper.getAllInstanceTypes();
boolean isTypeInList = types.stream().anyMatch(i -> i.getInstanceType().equals(this.awsInstanceTypeFromAPI));
@DataBoundSetter
public void setAwsInstanceTypeFromAPISearch(String awsInstanceTypeFromAPISearch) {
this.awsInstanceTypeFromAPISearch = awsInstanceTypeFromAPISearch;
}

if (isTypeInList == false) {
AwsInstanceType instanceType = new AwsInstanceType();
instanceType.setInstanceType(awsInstanceTypeFromAPI);
instanceType.setvCPU(1);
SpotinstContext.getInstance().getAwsInstanceTypes().add(instanceType);
}
public AwsInstanceTypeSearchMethodEnum getSearchMethod() {

retVal = awsInstanceTypeFromAPI;
if(searchMethod == null){
return AwsInstanceTypeSearchMethodEnum.SELECT;
}
return searchMethod;
}
@DataBoundSetter
public void setSearchMethod(AwsInstanceTypeSearchMethodEnum searchMethod) {

if(searchMethod == null){
this.searchMethod = AwsInstanceTypeSearchMethodEnum.SELECT;
}
else {
if(awsInstanceType != null){
retVal = awsInstanceType.getValue();
}
this.searchMethod = searchMethod;
}

return retVal;
}
//endregion
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package hudson.plugins.spotinst.common;

public enum AwsInstanceTypeSearchMethodEnum {
sitay93 marked this conversation as resolved.
Show resolved Hide resolved
SELECT("SELECT"),
sitay93 marked this conversation as resolved.
Show resolved Hide resolved
SEARCH("SEARCH");

private final String name;

AwsInstanceTypeSearchMethodEnum(String name) {
this.name = name;
}

public String getName() {
return name;
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form" xmlns:st="jelly:stapler">
<f:entry field="awsInstanceTypeFromAPI" title="${%Instance type}">
<f:select/>
</f:entry>
<f:radioBlock checked="${instance == null || instance.searchMethod == null || instance.searchMethod == 'SELECT'}" name="searchMethod" title="Choose Instance Type" value="SELECT" inline="true">
<f:entry field="awsInstanceTypeFromAPISelect" title="${%Instance type}">
<f:select/>
</f:entry>
</f:radioBlock>

<f:radioBlock checked="${instance.searchMethod == 'SEARCH'}" name="searchMethod" title="Search Instance Type" value="SEARCH" inline="true">
<f:entry field="awsInstanceTypeFromAPISearch" title="${%Instance type}">
<f:textbox/>
</f:entry>
</f:radioBlock>

<f:entry title="${%# of executors}" field="executors">
<f:number/>
Expand Down