diff --git a/build/pom.xml b/build/pom.xml
index 0ad16da49c57950659a386b3f8da600b0cd89328..b4fac6c222df2667142a4962efa3c5dac00096b9 100755
--- a/build/pom.xml
+++ b/build/pom.xml
@@ -502,6 +502,11 @@
sdnController
${project.version}
+
+ org.zstack
+ sugonSdnController
+ ${project.version}
+
org.zstack
iam2-script-plugin
diff --git a/header/src/main/java/org/zstack/header/identity/BeforeDeleteAccountExtensionPoint.java b/header/src/main/java/org/zstack/header/identity/BeforeDeleteAccountExtensionPoint.java
index 50b68eb89a4c9245dcd50b4baecd164ac4b28b85..c349978495c735cc60dde85968f105e5a04d46f1 100644
--- a/header/src/main/java/org/zstack/header/identity/BeforeDeleteAccountExtensionPoint.java
+++ b/header/src/main/java/org/zstack/header/identity/BeforeDeleteAccountExtensionPoint.java
@@ -6,5 +6,5 @@ package org.zstack.header.identity;
* @time: 2022/10/9
*/
public interface BeforeDeleteAccountExtensionPoint {
- void beforeDeleteAccount(AccountInventory account);
+ void beforeDeleteAccount(AccountInventory account, AccountVO accountBase);
}
diff --git a/header/src/main/java/org/zstack/header/identity/BeforeUpdateAccountExtensionPoint.java b/header/src/main/java/org/zstack/header/identity/BeforeUpdateAccountExtensionPoint.java
index 285eb860a4f3f30ca0df7ee5c7fc86c69084ad41..bcf3e93110a10f3cc65a71ff100e0f8e21ab7ed6 100644
--- a/header/src/main/java/org/zstack/header/identity/BeforeUpdateAccountExtensionPoint.java
+++ b/header/src/main/java/org/zstack/header/identity/BeforeUpdateAccountExtensionPoint.java
@@ -6,5 +6,5 @@ package org.zstack.header.identity;
* @time: 2022/10/9
*/
public interface BeforeUpdateAccountExtensionPoint {
- void beforeUpdateAccount(AccountInventory account);
+ void beforeUpdateAccount(AccountInventory account, AccountVO accountBase);
}
diff --git a/identity/src/main/java/org/zstack/identity/AccountBase.java b/identity/src/main/java/org/zstack/identity/AccountBase.java
index 8411958ae925b777182eaade0415101455a46abb..6efd37bc9112ce89f26500e042549d6cfa5862bc 100755
--- a/identity/src/main/java/org/zstack/identity/AccountBase.java
+++ b/identity/src/main/java/org/zstack/identity/AccountBase.java
@@ -1,6 +1,7 @@
package org.zstack.identity;
import org.hibernate.exception.ConstraintViolationException;
+import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
@@ -82,7 +83,8 @@ public class AccountBase extends AbstractAccount {
private void handle(APIUpdateAccountMsg msg) {
AccountVO account = dbf.findByUuid(msg.getUuid(), AccountVO.class);
-
+ final AccountVO accountBase = new AccountVO();
+ BeanUtils.copyProperties(account,accountBase);
if (msg.getPassword() != null) {
for(PasswordUpdateExtensionPoint ext : pluginRgty.getExtensionList(PasswordUpdateExtensionPoint.class)) {
ext.preUpdatePassword(account.getUuid(), account.getPassword(), msg.getPassword());
@@ -115,7 +117,7 @@ public class AccountBase extends AbstractAccount {
// execute tf extension point
final AccountInventory inventory = AccountInventory.valueOf(account);
CollectionUtils.safeForEach(pluginRgty.getExtensionList(BeforeUpdateAccountExtensionPoint.class),
- arg -> arg.beforeUpdateAccount(inventory));
+ arg -> arg.beforeUpdateAccount(inventory,accountBase));
APIUpdateAccountEvent evt = new APIUpdateAccountEvent(msg.getId());
evt.setInventory(AccountInventory.valueOf(account));
@@ -206,7 +208,7 @@ public class AccountBase extends AbstractAccount {
private void handle(final APIDeleteAccountMsg msg) {
final APIDeleteAccountEvent evt = new APIDeleteAccountEvent(msg.getId());
-
+ AccountVO accountBase = Q.New(AccountVO.class).eq(AccountVO_.uuid, msg.getUuid()).find();
deleteAccount(new Completion(msg) {
@Override
public void success() {
@@ -214,7 +216,7 @@ public class AccountBase extends AbstractAccount {
final AccountInventory inventory = new AccountInventory();
inventory.setUuid(msg.getUuid() );
CollectionUtils.safeForEach(pluginRgty.getExtensionList(BeforeDeleteAccountExtensionPoint.class),
- arg -> arg.beforeDeleteAccount(inventory));
+ arg -> arg.beforeDeleteAccount(inventory,accountBase));
bus.publish(evt);
}
diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/account/AccountSync.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/account/AccountSync.java
index daed8aa5425b498fe808ff129cb85f07a4a8dea1..bef1d158dab85302337946635fa0f82f0e6401ca 100644
--- a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/account/AccountSync.java
+++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/account/AccountSync.java
@@ -1,17 +1,14 @@
package org.zstack.sugonSdnController.account;
import org.springframework.beans.factory.annotation.Autowired;
-import org.zstack.sugonSdnController.controller.SugonSdnController;
-import org.zstack.sugonSdnController.controller.SugonSdnControllerConstant;
import org.zstack.core.db.Q;
-import org.zstack.header.identity.AccountInventory;
-import org.zstack.header.identity.BeforeCreateAccountExtensionPoint;
-import org.zstack.header.identity.BeforeDeleteAccountExtensionPoint;
-import org.zstack.header.identity.BeforeUpdateAccountExtensionPoint;
+import org.zstack.header.identity.*;
import org.zstack.sdnController.SdnController;
import org.zstack.sdnController.SdnControllerManager;
import org.zstack.sdnController.header.SdnControllerVO;
import org.zstack.sdnController.header.SdnControllerVO_;
+import org.zstack.sugonSdnController.controller.SugonSdnController;
+import org.zstack.sugonSdnController.controller.SugonSdnControllerConstant;
/**
* @description:
@@ -31,18 +28,18 @@ public class AccountSync implements BeforeCreateAccountExtensionPoint, BeforeUpd
}
@Override
- public void beforeDeleteAccount(AccountInventory account) {
+ public void beforeDeleteAccount(AccountInventory account, AccountVO accountBase) {
SdnControllerVO sdn = Q.New(SdnControllerVO.class).eq(SdnControllerVO_.vendorType, SugonSdnControllerConstant.TF_CONTROLLER).find();
SdnController sdnController = sdnControllerManager.getSdnController(sdn);
SugonSdnController sugonSdnController = (SugonSdnController) sdnController;
- sugonSdnController.deleteAccount(account);
+ sugonSdnController.deleteAccount(account,accountBase);
}
@Override
- public void beforeUpdateAccount(AccountInventory account) {
+ public void beforeUpdateAccount(AccountInventory account, AccountVO accountBase) {
SdnControllerVO sdn = Q.New(SdnControllerVO.class).eq(SdnControllerVO_.vendorType, SugonSdnControllerConstant.TF_CONTROLLER).find();
SdnController sdnController = sdnControllerManager.getSdnController(sdn);
SugonSdnController sugonSdnController = (SugonSdnController) sdnController;
- sugonSdnController.updateAccount(account);
+ sugonSdnController.updateAccount(account,accountBase);
}
}
diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/SugonSdnController.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/SugonSdnController.java
index e10c9533c2e5fd4ad5494ac4e04219ad2a7678c9..5b19491a463df72793aeb024ad672b860b2e5d4e 100644
--- a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/SugonSdnController.java
+++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/SugonSdnController.java
@@ -2,12 +2,12 @@ package org.zstack.sugonSdnController.controller;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowire;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
+import org.zstack.core.cloudbus.CloudBus;
import org.zstack.core.db.Q;
import org.zstack.header.core.Completion;
-import org.zstack.header.identity.AccountInventory;
-import org.zstack.header.identity.AccountVO;
-import org.zstack.header.identity.AccountVO_;
+import org.zstack.header.identity.*;
import org.zstack.header.network.l2.APICreateL2NetworkMsg;
import org.zstack.header.network.l2.L2NetworkVO;
import org.zstack.header.network.l3.*;
@@ -38,6 +38,9 @@ public class SugonSdnController implements TfSdnController, SdnController {
private SdnControllerVO sdnControllerVO;
+ @Autowired
+ protected CloudBus bus;
+
public SugonSdnController(SdnControllerVO vo) {
sdnControllerVO = vo;
}
@@ -238,25 +241,32 @@ public class SugonSdnController implements TfSdnController, SdnController {
public void createAccount(AccountInventory account) {
try {
ApiConnector apiConnector = ApiConnectorFactory.build(sdnControllerVO.getIp(), SugonSdnControllerGlobalProperty.TF_CONTROLLER_PORT);
- Domain domain = (Domain) apiConnector.findByFQN(Domain.class, SugonSdnControllerConstant.TF_DEFAULT_DOMAIN);
- Project project = new Project();
- project.setParent(domain);
- project.setUuid(StringDSL.transToTfUuid(account.getUuid()));
- project.setDisplayName(account.getName());
- project.setName(account.getName());
- Status status = apiConnector.create(project);
- if (!status.isSuccess()) {
- String message = String.format("create tf project[name:%s] failed due to:%s ",account.getName(), "tf api call failed");
- logger.error(message);
+ Project checkProject = (Project)apiConnector.findById(Project.class,StringDSL.transToTfUuid(account.getUuid()));
+ if(checkProject==null) {
+ Domain domain = (Domain) apiConnector.findByFQN(Domain.class, SugonSdnControllerConstant.TF_DEFAULT_DOMAIN);
+ Project project = new Project();
+ project.setParent(domain);
+ project.setUuid(StringDSL.transToTfUuid(account.getUuid()));
+ project.setDisplayName(account.getName());
+ project.setName(account.getName());
+ Status status = apiConnector.create(project);
+ if (!status.isSuccess()) {
+ String message = String.format("create tf project[name:%s] failed due to:%s ", account.getName(), "tf api call failed");
+ logger.error(message);
+ //回滚
+ createAccountRollback(account);
+ }
}
} catch (Exception e){
String message = String.format("create tf project[name:%s] failed due to:%s ",account.getName(), e.getMessage());
logger.error(message, e);
+ //回滚
+ createAccountRollback(account);
}
}
@Override
- public void deleteAccount(AccountInventory account) {
+ public void deleteAccount(AccountInventory account,AccountVO accountBase) {
try {
ApiConnector apiConnector = ApiConnectorFactory.build(sdnControllerVO.getIp(), SugonSdnControllerGlobalProperty.TF_CONTROLLER_PORT);
Project project = new Project();
@@ -265,28 +275,39 @@ public class SugonSdnController implements TfSdnController, SdnController {
if (!status.isSuccess()) {
String message = String.format("delete tf project[name:%s] failed due to:%s ",account.getName(), "tf api call failed");
logger.error(message);
+ // 回滚
+ deleteAccountRollback(accountBase);
}
} catch (Exception e){
String message = String.format("delete tf project[name:%s] failed due to:%s ",account.getName(), e.getMessage());
logger.error(message, e);
+ // 回滚
+ deleteAccountRollback(accountBase);
}
}
@Override
- public void updateAccount(AccountInventory account) {
+ public void updateAccount(AccountInventory account,AccountVO accountBase) {
try {
ApiConnector apiConnector = ApiConnectorFactory.build(sdnControllerVO.getIp(), SugonSdnControllerGlobalProperty.TF_CONTROLLER_PORT);
- Project project = new Project();
- project.setUuid(StringDSL.transToTfUuid(account.getUuid()));
- project.setDisplayName(account.getName());
- Status status = apiConnector.update(project);
- if (!status.isSuccess()) {
- String message = String.format("update tf project[name:%s] failed due to:%s ",account.getName(), "tf api call failed");
- logger.error(message);
+ Project checkProject = (Project)apiConnector.findById(Project.class,StringDSL.transToTfUuid(account.getUuid()));
+ if(!checkProject.getDisplayName().equals(account.getName())) {
+ Project project = new Project();
+ project.setUuid(StringDSL.transToTfUuid(account.getUuid()));
+ project.setDisplayName(account.getName());
+ Status status = apiConnector.update(project);
+ if (!status.isSuccess()) {
+ String message = String.format("update tf project[name:%s] failed due to:%s ", account.getName(), "tf api call failed");
+ logger.error(message);
+ // 回滚
+ updateAccountRollback(accountBase);
+ }
}
} catch (Exception e){
String message = String.format("update tf project[name:%s] failed due to:%s ",account.getName(), e.getMessage());
logger.error(message, e);
+ // 回滚
+ updateAccountRollback(accountBase);
}
}
@@ -644,4 +665,38 @@ public class SugonSdnController implements TfSdnController, SdnController {
String enableDHCP = L3NetworkSystemTags.ENABLE_DHCP.getTokenByResourceUuid(l3Uuid, L3NetworkSystemTags.ENABLE_DHCP_TOKEN);
return Boolean.parseBoolean(enableDHCP);
}
+
+ private void createAccountRollback(AccountInventory account){
+ DeleteAccountMsg msg = new DeleteAccountMsg();
+ msg.setUuid(account.getUuid());
+ msg.setServiceId(bus.makeLocalServiceId(AccountConstant.SERVICE_ID));
+
+ bus.send(msg);
+ }
+
+ private void updateAccountRollback(AccountVO accountBase){
+ APIUpdateAccountMsg msg = new APIUpdateAccountMsg();
+ msg.setDescription(accountBase.getDescription());
+ msg.setName(accountBase.getName());
+ msg.setPassword(accountBase.getPassword());
+ msg.setUuid(accountBase.getUuid());
+ msg.setServiceId(bus.makeLocalServiceId(AccountConstant.SERVICE_ID));
+ SessionInventory sessionInventory = new SessionInventory();
+ sessionInventory.setAccountUuid(accountBase.getUuid());
+ msg.setSession(sessionInventory);
+
+ bus.send(msg);
+ }
+
+ private void deleteAccountRollback(AccountVO accountBase){
+ APICreateAccountMsg msg = new APICreateAccountMsg();
+ msg.setPassword(accountBase.getPassword());
+ msg.setResourceUuid(accountBase.getUuid());
+ msg.setName(accountBase.getName());
+ msg.setDescription(accountBase.getDescription());
+ msg.setType(accountBase.getType().name());
+ msg.setServiceId(bus.makeLocalServiceId(AccountConstant.SERVICE_ID));
+
+ bus.send(msg);
+ }
}
diff --git a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/TfSdnController.java b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/TfSdnController.java
index d278b476b38fae01272e6bc54891cb8089226e43..847b3678e8146a15529e2c796fdfdb41f9e60117 100644
--- a/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/TfSdnController.java
+++ b/plugin/sugonSdnController/src/main/java/org/zstack/sugonSdnController/controller/TfSdnController.java
@@ -2,6 +2,7 @@ package org.zstack.sugonSdnController.controller;
import org.zstack.header.core.Completion;
import org.zstack.header.identity.AccountInventory;
+import org.zstack.header.identity.AccountVO;
import org.zstack.header.network.l2.APICreateL2NetworkMsg;
import org.zstack.header.network.l2.L2NetworkVO;
import org.zstack.header.network.l3.*;
@@ -16,8 +17,8 @@ public interface TfSdnController {
// 账号同步:zstack->tf
void createAccount(AccountInventory account);
- void deleteAccount(AccountInventory account);
- void updateAccount(AccountInventory account);
+ void deleteAccount(AccountInventory account, AccountVO accountBase);
+ void updateAccount(AccountInventory account, AccountVO accountBase);
// L3网络:zstack->tf
void deleteL3Network(L3NetworkVO l3NetworkVO, Completion completion);