2525import com .vmware .nsx .model .ControllerClusterStatus ;
2626import com .vmware .nsx .model .TransportZone ;
2727import com .vmware .nsx .model .TransportZoneListResult ;
28+ import com .vmware .nsx_policy .Infra ;
2829import com .vmware .nsx_policy .infra .DhcpRelayConfigs ;
2930import com .vmware .nsx_policy .infra .IpDiscoveryProfiles ;
3031import com .vmware .nsx_policy .infra .LbAppProfiles ;
4243import com .vmware .nsx_policy .infra .domains .SecurityPolicies ;
4344import com .vmware .nsx_policy .infra .domains .groups .members .SegmentPorts ;
4445import com .vmware .nsx_policy .infra .domains .security_policies .Rules ;
45- import com .vmware .nsx_policy .infra .segments .SegmentDiscoveryProfileBindingMaps ;
46- import com .vmware .nsx_policy .infra .segments .SegmentSecurityProfileBindingMaps ;
4746import com .vmware .nsx_policy .infra .sites .EnforcementPoints ;
4847import com .vmware .nsx_policy .infra .tier_0s .LocaleServices ;
4948import com .vmware .nsx_policy .infra .tier_1s .nat .NatRules ;
5049import com .vmware .nsx_policy .model .ApiError ;
50+ import com .vmware .nsx_policy .model .ChildSegment ;
51+ import com .vmware .nsx_policy .model .ChildSegmentDiscoveryProfileBindingMap ;
52+ import com .vmware .nsx_policy .model .ChildSegmentSecurityProfileBindingMap ;
5153import com .vmware .nsx_policy .model .DhcpRelayConfig ;
5254import com .vmware .nsx_policy .model .EnforcementPoint ;
5355import com .vmware .nsx_policy .model .EnforcementPointListResult ;
@@ -139,6 +141,9 @@ public class NsxApiClient {
139141 private static final String TIER_1_RESOURCE_TYPE = "Tier1" ;
140142 private static final String TIER_1_LOCALE_SERVICE_ID = "default" ;
141143 private static final String SEGMENT_RESOURCE_TYPE = "Segment" ;
144+ private static final String INFRA_RESOURCE_TYPE = "Infra" ;
145+ private static final String SEGMENT_DISCOVERY_PROFILE_BINDING_RESOURCE_TYPE = "SegmentDiscoveryProfileBindingMap" ;
146+ private static final String SEGMENT_SECURITY_PROFILE_BINDING_RESOURCE_TYPE = "SegmentSecurityProfileBindingMap" ;
142147 private static final String SEGMENT_DISCOVERY_PROFILE_BINDING_ID = "cloudstack-discovery-profile-binding" ;
143148 private static final String SEGMENT_SECURITY_PROFILE_BINDING_ID = "cloudstack-security-profile-binding" ;
144149 private static final String TIER_0_GATEWAY_PATH_PREFIX = "/infra/tier-0s/" ;
@@ -489,7 +494,6 @@ public void createSegment(String segmentName, String tier1GatewayName, String ga
489494 String ipDiscoveryProfilePath = getIpDiscoveryProfilePath (ipDiscoveryProfileId );
490495 String macDiscoveryProfilePath = getMacDiscoveryProfilePath (macDiscoveryProfileId );
491496 String segmentSecurityProfilePath = getSegmentSecurityProfilePath (segmentSecurityProfileId );
492- Segments segmentService = (Segments ) nsxService .apply (Segments .class );
493497 SegmentSubnet subnet = new SegmentSubnet .Builder ()
494498 .setGatewayAddress (gatewayAddress )
495499 .build ();
@@ -502,8 +506,24 @@ public void createSegment(String segmentName, String tier1GatewayName, String ga
502506 .setSubnets (List .of (subnet ))
503507 .setTransportZonePath (enforcementPointPath + "/transport-zones/" + transportZones .get (0 ).getId ())
504508 .build ();
505- segmentService .patch (segmentName , segment );
506- bindSegmentProfiles (segmentName , ipDiscoveryProfilePath , macDiscoveryProfilePath , segmentSecurityProfilePath );
509+ List <Structure > profileBindings = getSegmentProfileBindings (ipDiscoveryProfilePath , macDiscoveryProfilePath ,
510+ segmentSecurityProfilePath );
511+ if (profileBindings .isEmpty ()) {
512+ Segments segmentService = (Segments ) nsxService .apply (Segments .class );
513+ segmentService .patch (segmentName , segment );
514+ } else {
515+ segment .setChildren (profileBindings );
516+ ChildSegment childSegment = new ChildSegment .Builder ()
517+ .setId (segmentName )
518+ .setSegment (segment )
519+ .build ();
520+ com .vmware .nsx_policy .model .Infra infra = new com .vmware .nsx_policy .model .Infra .Builder ()
521+ .setResourceType (INFRA_RESOURCE_TYPE )
522+ .setChildren (List .of (childSegment ))
523+ .build ();
524+ Infra infraService = (Infra ) nsxService .apply (Infra .class );
525+ infraService .patch (infra , false );
526+ }
507527 } catch (Error error ) {
508528 ApiError ae = error .getData ()._convertTo (ApiError .class );
509529 String msg = String .format ("Error creating segment %s: %s" , segmentName , ae .getErrorMessage ());
@@ -518,7 +538,7 @@ protected String getIpDiscoveryProfilePath(String profileId) {
518538 }
519539 IpDiscoveryProfiles profiles = (IpDiscoveryProfiles ) nsxService .apply (IpDiscoveryProfiles .class );
520540 IPDiscoveryProfile profile = profiles .get (profileId );
521- return validateProfilePath (profileId , profile .getPath ());
541+ return validateProfile (profileId , profile .getId (), profile . getPath (), "/infra/ip-discovery-profiles/" , profile . getMarkedForDelete ());
522542 }
523543
524544 protected String getMacDiscoveryProfilePath (String profileId ) {
@@ -527,7 +547,7 @@ protected String getMacDiscoveryProfilePath(String profileId) {
527547 }
528548 MacDiscoveryProfiles profiles = (MacDiscoveryProfiles ) nsxService .apply (MacDiscoveryProfiles .class );
529549 MacDiscoveryProfile profile = profiles .get (profileId );
530- return validateProfilePath (profileId , profile .getPath ());
550+ return validateProfile (profileId , profile .getId (), profile . getPath (), "/infra/mac-discovery-profiles/" , profile . getMarkedForDelete ());
531551 }
532552
533553 protected String getSegmentSecurityProfilePath (String profileId ) {
@@ -536,37 +556,50 @@ protected String getSegmentSecurityProfilePath(String profileId) {
536556 }
537557 SegmentSecurityProfiles profiles = (SegmentSecurityProfiles ) nsxService .apply (SegmentSecurityProfiles .class );
538558 SegmentSecurityProfile profile = profiles .get (profileId );
539- return validateProfilePath (profileId , profile .getPath ());
559+ return validateProfile (profileId , profile .getId (), profile . getPath (), "/infra/segment-security-profiles/" , profile . getMarkedForDelete ());
540560 }
541561
542- protected String validateProfilePath (String profileId , String profilePath ) {
543- if (StringUtils .isBlank (profilePath )) {
544- throw new CloudRuntimeException (String .format ("NSX profile %s did not return a canonical resource path" , profileId ));
562+ protected String validateProfile (String requestedId , String resolvedId , String profilePath ,
563+ String expectedPathPrefix , Boolean markedForDelete ) {
564+ if (!Objects .equals (requestedId , resolvedId )) {
565+ throw new CloudRuntimeException (String .format ("NSX returned profile %s while resolving requested profile %s" , resolvedId , requestedId ));
566+ }
567+ if (!Objects .equals (expectedPathPrefix + requestedId , profilePath )) {
568+ throw new CloudRuntimeException (String .format ("NSX profile %s did not return a canonical resource path of the expected type" , requestedId ));
569+ }
570+ if (Boolean .TRUE .equals (markedForDelete )) {
571+ throw new CloudRuntimeException (String .format ("NSX profile %s is marked for deletion" , requestedId ));
545572 }
546573 return profilePath ;
547574 }
548575
549- protected void bindSegmentProfiles (String segmentName , String ipDiscoveryProfilePath , String macDiscoveryProfilePath ,
550- String segmentSecurityProfilePath ) {
576+ protected List <Structure > getSegmentProfileBindings (String ipDiscoveryProfilePath , String macDiscoveryProfilePath ,
577+ String segmentSecurityProfilePath ) {
578+ List <Structure > bindings = new ArrayList <>();
551579 if (StringUtils .isNotBlank (ipDiscoveryProfilePath ) || StringUtils .isNotBlank (macDiscoveryProfilePath )) {
552- SegmentDiscoveryProfileBindingMaps discoveryBindings =
553- (SegmentDiscoveryProfileBindingMaps ) nsxService .apply (SegmentDiscoveryProfileBindingMaps .class );
554580 SegmentDiscoveryProfileBindingMap binding = new SegmentDiscoveryProfileBindingMap .Builder ()
581+ .setResourceType (SEGMENT_DISCOVERY_PROFILE_BINDING_RESOURCE_TYPE )
555582 .setId (SEGMENT_DISCOVERY_PROFILE_BINDING_ID )
556583 .setIpDiscoveryProfilePath (ipDiscoveryProfilePath )
557584 .setMacDiscoveryProfilePath (macDiscoveryProfilePath )
558585 .build ();
559- discoveryBindings .patch (segmentName , SEGMENT_DISCOVERY_PROFILE_BINDING_ID , binding );
586+ bindings .add (new ChildSegmentDiscoveryProfileBindingMap .Builder ()
587+ .setId (SEGMENT_DISCOVERY_PROFILE_BINDING_ID )
588+ .setSegmentDiscoveryProfileBindingMap (binding )
589+ .build ());
560590 }
561591 if (StringUtils .isNotBlank (segmentSecurityProfilePath )) {
562- SegmentSecurityProfileBindingMaps securityBindings =
563- (SegmentSecurityProfileBindingMaps ) nsxService .apply (SegmentSecurityProfileBindingMaps .class );
564592 SegmentSecurityProfileBindingMap binding = new SegmentSecurityProfileBindingMap .Builder ()
593+ .setResourceType (SEGMENT_SECURITY_PROFILE_BINDING_RESOURCE_TYPE )
565594 .setId (SEGMENT_SECURITY_PROFILE_BINDING_ID )
566595 .setSegmentSecurityProfilePath (segmentSecurityProfilePath )
567596 .build ();
568- securityBindings .patch (segmentName , SEGMENT_SECURITY_PROFILE_BINDING_ID , binding );
597+ bindings .add (new ChildSegmentSecurityProfileBindingMap .Builder ()
598+ .setId (SEGMENT_SECURITY_PROFILE_BINDING_ID )
599+ .setSegmentSecurityProfileBindingMap (binding )
600+ .build ());
569601 }
602+ return bindings ;
570603 }
571604
572605 public void deleteSegment (long zoneId , long domainId , long accountId , Long vpcId , long networkId , String segmentName ) {
0 commit comments