Skip to content

Commit 6366a06

Browse files
committed
Implicit host tags
1 parent f50ab59 commit 6366a06

File tree

18 files changed

+293
-20
lines changed

18 files changed

+293
-20
lines changed

agent/conf/agent.properties

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,3 +430,6 @@ iscsi.session.cleanup.enabled=false
430430
# If set to "true", the agent will register for libvirt domain events, allowing for immediate updates on crashed or
431431
# unexpectedly stopped. Experimental, requires agent restart.
432432
# libvirt.events.enabled=false
433+
434+
# Implicit host tags managed by agent.properties
435+
# host.tags=

agent/src/main/java/com/cloud/agent/properties/AgentProperties.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,13 @@ public Property<Integer> getWorkers() {
803803
*/
804804
public static final Property<String> KEYSTORE_PASSPHRASE = new Property<>(KeyStoreUtils.KS_PASSPHRASE_PROPERTY, null, String.class);
805805

806+
/**
807+
* Implicit host tags
808+
* Data type: String.<br>
809+
* Default value: <code>null</code>
810+
*/
811+
public static final Property<String> HOST_TAGS = new Property<>("host.tags", null, String.class);
812+
806813
public static class Property <T>{
807814
private String name;
808815
private T defaultValue;

api/src/main/java/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ public class ApiConstants {
263263
public static final String IS_EDGE = "isedge";
264264
public static final String IS_EXTRACTABLE = "isextractable";
265265
public static final String IS_FEATURED = "isfeatured";
266+
public static final String IS_IMPLICIT = "isimplicit";
266267
public static final String IS_PORTABLE = "isportable";
267268
public static final String IS_PUBLIC = "ispublic";
268269
public static final String IS_PERSISTENT = "ispersistent";

api/src/main/java/org/apache/cloudstack/api/response/HostForMigrationResponse.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,9 +205,13 @@ public class HostForMigrationResponse extends BaseResponse {
205205
private String events;
206206

207207
@SerializedName("hosttags")
208-
@Param(description = "comma-separated list of tags for the host")
208+
@Param(description = "comma-separated list of explicit host tags for the host")
209209
private String hostTags;
210210

211+
@SerializedName("implicithosttags")
212+
@Param(description = "comma-separated list of implicit host tags for the host", since = "4.20.0")
213+
private String implicitHostTags;
214+
211215
@SerializedName("hasenoughcapacity")
212216
@Param(description = "true if this host has enough CPU and RAM capacity to migrate a VM to it, false otherwise")
213217
private Boolean hasEnoughCapacity;
@@ -414,6 +418,10 @@ public void setHostTags(String hostTags) {
414418
this.hostTags = hostTags;
415419
}
416420

421+
public void setImplicitHostTags(String implicitHostTags) {
422+
this.implicitHostTags = implicitHostTags;
423+
}
424+
417425
public void setHasEnoughCapacity(Boolean hasEnoughCapacity) {
418426
this.hasEnoughCapacity = hasEnoughCapacity;
419427
}

api/src/main/java/org/apache/cloudstack/api/response/HostResponse.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,9 +218,13 @@ public class HostResponse extends BaseResponseWithAnnotations {
218218
private String events;
219219

220220
@SerializedName("hosttags")
221-
@Param(description = "comma-separated list of tags for the host")
221+
@Param(description = "comma-separated list of explicit host tags for the host")
222222
private String hostTags;
223223

224+
@SerializedName("implicithosttags")
225+
@Param(description = "comma-separated list of implicit host tags for the host", since = "4.20.0")
226+
private String implicitHostTags;
227+
224228
@SerializedName(ApiConstants.IS_TAG_A_RULE)
225229
@Param(description = ApiConstants.PARAMETER_DESCRIPTION_IS_TAG_A_RULE)
226230
private Boolean isTagARule;
@@ -458,6 +462,14 @@ public void setHostTags(String hostTags) {
458462
this.hostTags = hostTags;
459463
}
460464

465+
public String getImplicitHostTags() {
466+
return implicitHostTags;
467+
}
468+
469+
public void setImplicitHostTags(String implicitHostTags) {
470+
this.implicitHostTags = implicitHostTags;
471+
}
472+
461473
public void setHasEnoughCapacity(Boolean hasEnoughCapacity) {
462474
this.hasEnoughCapacity = hasEnoughCapacity;
463475
}

api/src/main/java/org/apache/cloudstack/api/response/HostTagResponse.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.google.gson.annotations.SerializedName;
2020
import com.cloud.serializer.Param;
2121

22+
import org.apache.cloudstack.api.ApiConstants;
2223
import org.apache.cloudstack.api.BaseResponse;
2324

2425
public class HostTagResponse extends BaseResponse {
@@ -34,6 +35,10 @@ public class HostTagResponse extends BaseResponse {
3435
@Param(description = "the name of the host tag")
3536
private String name;
3637

38+
@SerializedName(ApiConstants.IS_IMPLICIT)
39+
@Param(description = "true if the host tag is implicit")
40+
private boolean isImplicit;
41+
3742
public String getId() {
3843
return id;
3944
}
@@ -57,4 +62,12 @@ public String getName() {
5762
public void setName(String name) {
5863
this.name = name;
5964
}
65+
66+
public boolean isImplicit() {
67+
return isImplicit;
68+
}
69+
70+
public void setImplicit(boolean implicit) {
71+
isImplicit = implicit;
72+
}
6073
}

engine/schema/src/main/java/com/cloud/host/HostTagVO.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ public class HostTagVO implements InternalIdentity {
4040
@Column(name = "tag")
4141
private String tag;
4242

43+
@Column(name = "is_implicit")
44+
private boolean isImplicit = false;
45+
4346
@Column(name = "is_tag_a_rule")
4447
private boolean isTagARule;
4548

@@ -74,6 +77,13 @@ public boolean getIsTagARule() {
7477
return isTagARule;
7578
}
7679

80+
public void setIsImplicit(boolean isImplicit) {
81+
this.isImplicit = isImplicit;
82+
}
83+
84+
public boolean getIsImplicit() {
85+
return isImplicit;
86+
}
7787

7888
@Override
7989
public long getId() {

engine/schema/src/main/java/com/cloud/host/dao/HostTagsDao.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ public interface HostTagsDao extends GenericDao<HostTagVO, Long> {
3636

3737
void deleteTags(long hostId);
3838

39+
boolean updateImplicitTags(long hostId, List<String> hostTags);
40+
41+
List<HostTagVO> getExplicitHostTags(long hostId);
42+
3943
List<HostTagVO> findHostRuleTags();
4044

4145
HostTagResponse newHostTagResponse(HostTagVO hostTag);

engine/schema/src/main/java/com/cloud/host/dao/HostTagsDaoImpl.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.apache.cloudstack.framework.config.ConfigKey;
2424
import org.apache.cloudstack.framework.config.Configurable;
2525
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
26+
import org.apache.commons.lang3.StringUtils;
2627
import org.springframework.stereotype.Component;
2728

2829
import com.cloud.host.HostTagVO;
@@ -41,13 +42,15 @@ public class HostTagsDaoImpl extends GenericDaoBase<HostTagVO, Long> implements
4142
protected final GenericSearchBuilder<HostTagVO, String> DistinctImplictTagsSearch;
4243
private final SearchBuilder<HostTagVO> stSearch;
4344
private final SearchBuilder<HostTagVO> stIdSearch;
45+
private final SearchBuilder<HostTagVO> ImplicitTagsSearch;
4446

4547
@Inject
4648
private ConfigurationDao _configDao;
4749

4850
public HostTagsDaoImpl() {
4951
HostSearch = createSearchBuilder();
5052
HostSearch.and("hostId", HostSearch.entity().getHostId(), SearchCriteria.Op.EQ);
53+
HostSearch.and("isImplicit", HostSearch.entity().getIsImplicit(), SearchCriteria.Op.EQ);
5154
HostSearch.and("isTagARule", HostSearch.entity().getIsTagARule(), SearchCriteria.Op.EQ);
5255
HostSearch.done();
5356

@@ -64,6 +67,11 @@ public HostTagsDaoImpl() {
6467
stIdSearch = createSearchBuilder();
6568
stIdSearch.and("id", stIdSearch.entity().getId(), SearchCriteria.Op.EQ);
6669
stIdSearch.done();
70+
71+
ImplicitTagsSearch = createSearchBuilder();
72+
ImplicitTagsSearch.and("hostId", ImplicitTagsSearch.entity().getHostId(), SearchCriteria.Op.EQ);
73+
ImplicitTagsSearch.and("isImplicit", ImplicitTagsSearch.entity().getIsImplicit(), SearchCriteria.Op.EQ);
74+
ImplicitTagsSearch.done();
6775
}
6876

6977
@Override
@@ -92,6 +100,36 @@ public void deleteTags(long hostId) {
92100
txn.commit();
93101
}
94102

103+
@Override
104+
public boolean updateImplicitTags(long hostId, List<String> hostTags) {
105+
TransactionLegacy txn = TransactionLegacy.currentTxn();
106+
txn.start();
107+
SearchCriteria<HostTagVO> sc = ImplicitTagsSearch.create();
108+
sc.setParameters("hostId", hostId);
109+
sc.setParameters("isImplicit", true);
110+
boolean expunged = expunge(sc) > 0;
111+
boolean persisted = false;
112+
for (String tag : hostTags) {
113+
if (StringUtils.isNotBlank(tag)) {
114+
HostTagVO vo = new HostTagVO(hostId, tag.trim());
115+
vo.setIsImplicit(true);
116+
persist(vo);
117+
persisted = true;
118+
}
119+
}
120+
txn.commit();
121+
return expunged || persisted;
122+
}
123+
124+
@Override
125+
public List<HostTagVO> getExplicitHostTags(long hostId) {
126+
SearchCriteria<HostTagVO> sc = ImplicitTagsSearch.create();
127+
sc.setParameters("hostId", hostId);
128+
sc.setParameters("isImplicit", false);
129+
130+
return search(sc, null);
131+
}
132+
95133
@Override
96134
public List<HostTagVO> findHostRuleTags() {
97135
SearchCriteria<HostTagVO> sc = HostSearch.create();
@@ -107,6 +145,7 @@ public void persist(long hostId, List<String> hostTags, Boolean isTagARule) {
107145
txn.start();
108146
SearchCriteria<HostTagVO> sc = HostSearch.create();
109147
sc.setParameters("hostId", hostId);
148+
sc.setParameters("isImplicit", false);
110149
expunge(sc);
111150

112151
for (String tag : hostTags) {
@@ -135,6 +174,7 @@ public HostTagResponse newHostTagResponse(HostTagVO tag) {
135174

136175
tagResponse.setName(tag.getTag());
137176
tagResponse.setHostId(tag.getHostId());
177+
tagResponse.setImplicit(tag.getIsImplicit());
138178

139179
tagResponse.setObjectName("hosttag");
140180

engine/schema/src/main/resources/META-INF/db/schema-41900to42000.sql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,6 @@ CREATE TABLE IF NOT EXISTS `cloud_usage`.`quota_email_configuration`(
7979
PRIMARY KEY (`account_id`, `email_template_id`),
8080
CONSTRAINT `FK_quota_email_configuration_account_id` FOREIGN KEY (`account_id`) REFERENCES `cloud_usage`.`quota_account`(`account_id`),
8181
CONSTRAINT `FK_quota_email_configuration_email_template_id` FOREIGN KEY (`email_template_id`) REFERENCES `cloud_usage`.`quota_email_templates`(`id`));
82+
83+
-- Add `is_implicit` column to `host_tags` table
84+
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.host_tags', 'is_implicit', 'int(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT "If host tag is implicit or explicit" ');

0 commit comments

Comments
 (0)