You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by GitBox <gi...@apache.org> on 2021/02/16 08:38:21 UTC

[GitHub] [cloudstack] weizhouapache opened a new pull request #4141: [New feature] Load balancer customization (haproxy-based)

weizhouapache opened a new pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141


   ## Description
   
   As discussed in mailing list, create this PR for haproxy config customization.
   
   FS: https://cwiki.apache.org/confluence/display/CLOUDSTACK/VR+haproxy+customization+in+CloudStack
   
   Fixes #3789
   
   It supports (or will support)
   - Basic haproxy configurations: 
   haproxy statistics uri, auth, enable/disable
   global maxconn and maxpipes
   - Basic configurations on rule 
   timeout connection, client ,server globally and per rule
   http, httpalive per rule
   maxconn, fullconn per rule
   maxconn, minconn, maxqueue per server in rule
   - advanced features 
   transparent load balancer
   SSL offloading
   http2 support
   Variable SSL configurations
   
   
   TODO:
   - UI change on primate
   - unit tests
   
   ## Types of changes
   <!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
   - [ ] Breaking change (fix or feature that would cause existing functionality to change)
   - [X] New feature (non-breaking change which adds functionality)
   - [ ] Bug fix (non-breaking change which fixes an issue)
   - [x] Enhancement (improves an existing feature and functionality)
   - [ ] Cleanup (Code refactoring and cleanup, that may add test cases)
   
   ## Screenshots (if appropriate):
   
   ## How Has This Been Tested?
   <!-- Please describe in detail how you tested your changes. -->
   <!-- Include details of your testing environment, and the tests you ran to -->
   <!-- see how your change affects other areas of the code, etc. -->
   
   
   <!-- Please read the [CONTRIBUTING](https://github.com/apache/cloudstack/blob/master/CONTRIBUTING.md) document -->
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-918865984


   Ping @weizhouapache I think some more work may be needed on this as now Debian 11 has moved to haproxy 2.x, should this be targeted for next milestone. I worry it may not be stable within two weeks, ie current tentative RC date. 


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-725710143


   <b>Trillian test result (tid-3156)</b>
   Environment: kvm-centos7 (x2), Advanced Networking with Mgmt server 7
   Total time taken: 31286 seconds
   Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr4141-t3156-kvm-centos7.zip
   Intermittent failure detected: /marvin/tests/smoke/test_privategw_acl.py
   Smoke tests completed. 86 look OK, 0 have error(s)
   Only failed tests results shown below:
   
   
   Test | Result | Time (s) | Test File
   --- | --- | --- | ---
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland closed pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland closed pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141


   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] sureshanaparti commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
sureshanaparti commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r520571068



##########
File path: core/src/main/java/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java
##########
@@ -72,4 +82,35 @@ public NicTO getNic() {
     public Long getVpcId() {
         return vpcId;
     }
+
+    public LoadBalancerConfigTO[] getNetworkLbConfigs() {
+        return this.networkLbConfigs;
+    }
+
+    public void setNetworkLbConfigs(List<? extends LoadBalancerConfig> networkLbConfigs) {
+        if (networkLbConfigs == null) {
+            networkLbConfigs = new ArrayList<LoadBalancerConfig>();
+        }
+        this.networkLbConfigs = new LoadBalancerConfigTO[networkLbConfigs.size()];

Review comment:
       @weizhouapache if you intention is to create an empty array, create `new LoadBalancerConfigTO[0]` and return when `networkLbConfigs` is null; else just return.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-781930165


   @blueorangutan package


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-684662336


   Packaging result: ✔centos7 ✖centos8 ✖debian. JID-1859


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan removed a comment on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan removed a comment on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-724922419






----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-713743041


   Packaging result: ✔centos7 ✔centos8 ✔debian. JID-2254


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r467488786



##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerConfigCmd.java
##########
@@ -0,0 +1,215 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.LoadBalancerConfigResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.rules.LoadBalancer;
+import com.cloud.network.rules.LoadBalancerConfig;
+import com.cloud.network.rules.LoadBalancerConfig.Scope;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "createLoadBalancerConfig", description = "Creates a load balancer config",

Review comment:
       should we add a `since` attribute

##########
File path: api/src/main/java/com/cloud/agent/api/to/LoadBalancerConfigTO.java
##########
@@ -0,0 +1,42 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.agent.api.to;
+
+import com.cloud.network.rules.LoadBalancerConfig;

Review comment:
       should we use org.apache.cloudstack as base packages for new classes?

##########
File path: api/src/main/java/com/cloud/network/rules/LoadBalancerConfig.java
##########
@@ -0,0 +1,83 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.network.rules;

Review comment:
       package

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerConfigCmd.java
##########
@@ -0,0 +1,215 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.LoadBalancerConfigResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.rules.LoadBalancer;
+import com.cloud.network.rules.LoadBalancerConfig;
+import com.cloud.network.rules.LoadBalancerConfig.Scope;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "createLoadBalancerConfig", description = "Creates a load balancer config",
+        responseObject = LoadBalancerConfigResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class CreateLoadBalancerConfigCmd extends BaseAsyncCreateCmd {
+    public static final Logger s_logger = Logger.getLogger(CreateLoadBalancerConfigCmd.class.getName());

Review comment:
       name convention for `public static final` is all capital. I'd suggest `LOGGER` as name.

##########
File path: api/src/main/java/com/cloud/network/lb/LoadBalancerConfigService.java
##########
@@ -0,0 +1,40 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.network.lb;

Review comment:
       base package for new classes




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-725422245


   Packaging result: ✔centos7 ✔centos8 ✔debian. JID-2368


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-698124537






----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-698165421


   @rhtyd a Trillian-Jenkins test job (centos7 mgmt + kvm-centos7) has been kicked to run smoke tests


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-700678115


   @rhtyd a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-683732170


   @rhtyd @luhaijiao conflicts are fixed


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-694618697


   @rhtyd a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-720330671






----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-713718282


   @rhtyd a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-684744571


   @rhtyd a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-689869648


   @rhtyd a Trillian-Jenkins test job (centos7 mgmt + kvm-centos7) has been kicked to run smoke tests


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-664250849


   Packaging result: ✖centos7 ✔debian. JID-1606


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-797104620


   <b>[S] Trillian test result (tid-84)</b>
   Environment: kvm-centos7 (x2), Advanced Networking with Mgmt server 7
   Total time taken: 45581 seconds
   Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr4141-t84-kvm-centos7.zip
   Intermittent failure detected: /marvin/tests/smoke/test_templates.py
   Intermittent failure detected: /marvin/tests/smoke/test_usage.py
   Intermittent failure detected: /marvin/tests/smoke/test_vm_life_cycle.py
   Smoke tests completed. 83 look OK, 3 have error(s)
   Only failed tests results shown below:
   
   
   Test | Result | Time (s) | Test File
   --- | --- | --- | ---
   test_CreateTemplateWithDuplicateName | `Error` | 953.60 | test_templates.py
   test_09_list_templates_download_details | `Failure` | 0.04 | test_templates.py
   test_01_lb_usage | `Error` | 0.00 | test_usage.py
   test_01_volume_usage | `Failure` | 786.31 | test_usage.py
   test_01_migrate_VM_and_root_volume | `Error` | 67.27 | test_vm_life_cycle.py
   test_02_migrate_VM_with_two_data_disks | `Error` | 50.11 | test_vm_life_cycle.py
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-673413561


   > @weizhouapache can you look at failures? Thanks
   
   @rhtyd I will do


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-725294714


   the test environemenmt keeps failing to start, needs love...


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-719432997


   @rhtyd @DaanHoogland @PaulAngus 
   rebased with latest master


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-721612964


   @DaanHoogland a Trillian-Jenkins test job (centos7 mgmt + kvm-centos7) has been kicked to run smoke tests


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-678879871


   @rhtyd a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-689500301


   @blueorangutan package


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-725433410


   @blueorangutan test


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-694646290


   @blueorangutan test centos7 vmware-67u3


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-792650678


   Packaging result: :heavy_multiplication_x: centos7 :heavy_multiplication_x: centos8 :heavy_multiplication_x: debian. SL-JID 54


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-698142615


   Packaging result: ✔centos7 ✔centos8 ✔debian. JID-2077


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache closed pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache closed pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141


   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-723987078


   Packaging result: ✔centos7 ✔centos8 ✔debian. JID-2345


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] GutoVeronezi commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
GutoVeronezi commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r660776060



##########
File path: api/src/main/java/com/cloud/agent/api/to/LoadBalancerTO.java
##########
@@ -179,6 +182,22 @@ public boolean isInline() {
         return inline;
     }
 
+    public LoadBalancerConfigTO[] getLbConfigs() {
+        return this.lbConfigs;
+    }
+
+    public void setLbConfigs(List<? extends LoadBalancerConfig> lbConfigs) {
+        if (lbConfigs == null || lbConfigs.size() == 0) {

Review comment:
       We could use `org.apache.commons.lang3.ArrayUtils` here:
   
   ```java
   ...
   if (ArrayUtils.isEmpty(lbConfigs)) {
   ...
   ```

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/AssignCertToLoadBalancerCmd.java
##########
@@ -103,4 +110,32 @@ public Long getCertId() {
     public Long getLbRuleId() {
         return lbRuleId;
     }
+
+    public boolean isForced() {
+        return (forced != null) ? forced : false;

Review comment:
       We could use `org.apache.commons.lang3.BooleanUtils` here:
   
   ```java
   ...
   return BooleanUtils.toBoolean(forced);
   ...
   ```

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/AssignCertToLoadBalancerCmd.java
##########
@@ -103,4 +110,32 @@ public Long getCertId() {
     public Long getLbRuleId() {
         return lbRuleId;
     }
+
+    public boolean isForced() {
+        return (forced != null) ? forced : false;
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.LoadBalancerRule;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return lbRuleId;
+    }
+
+    @Override
+    public String getSyncObjType() {
+        return BaseAsyncCmd.networkSyncObject;
+    }
+
+    @Override
+    public Long getSyncObjId() {
+        LoadBalancer lb = _entityMgr.findById(LoadBalancer.class, getLbRuleId());
+        if (lb == null) {
+            return null;
+        }
+        return lb.getNetworkId();

Review comment:
       We could implement a ternary here.

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerConfigCmd.java
##########
@@ -0,0 +1,216 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.LoadBalancerConfigResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig.Scope;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.rules.LoadBalancer;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "createLoadBalancerConfig", description = "Creates a load balancer config",
+        responseObject = LoadBalancerConfigResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        since = "4.15",
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class CreateLoadBalancerConfigCmd extends BaseAsyncCreateCmd {
+    public static final Logger LOGGER = Logger.getLogger(CreateLoadBalancerConfigCmd.class.getName());
+
+    private static final String s_name = "createloadbalancerconfigresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.SCOPE,
+               type = CommandType.STRING,
+               required = true,
+               description = "the scope of the config: network, vpc or rule")
+    private String scope;
+
+    @Parameter(name = ApiConstants.NETWORK_ID,
+               type = CommandType.UUID,
+               entityType = NetworkResponse.class,
+               description = "the ID of network to update")
+    private Long networkId;
+
+    @Parameter(name = ApiConstants.VPC_ID,
+               type = CommandType.UUID,
+               entityType = VpcResponse.class,
+               description = "the ID of vpc to update")
+    private Long vpcId;
+
+    @Parameter(name = ApiConstants.LOAD_BALANCER_ID,
+               type = CommandType.UUID,
+               entityType = FirewallRuleResponse.class,
+               description = "the ID of the load balancer rule to update")
+    private Long loadBalancerId;
+
+    @Parameter(name = ApiConstants.NAME,
+               type = CommandType.STRING,
+               required = true,
+               description = "name of the load balancer config")
+    private String name;
+
+    @Parameter(name = ApiConstants.VALUE,
+               type = CommandType.STRING,
+               required = true,
+               description = "value of the load balancer config")
+    private String value;
+
+    @Parameter(name = ApiConstants.FORCED,
+               type = CommandType.BOOLEAN,
+               required = false,
+               description = "Force add a load balancer config. Existing config will be removed")
+    private Boolean forced;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getScope() {
+        return scope;
+    }
+
+    public Long getVpcId() {
+        return vpcId;
+    }
+
+    public Long getNetworkId() {
+        return networkId;
+    }
+
+    public Long getLoadBalancerId() {
+        return loadBalancerId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public boolean isForced() {
+        return (forced != null) ? forced : false;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public void execute() {
+
+        LoadBalancerConfig config = null;
+        try {
+            config = _entityMgr.findById(LoadBalancerConfig.class, getEntityId());

Review comment:
       As `config` is not referenced outside the try block, we could declare it inside.

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/RemoveCertFromLoadBalancerCmd.java
##########
@@ -90,4 +91,28 @@ public long getEntityOwnerId() {
     public Long getLbRuleId() {
         return this.lbRuleId;
     }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.LoadBalancerRule;
+    }
+
+    @Override
+    public Long getInstanceId() {
+        return lbRuleId;
+    }
+
+    @Override
+    public String getSyncObjType() {
+        return BaseAsyncCmd.networkSyncObject;
+    }
+
+    @Override
+    public Long getSyncObjId() {
+        LoadBalancer lb = _entityMgr.findById(LoadBalancer.class, getLbRuleId());
+        if (lb == null) {
+            return null;
+        }
+        return lb.getNetworkId();

Review comment:
       We could implement a ternary here.

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLoadBalancerConfigCmd.java
##########
@@ -0,0 +1,148 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.LoadBalancerConfigResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "deleteLoadBalancerConfig", description = "Deletes a load balancer config.",
+        responseObject = SuccessResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        since = "4.15",
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class DeleteLoadBalancerConfigCmd extends BaseAsyncCmd {
+    public static final Logger LOGGER = Logger.getLogger(DeleteLoadBalancerConfigCmd.class.getName());
+    private static final String s_name = "deleteloadbalancerconfigresponse";
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID,
+               type = CommandType.UUID,
+               entityType = LoadBalancerConfigResponse.class,
+               required = true,
+               description = "the ID of the load balancer config")
+    private Long id;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public void execute() {
+        boolean result = _lbConfigService.deleteLoadBalancerConfig(this);
+
+        if (result) {
+            SuccessResponse response = new SuccessResponse(getCommandName());
+            this.setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete load balancer config");
+        }
+    }
+
+    @Override
+    public String getSyncObjType() {
+        LoadBalancerConfig config = _entityMgr.findById(LoadBalancerConfig.class, getId());
+        if (config == null) {
+            throw new InvalidParameterValueException("Unable to find load balancer config: " + id);
+        }
+        if (config.getNetworkId() != null) {
+            return BaseAsyncCmd.networkSyncObject;
+        } else if (config.getVpcId() != null) {
+            return BaseAsyncCmd.vpcSyncObject;
+        }
+        return null;
+    }
+
+    @Override
+    public Long getSyncObjId() {
+        LoadBalancerConfig config = _entityMgr.findById(LoadBalancerConfig.class, getId());
+        if (config == null) {
+            throw new InvalidParameterValueException("Unable to find load balancer config: " + id);
+        }
+        if (config.getNetworkId() != null) {
+            return config.getNetworkId();
+        } else if (config.getVpcId() != null) {
+            return config.getVpcId();
+        }
+        return null;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        LoadBalancerConfig config = _entityMgr.findById(LoadBalancerConfig.class, getId());
+        if (config != null) {
+            if (config.getNetworkId() != null) {
+                Network network = _entityMgr.findById(Network.class, config.getNetworkId());
+                if (network != null) {
+                    return network.getAccountId();
+                }
+            } else if (config.getVpcId() != null) {
+                Vpc vpc = _entityMgr.findById(Vpc.class, config.getVpcId());
+                if (vpc != null) {
+                    return vpc.getAccountId();
+                }
+            } else if (config.getLoadBalancerId() != null) {
+                FirewallRule rule = _entityMgr.findById(FirewallRule.class, config.getLoadBalancerId());
+                if (rule != null) {
+                    return rule.getAccountId();
+                }
+            }

Review comment:
       We could add this code to the helper that I mentioned before.

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLoadBalancerConfigCmd.java
##########
@@ -0,0 +1,156 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.LoadBalancerConfigResponse;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "updateLoadBalancerConfig", description = "Updates a load balancer config",
+        responseObject = LoadBalancerConfigResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        since = "4.15",
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class UpdateLoadBalancerConfigCmd extends BaseAsyncCmd {
+    public static final Logger LOGGER = Logger.getLogger(UpdateLoadBalancerConfigCmd.class.getName());
+    private static final String s_name = "updateloadbalancerconfigresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID,
+               type = CommandType.UUID,
+               entityType = LoadBalancerConfigResponse.class,
+               required = true,
+               description = "the ID of the load balancer config to update")
+    private Long id;
+
+    @Parameter(name = ApiConstants.VALUE,
+               type = CommandType.STRING,
+               required = true,
+               description = "value of the load balancer config")
+    private String value;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public void execute() {
+        LoadBalancerConfig result = _lbConfigService.updateLoadBalancerConfig(this);
+        if (result != null) {
+            LoadBalancerConfigResponse response = _responseGenerator.createLoadBalancerConfigResponse(result);
+            response.setResponseName(getCommandName());
+            this.setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update load balancer config");
+        }
+    }
+
+    @Override
+    public String getSyncObjType() {
+        LoadBalancerConfig config = _entityMgr.findById(LoadBalancerConfig.class, getId());
+        if (config == null) {
+            throw new InvalidParameterValueException("Unable to find load balancer config: " + id);
+        }
+        if (config.getNetworkId() != null) {
+            return BaseAsyncCmd.networkSyncObject;
+        } else if (config.getVpcId() != null) {
+            return BaseAsyncCmd.vpcSyncObject;
+        }
+        return null;
+    }
+
+    @Override
+    public Long getSyncObjId() {
+        LoadBalancerConfig config = _entityMgr.findById(LoadBalancerConfig.class, getId());
+        if (config == null) {
+            throw new InvalidParameterValueException("Unable to find load balancer config: " + id);
+        }
+        if (config.getNetworkId() != null) {
+            return config.getNetworkId();
+        } else if (config.getVpcId() != null) {
+            return config.getVpcId();
+        }
+        return null;

Review comment:
       We could add this code to the helper that I mentioned before.

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLoadBalancerConfigCmd.java
##########
@@ -0,0 +1,156 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.LoadBalancerConfigResponse;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "updateLoadBalancerConfig", description = "Updates a load balancer config",
+        responseObject = LoadBalancerConfigResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        since = "4.15",
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class UpdateLoadBalancerConfigCmd extends BaseAsyncCmd {
+    public static final Logger LOGGER = Logger.getLogger(UpdateLoadBalancerConfigCmd.class.getName());
+    private static final String s_name = "updateloadbalancerconfigresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID,
+               type = CommandType.UUID,
+               entityType = LoadBalancerConfigResponse.class,
+               required = true,
+               description = "the ID of the load balancer config to update")
+    private Long id;
+
+    @Parameter(name = ApiConstants.VALUE,
+               type = CommandType.STRING,
+               required = true,
+               description = "value of the load balancer config")
+    private String value;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public void execute() {
+        LoadBalancerConfig result = _lbConfigService.updateLoadBalancerConfig(this);
+        if (result != null) {
+            LoadBalancerConfigResponse response = _responseGenerator.createLoadBalancerConfigResponse(result);
+            response.setResponseName(getCommandName());
+            this.setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update load balancer config");
+        }

Review comment:
       We could invert the logic here to reduce block complexity:
   
   ```java
   ...
   if (result == null){
     throw...
   }
   
   ...
   ``` 

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLoadBalancerConfigCmd.java
##########
@@ -0,0 +1,156 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.LoadBalancerConfigResponse;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "updateLoadBalancerConfig", description = "Updates a load balancer config",
+        responseObject = LoadBalancerConfigResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        since = "4.15",
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class UpdateLoadBalancerConfigCmd extends BaseAsyncCmd {
+    public static final Logger LOGGER = Logger.getLogger(UpdateLoadBalancerConfigCmd.class.getName());
+    private static final String s_name = "updateloadbalancerconfigresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID,
+               type = CommandType.UUID,
+               entityType = LoadBalancerConfigResponse.class,
+               required = true,
+               description = "the ID of the load balancer config to update")
+    private Long id;
+
+    @Parameter(name = ApiConstants.VALUE,
+               type = CommandType.STRING,
+               required = true,
+               description = "value of the load balancer config")
+    private String value;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public void execute() {
+        LoadBalancerConfig result = _lbConfigService.updateLoadBalancerConfig(this);
+        if (result != null) {
+            LoadBalancerConfigResponse response = _responseGenerator.createLoadBalancerConfigResponse(result);
+            response.setResponseName(getCommandName());
+            this.setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update load balancer config");
+        }
+    }
+
+    @Override
+    public String getSyncObjType() {
+        LoadBalancerConfig config = _entityMgr.findById(LoadBalancerConfig.class, getId());
+        if (config == null) {
+            throw new InvalidParameterValueException("Unable to find load balancer config: " + id);
+        }
+        if (config.getNetworkId() != null) {
+            return BaseAsyncCmd.networkSyncObject;
+        } else if (config.getVpcId() != null) {
+            return BaseAsyncCmd.vpcSyncObject;
+        }
+        return null;
+    }
+
+    @Override
+    public Long getSyncObjId() {
+        LoadBalancerConfig config = _entityMgr.findById(LoadBalancerConfig.class, getId());
+        if (config == null) {
+            throw new InvalidParameterValueException("Unable to find load balancer config: " + id);
+        }
+        if (config.getNetworkId() != null) {
+            return config.getNetworkId();
+        } else if (config.getVpcId() != null) {
+            return config.getVpcId();
+        }
+        return null;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        LoadBalancerConfig config = _entityMgr.findById(LoadBalancerConfig.class, getId());
+        if (config != null) {
+            if (config.getNetworkId() != null) {
+                Network network = _entityMgr.findById(Network.class, config.getNetworkId());
+                if (network != null) {
+                    return network.getAccountId();
+                }
+            } else if (config.getVpcId() != null) {
+                Vpc vpc = _entityMgr.findById(Vpc.class, config.getVpcId());
+                if (vpc != null) {
+                    return vpc.getAccountId();
+                }
+            } else if (config.getLoadBalancerId() != null) {
+                FirewallRule rule = _entityMgr.findById(FirewallRule.class, config.getLoadBalancerId());
+                if (rule != null) {
+                    return rule.getAccountId();
+                }
+            }

Review comment:
       We could add this code to the helper that I mentioned before.

##########
File path: core/src/main/java/com/cloud/network/HAProxyConfigurator.java
##########
@@ -531,42 +654,111 @@ private String getLbSubRuleForStickiness(final LoadBalancerTO lbTO) {
                 }
             }
             if (httpbasedStickiness) {
-                result.addAll(dstWithCookieSubRule);
+                backendConfigs.addAll(dstWithCookieSubRule);
             } else {
-                result.addAll(dstSubRule);
+                backendConfigs.addAll(dstSubRule);
             }
-            result.add(stickinessSubRule);
+            backendConfigs.add(stickinessSubRule);
         } else {
-            result.addAll(dstSubRule);
+            backendConfigs.addAll(dstSubRule);
         }
         if (stickinessSubRule != null && !destsAvailable) {
             s_logger.warn("Haproxy stickiness policy for lb rule: " + lbTO.getSrcIp() + ":" + lbTO.getSrcPort() + ": Not Applied, cause:  backends are unavailable");
         }
-        if (publicPort == NetUtils.HTTP_PORT && !keepAliveEnabled || httpbasedStickiness) {
+        boolean http = false;
+        String cfgLbHttp = lbConfigsMap.get(LoadBalancerConfigKey.LbHttp.key());
+        if (publicPort == NetUtils.HTTP_PORT && cfgLbHttp == null) {
+            http = true;
+        } else if (cfgLbHttp != null && cfgLbHttp.equalsIgnoreCase("true")) {
+            http = true;
+        }
+
+        boolean keepAliveEnabled = lbCmd.keepAliveEnabled;
+        String cfgLbHttpKeepalive = lbConfigsMap.get(LoadBalancerConfigKey.LbHttpKeepalive.key());
+        if (cfgLbHttpKeepalive != null && cfgLbHttpKeepalive.equalsIgnoreCase("true")) {
+            keepAliveEnabled = true;
+        } else if (cfgLbHttpKeepalive != null && cfgLbHttpKeepalive.equalsIgnoreCase("false")) {
+            keepAliveEnabled = false;
+        }
+
+        if (http || httpbasedStickiness || sslOffloading) {
             sb = new StringBuilder();
             sb.append("\t").append("mode http");
+            frontendConfigs.add(sb.toString());
+            backendConfigsForHttp.add(sb.toString());
+            if (keepAliveEnabled) {
+                sb = new StringBuilder();
+                sb.append("\t").append("no option forceclose");
+                frontendConfigs.add(sb.toString());
+                backendConfigsForHttp.add(sb.toString());
+            } else {
+                sb = new StringBuilder();
+                sb.append("\t").append("option httpclose");
+                frontendConfigs.add(sb.toString());
+                backendConfigsForHttp.add(sb.toString());
+            }
+        }
+
+        if (isTransparent) {
+            sb = new StringBuilder();
+            sb.append("frontend ").append(poolName);
             result.add(sb.toString());
+            result.addAll(frontendConfigs);
             sb = new StringBuilder();
-            sb.append("\t").append("option httpclose");
+            sb.append("\tacl local_subnet src ").append(lbCmd.getNetworkCidr());
+            sb.append("\n\tuse_backend ").append(poolName).append("-backend-local if local_subnet");
+            sb.append("\n\tdefault_backend ").append(poolName).append("-backend");
+            sb.append("\n\n");
+            sb.append("backend ").append(poolName).append("-backend");
+            result.add(sb.toString());
+            result.addAll(backendConfigsForHttp);
+            result.addAll(backendConfigs);
+            sb = new StringBuilder();
+            sb.append("\t").append("source 0.0.0.0 usesrc clientip");
+            sb.append("\n\n");

Review comment:
       Instead of using `StringBuilder`, we could use `String.format`, it is more clean and readable.

##########
File path: api/src/main/java/org/apache/cloudstack/network/lb/LoadBalancerConfigKey.java
##########
@@ -0,0 +1,221 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.network.lb;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.cloudstack.network.lb.LoadBalancerConfig.SSLConfiguration;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig.Scope;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.cloud.utils.Pair;
+
+public enum LoadBalancerConfigKey {
+
+    LbStatsEnable(Category.Stats, "lb.stats.enable", "LB stats enable", Boolean.class, "true", "Enable statistics reporting with default settings, default is 'true'", Scope.Network, Scope.Vpc),
+
+    LbStatsUri(Category.Stats, "lb.stats.uri", "LB stats URI", String.class, "/admin?stats", "Enable statistics and define the URI prefix to access them, default is '/admin?stats'", Scope.Network, Scope.Vpc),
+
+    LbStatsAuth(Category.Stats, "lb.stats.auth", "LB stats auth", String.class, "admin1:AdMiN123", "Enable statistics with authentication and grant access to an account, default is 'admin1:AdMiN123'", Scope.Network, Scope.Vpc),
+
+    GlobalStatsSocket(Category.Stats, "global.stats.socket", "Stats socket enabled/disabled", Boolean.class, "false", "Binds a UNIX socket to /var/run/haproxy.socket, default is 'false'", Scope.Network, Scope.Vpc),
+
+    LbTimeoutConnect(Category.General, "lb.timeout.connect", "Maximum time (in ms) to wait for a connection to succeed", Long.class, "5000", "Set the maximum time to wait for a connection attempt to a server to succeed.", Scope.Network, Scope.Vpc, Scope.LoadBalancerRule),
+
+    LbTimeoutServer(Category.General, "lb.timeout.server", "Maximum inactivity time (in ms) on server side", Long.class, "50000", "Set the maximum inactivity time on the server side.", Scope.Network, Scope.Vpc, Scope.LoadBalancerRule),
+
+    LbTimeoutClient(Category.General, "lb.timeout.client", "Maximum inactivity time (in ms) on client side", Long.class, "50000", "Set the maximum inactivity time on the client side.", Scope.Network, Scope.Vpc, Scope.LoadBalancerRule),
+
+    LbHttp(Category.LoadBalancer, "lb.http", "LB http enabled/disabled", Boolean.class, "true for port 80; false for other ports", "If LB is http, default is 'true' for port 80 and 'false' for others'", Scope.LoadBalancerRule),
+
+    LbHttp2(Category.LoadBalancer, "lb.http2", "Enable/disable HTTP2 support", Boolean.class, "false", "Enable or disable HTTP2 support in HAproxy", Scope.LoadBalancerRule),
+
+    LbHttpKeepalive(Category.LoadBalancer, "lb.http.keepalive", "LB http keepalive enabled/disabled", Boolean.class, "<Inherited from network offering>", "Enable or disable HTTP keep-alive, default is inherited from network offering", Scope.LoadBalancerRule),
+
+    LbBackendHttps(Category.LoadBalancer, "lb.backend.https", "If backend server is https", Boolean.class, "false", "If backend server is https. If yes, use 'check ssl verify none' instead of 'check'", Scope.LoadBalancerRule),
+
+    LbTransparent(Category.LoadBalancer, "lb.transparent.mode", "LB transparent mode enabled/disabled", Boolean.class, "false", "Enable or disable transparent mode, default is 'false'", Scope.LoadBalancerRule),
+
+    GlobalMaxConn(Category.LoadBalancer, "global.maxconn", "LB max connection", Long.class, "4096", "Maximum per process number of concurrent connections, default is '4096'", Scope.Network, Scope.Vpc),
+
+    GlobalMaxPipes(Category.LoadBalancer, "global.maxpipes", "LB max pipes", Long.class, "<global.maxconn/4>", "Maximum number of per process pipes, default is 'maxconn/4'", Scope.Network, Scope.Vpc),
+
+    LbMaxConn(Category.LoadBalancer, "lb.maxconn", "LB max connection", Long.class, "<2000 in haproxy>", "Maximum per process number of concurrent connections per site/vm", Scope.LoadBalancerRule),
+
+    LbFullConn(Category.LoadBalancer, "lb.fullconn", "LB full connection", Long.class, "<maxconn/10 in haproxy>", "Specify at what backend load the servers will reach their maxconn, default is 'maxconn/10'", Scope.LoadBalancerRule),
+
+    LbServerMaxConn(Category.LoadBalancer, "lb.server.maxconn", "LB max connection per server", Long.class, "<0 means unlimited in haproxy>", "LB max connection per server, default is ''", Scope.LoadBalancerRule),
+
+    LbServerMinConn(Category.LoadBalancer, "lb.server.minconn", "LB minimum connection per server", Long.class, "", "LB minimum connection per server, default is ''", Scope.LoadBalancerRule),
+
+    LbServerMaxQueue(Category.LoadBalancer, "lb.server.maxqueue", "Max conn wait in queue per server", Long.class, "<0 means unlimited in haproxy>", "Maximum number of connections which will wait in queue for this server, default is ''", Scope.LoadBalancerRule),
+
+    LbSslConfiguration(Category.LoadBalancer, "lb.ssl.configuration", "SSL configuration, could be 'none', 'old' or 'intermediate'", String.class, "Inherited from global setting" , "if 'none', no SSL configurations will be added, if 'old', refer to https://ssl-config.mozilla.org/#server=haproxy&server-version=1.8.17&config=old&openssl-version=1.0.2l if 'intermediate', refer to https://ssl-config.mozilla.org/#server=haproxy&server-version=1.8.17&config=intermediate&openssl-version=1.0.2l default value is 'none'", Scope.LoadBalancerRule);
+
+    public static enum Category {
+        General, Advanced, Stats, LoadBalancer
+    }
+
+    private final Category _category;
+    private final Scope[] _scope;
+    private final String _key;
+    private final String _displayText;
+    private final String _description;
+    private final Class<?> _type;
+    private final String _defaultValue;
+
+    private LoadBalancerConfigKey(Category category, String key, String displayText, Class<?> type, String defaultValue, String description, Scope... scope) {
+        _category = category;
+        _scope = scope;
+        _key = key;
+        _displayText = displayText;
+        _type = type;
+        _defaultValue = defaultValue;
+        _description = description;
+    }
+
+    public Category category() {
+        return _category;
+    }
+
+    public Class<?> type() {
+        return _type;
+    }
+
+    public String key() {
+        return _key;
+    }
+
+    public String displayText() {
+        return _displayText;
+    }
+
+    public String defaultValue() {
+        return _defaultValue;
+    }
+
+    public String description() {
+        return _description;
+    }
+
+    public Scope[] scope() {
+        return _scope;
+    }
+
+    @Override
+    public String toString() {
+        return _key;
+    }
+
+    private static final HashMap<Scope, Map<String, LoadBalancerConfigKey>> Configs = new HashMap<Scope, Map<String, LoadBalancerConfigKey>>();
+    static {
+        Configs.put(Scope.Network, new LinkedHashMap<String, LoadBalancerConfigKey>());
+        Configs.put(Scope.Vpc, new LinkedHashMap<String, LoadBalancerConfigKey>());
+        Configs.put(Scope.LoadBalancerRule, new LinkedHashMap<String, LoadBalancerConfigKey>());
+        for (LoadBalancerConfigKey c : LoadBalancerConfigKey.values()) {
+            Scope[] scopes = c.scope();
+            for (Scope scope : scopes) {
+                Map<String, LoadBalancerConfigKey> currentConfigs = Configs.get(scope);
+                currentConfigs.put(c.key(), c);
+                Configs.put(scope, currentConfigs);
+            }
+        }
+    }
+
+    public static Map<String, LoadBalancerConfigKey> getConfigsByScope(Scope scope) {
+        return Configs.get(scope);
+    }
+
+    public static LoadBalancerConfigKey getConfigsByScopeAndName(Scope scope, String name) {
+        Map<String, LoadBalancerConfigKey> configs = Configs.get(scope);
+        if (configs.keySet().contains(name)) {
+            return configs.get(name);
+        }
+        return null;
+    }
+
+    public static Scope getScopeFromString(String scope) {
+        if (scope == null) {
+            return null;
+        }
+        for (Scope offScope : Scope.values()) {
+            if (offScope.name().equalsIgnoreCase(scope)) {
+                return offScope;
+            }
+        }
+        return null;
+    }
+
+    public static Pair<LoadBalancerConfigKey, String> validate(Scope scope, String key, String value) {
+        Map<String, LoadBalancerConfigKey> configs = Configs.get(scope);
+        if (configs == null) {
+            return new Pair<LoadBalancerConfigKey, String>(null, "Invalid scope " + scope);
+        }
+        LoadBalancerConfigKey config = null;
+        for (LoadBalancerConfigKey c : configs.values()) {
+            if (c.key().equals(key)) {
+                config = c;
+                break;
+            }
+        }
+        if (config == null) {
+            return new Pair<LoadBalancerConfigKey, String>(null, "Invalid key " + key);
+        }
+        if (value == null) {
+            return new Pair<LoadBalancerConfigKey, String>(null, "Invalid null value for parameter " + key);
+        }
+        Class<?> type = config.type();
+        String errMsg = null;
+        try {
+            if (type.equals(Integer.class)) {
+                errMsg = "Please enter a valid integer value for parameter " + key;
+                Integer.parseInt(value);
+            } else if (type.equals(Float.class)) {
+                errMsg = "Please enter a valid float value for parameter " + key;
+                Float.parseFloat(value);
+            } else if (type.equals(Long.class)) {
+                errMsg = "Please enter a valid long value for parameter " + key;
+                Long.parseLong(value);
+            }
+        } catch (final Exception e) {
+            // catching generic exception as some throws NullPointerException and some throws NumberFormatExcpeion

Review comment:
       As they are known, we could catch them, instead of catch them all.

##########
File path: server/src/main/java/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
##########
@@ -1748,7 +1816,22 @@ private void updateWithLbRules(final DomainRouterJoinVO routerJoinVO, final Stri
                             .append(",protocol=").append(appLoadBalancerVO.getLbProtocol());
                 }
                 loadBalancingData.append(",stickiness=").append(getStickinessPolicies(firewallRuleVO.getId()));
-                loadBalancingData.append(",keepAliveEnabled=").append(offering.isKeepAliveEnabled()).append(",vmIps=");
+                if (isHttp != null) {
+                    loadBalancingData.append(",http=").append(isHttp);
+                } else if (firewallRuleVO.getSourcePortStart() == NetUtils.HTTP_PORT) {
+                    loadBalancingData.append(",http=").append(true);
+                }
+                if (isHttpKeepalive != null) {
+                    loadBalancingData.append(",keepAliveEnabled=").append(isHttpKeepalive);
+                } else {
+                    loadBalancingData.append(",keepAliveEnabled=").append(offering.isKeepAliveEnabled());
+                }
+                if (isTransparent != null) {
+                    loadBalancingData.append(",transparent=").append(isTransparent);
+                }

Review comment:
       This code seems repeated, but changing parameters; We could extract it to a method.

##########
File path: server/src/main/java/org/apache/cloudstack/network/lb/LoadBalancerConfigManagerImpl.java
##########
@@ -0,0 +1,396 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.network.lb;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.dao.LoadBalancerConfigDao;
+import com.cloud.network.dao.LoadBalancerConfigVO;
+import com.cloud.network.dao.LoadBalancerDao;
+import com.cloud.network.dao.LoadBalancerVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkServiceMapDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.lb.LoadBalancingRulesManager;
+import com.cloud.network.rules.LoadBalancerContainer.Scheme;
+import com.cloud.network.vpc.VpcVO;
+import com.cloud.network.vpc.dao.VpcDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+import org.apache.cloudstack.api.command.user.loadbalancer.CreateLoadBalancerConfigCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.DeleteLoadBalancerConfigCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerConfigsCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.ReplaceLoadBalancerConfigsCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.UpdateLoadBalancerConfigCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig.Scope;
+import org.apache.log4j.Logger;
+
+public class LoadBalancerConfigManagerImpl extends ManagerBase implements LoadBalancerConfigService, LoadBalancerConfigManager {
+    private static final Logger LOGGER = Logger.getLogger(LoadBalancerConfigManagerImpl.class);
+
+    @Inject
+    LoadBalancerConfigDao _lbConfigDao;
+    @Inject
+    NetworkDao _networkDao;
+    @Inject
+    VpcDao _vpcDao;
+    @Inject
+    LoadBalancerDao _lbDao;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    LoadBalancingRulesManager _lbMgr;
+    @Inject
+    NetworkServiceMapDao _ntwkSrvcDao;
+
+    @Override
+    public List<? extends LoadBalancerConfig> searchForLoadBalancerConfigs(ListLoadBalancerConfigsCmd cmd) {
+        Long id = cmd.getId();
+        String scopeStr = cmd.getScope();
+        Long networkId = cmd.getNetworkId();
+        Long vpcId = cmd.getVpcId();
+        Long loadBalancerId = cmd.getLoadBalancerId();
+        String name = cmd.getName();
+
+        if (id == null && scopeStr == null) {
+            throw new InvalidParameterValueException("At least one of id/scope is required");
+        }
+
+        //validate parameters
+        Scope scope = null;
+        if (scopeStr != null) {
+            scope = LoadBalancerConfigKey.getScopeFromString(scopeStr);
+            if (scope == null) {
+                throw new InvalidParameterValueException("Invalid scope " + scopeStr);
+            }
+            checkPermission(scope, networkId, vpcId, loadBalancerId, cmd.listAll());
+        }
+
+        if (id != null) {
+            LoadBalancerConfigVO config = _lbConfigDao.findById(id);
+            if (config == null) {
+                throw new InvalidParameterValueException("Cannot find load balancer config by id " + id);
+            }
+            checkPermission(config);
+        }
+
+        if (cmd.listAll()) {
+            if (id != null || name != null) {
+                throw new InvalidParameterValueException("id and name must be null if listall is true");
+            }
+        }
+
+        SearchCriteria<LoadBalancerConfigVO> sc = _lbConfigDao.createSearchCriteria();
+        if (id != null) {
+            sc.addAnd("id", SearchCriteria.Op.EQ, id);
+        }
+        if (scope != null) {
+            sc.addAnd("scope", SearchCriteria.Op.EQ, scope);
+        }
+        if (networkId != null) {
+            sc.addAnd("networkId", SearchCriteria.Op.EQ, networkId);
+        }
+        if (vpcId != null) {
+            sc.addAnd("vpcId", SearchCriteria.Op.EQ, vpcId);
+        }
+        if (loadBalancerId != null) {
+            sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId);
+        }
+        if (name != null) {
+            sc.addAnd("name", SearchCriteria.Op.EQ, name);
+        }
+        List<LoadBalancerConfigVO> configs = new ArrayList<LoadBalancerConfigVO>();
+        if (id != null || networkId != null || vpcId != null || loadBalancerId != null) {

Review comment:
       We could use `org.apache.commons.lang3.ObjectUtils` here:
   
   ```java
   ...
   if (ObjectUtils.anyNotNull(id, networkId...
   ...
   ```

##########
File path: server/src/main/java/org/apache/cloudstack/network/lb/LoadBalancerConfigManagerImpl.java
##########
@@ -0,0 +1,396 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.network.lb;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.dao.LoadBalancerConfigDao;
+import com.cloud.network.dao.LoadBalancerConfigVO;
+import com.cloud.network.dao.LoadBalancerDao;
+import com.cloud.network.dao.LoadBalancerVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkServiceMapDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.lb.LoadBalancingRulesManager;
+import com.cloud.network.rules.LoadBalancerContainer.Scheme;
+import com.cloud.network.vpc.VpcVO;
+import com.cloud.network.vpc.dao.VpcDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+import org.apache.cloudstack.api.command.user.loadbalancer.CreateLoadBalancerConfigCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.DeleteLoadBalancerConfigCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerConfigsCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.ReplaceLoadBalancerConfigsCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.UpdateLoadBalancerConfigCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig.Scope;
+import org.apache.log4j.Logger;
+
+public class LoadBalancerConfigManagerImpl extends ManagerBase implements LoadBalancerConfigService, LoadBalancerConfigManager {
+    private static final Logger LOGGER = Logger.getLogger(LoadBalancerConfigManagerImpl.class);
+
+    @Inject
+    LoadBalancerConfigDao _lbConfigDao;
+    @Inject
+    NetworkDao _networkDao;
+    @Inject
+    VpcDao _vpcDao;
+    @Inject
+    LoadBalancerDao _lbDao;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    LoadBalancingRulesManager _lbMgr;
+    @Inject
+    NetworkServiceMapDao _ntwkSrvcDao;
+
+    @Override
+    public List<? extends LoadBalancerConfig> searchForLoadBalancerConfigs(ListLoadBalancerConfigsCmd cmd) {
+        Long id = cmd.getId();
+        String scopeStr = cmd.getScope();
+        Long networkId = cmd.getNetworkId();
+        Long vpcId = cmd.getVpcId();
+        Long loadBalancerId = cmd.getLoadBalancerId();
+        String name = cmd.getName();
+
+        if (id == null && scopeStr == null) {
+            throw new InvalidParameterValueException("At least one of id/scope is required");
+        }
+
+        //validate parameters
+        Scope scope = null;
+        if (scopeStr != null) {
+            scope = LoadBalancerConfigKey.getScopeFromString(scopeStr);
+            if (scope == null) {
+                throw new InvalidParameterValueException("Invalid scope " + scopeStr);
+            }
+            checkPermission(scope, networkId, vpcId, loadBalancerId, cmd.listAll());
+        }
+
+        if (id != null) {
+            LoadBalancerConfigVO config = _lbConfigDao.findById(id);
+            if (config == null) {
+                throw new InvalidParameterValueException("Cannot find load balancer config by id " + id);
+            }
+            checkPermission(config);
+        }
+
+        if (cmd.listAll()) {
+            if (id != null || name != null) {
+                throw new InvalidParameterValueException("id and name must be null if listall is true");
+            }
+        }
+
+        SearchCriteria<LoadBalancerConfigVO> sc = _lbConfigDao.createSearchCriteria();
+        if (id != null) {
+            sc.addAnd("id", SearchCriteria.Op.EQ, id);
+        }
+        if (scope != null) {
+            sc.addAnd("scope", SearchCriteria.Op.EQ, scope);
+        }
+        if (networkId != null) {
+            sc.addAnd("networkId", SearchCriteria.Op.EQ, networkId);
+        }
+        if (vpcId != null) {
+            sc.addAnd("vpcId", SearchCriteria.Op.EQ, vpcId);
+        }
+        if (loadBalancerId != null) {
+            sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId);
+        }
+        if (name != null) {
+            sc.addAnd("name", SearchCriteria.Op.EQ, name);
+        }
+        List<LoadBalancerConfigVO> configs = new ArrayList<LoadBalancerConfigVO>();
+        if (id != null || networkId != null || vpcId != null || loadBalancerId != null) {
+            configs = _lbConfigDao.search(sc, null);
+        }
+        if (cmd.listAll()) {
+            LOGGER.debug("Adding config keys for scope " + scope);
+            Map<String, LoadBalancerConfigVO> configsMap = new LinkedHashMap<String, LoadBalancerConfigVO>();
+            for (LoadBalancerConfigVO config : configs) {
+                configsMap.put(config.getName(), config);
+            }
+            List<LoadBalancerConfigVO> result = new ArrayList<LoadBalancerConfigVO>();
+            Map<String, LoadBalancerConfigKey> configKeys = LoadBalancerConfigKey.getConfigsByScope(scope);
+            for (LoadBalancerConfigKey configKey : configKeys.values()) {
+                if (configsMap.get(configKey.key()) != null) {
+                    result.add(configsMap.get(configKey.key()));
+                } else {
+                    result.add(new LoadBalancerConfigVO(scope, null, null, null, configKey, null));
+                }
+            }
+            return result;
+        } else {
+            return configs;
+        }
+    }
+
+    @Override
+    public LoadBalancerConfig createLoadBalancerConfig(CreateLoadBalancerConfigCmd cmd) {
+        String scopeStr = cmd.getScope();
+        Long networkId = cmd.getNetworkId();
+        Long vpcId = cmd.getVpcId();
+        Long loadBalancerId = cmd.getLoadBalancerId();
+        String name = cmd.getName();
+        String value = cmd.getValue();
+
+        //validate parameters
+        Scope scope = LoadBalancerConfigKey.getScopeFromString(scopeStr);
+        if (scope == null) {
+            throw new InvalidParameterValueException("Invalid scope " + scopeStr);
+        }
+        LoadBalancerConfigKey configKey = validateParameters(scope, name, value);
+
+        checkPermission(scope, networkId, vpcId, loadBalancerId);
+
+        LoadBalancerConfigVO existingConfig = _lbConfigDao.findConfig(scope, networkId, vpcId, loadBalancerId, name);
+        if (existingConfig != null) {
+            if (cmd.isForced()) {
+                _lbConfigDao.remove(existingConfig.getId());
+            } else {
+                throw new InvalidParameterValueException("config " + name + " already exists, please add forced=true or update it instead");           }
+        }
+        LoadBalancerConfigVO config = _lbConfigDao.persist(new LoadBalancerConfigVO(scope, networkId, vpcId, loadBalancerId, configKey, value));
+
+        applyLbConfigsForNetwork(config.getNetworkId(), config.getVpcId(), config.getLoadBalancerId());
+
+        return config;
+    }
+
+    @Override
+    public boolean deleteLoadBalancerConfig(DeleteLoadBalancerConfigCmd cmd) {
+        Long id = cmd.getId();
+        LoadBalancerConfigVO config = _lbConfigDao.findById(id);
+        if (config == null) {
+            throw new InvalidParameterValueException("Cannot find load balancer config by id " + id);
+        }
+        checkPermission(config);
+
+        boolean result = _lbConfigDao.remove(id);
+
+        applyLbConfigsForNetwork(config.getNetworkId(), config.getVpcId(), config.getLoadBalancerId());
+
+        return result;
+    }
+
+    @Override
+    public LoadBalancerConfig updateLoadBalancerConfig(UpdateLoadBalancerConfigCmd cmd) {
+        Long id = cmd.getId();
+        String value = cmd.getValue();
+
+        LoadBalancerConfigVO config = _lbConfigDao.findById(id);
+        if (config == null) {
+            throw new InvalidParameterValueException("Cannot find load balancer config by id " + id);
+        }
+        //validate parameters
+        LoadBalancerConfigKey configKey = validateParameters(config.getScope(), config.getName(), value);
+
+        checkPermission(config);
+        config.setValue(value);
+
+        _lbConfigDao.update(config.getId(), config);
+
+        applyLbConfigsForNetwork(config.getNetworkId(), config.getVpcId(), config.getLoadBalancerId());
+
+        return config;
+    }
+
+    @Override
+    public List<? extends LoadBalancerConfig> replaceLoadBalancerConfigs(ReplaceLoadBalancerConfigsCmd cmd) {
+        String scopeStr = cmd.getScope();
+        Long networkId = cmd.getNetworkId();
+        Long vpcId = cmd.getVpcId();
+        Long loadBalancerId = cmd.getLoadBalancerId();
+        Map<String, String> configList = cmd.getConfigList();
+        if (configList == null) {
+            throw new InvalidParameterValueException("Invalid config list");
+        }
+
+        //validate parameters
+        Scope scope = LoadBalancerConfigKey.getScopeFromString(scopeStr);
+        if (scope == null) {
+            throw new InvalidParameterValueException("Invalid scope " + scopeStr);
+        }
+        List<LoadBalancerConfigVO> configs = new ArrayList<LoadBalancerConfigVO>();
+        for (String name : configList.keySet()) {
+            String value = configList.get(name);
+            LoadBalancerConfigKey configKey = validateParameters(scope, name, value);
+            configs.add(new LoadBalancerConfigVO(scope, networkId, vpcId, loadBalancerId, configKey, value));
+        }
+
+        checkPermission(scope, networkId, vpcId, loadBalancerId);
+
+        configs = _lbConfigDao.saveConfigs(configs);
+
+        applyLbConfigsForNetwork(networkId, vpcId, loadBalancerId);
+
+        return configs;
+    }
+
+    private LoadBalancerConfigKey validateParameters(Scope scope, String name, String value) {
+        Pair<LoadBalancerConfigKey, String> res = LoadBalancerConfigKey.validate(scope, name, value);
+        if (res.second() != null) {
+            throw new InvalidParameterValueException(res.second());
+        }
+        return res.first();
+    }
+
+    private void checkPermission(LoadBalancerConfigVO config) {
+        checkPermission(config.getScope(), config.getNetworkId(), config.getVpcId(), config.getLoadBalancerId());
+    }
+
+    private void checkPermission(Scope scope, Long networkId, Long vpcId, Long loadBalancerId) {
+        checkPermission(scope, networkId, vpcId, loadBalancerId, false);
+    }
+
+    private void checkPermission(Scope scope, Long networkId, Long vpcId, Long loadBalancerId, Boolean listAll) {
+        Account caller = CallContext.current().getCallingAccount();
+        if (scope == Scope.Network) {
+            if (networkId == null) {
+                if (listAll) {
+                    return;
+                }
+                throw new InvalidParameterValueException("networkId is required");
+            }
+            if (vpcId != null || loadBalancerId != null) {

Review comment:
       We could use `org.apache.commons.lang3.ObjectUtils` here:
   
   ```java
   ...
   ObjectUtils.anyNotNull(...
   ...
   ```

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerConfigCmd.java
##########
@@ -0,0 +1,216 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.LoadBalancerConfigResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig.Scope;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.rules.LoadBalancer;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "createLoadBalancerConfig", description = "Creates a load balancer config",
+        responseObject = LoadBalancerConfigResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        since = "4.15",
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class CreateLoadBalancerConfigCmd extends BaseAsyncCreateCmd {
+    public static final Logger LOGGER = Logger.getLogger(CreateLoadBalancerConfigCmd.class.getName());
+
+    private static final String s_name = "createloadbalancerconfigresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.SCOPE,
+               type = CommandType.STRING,
+               required = true,
+               description = "the scope of the config: network, vpc or rule")
+    private String scope;
+
+    @Parameter(name = ApiConstants.NETWORK_ID,
+               type = CommandType.UUID,
+               entityType = NetworkResponse.class,
+               description = "the ID of network to update")
+    private Long networkId;
+
+    @Parameter(name = ApiConstants.VPC_ID,
+               type = CommandType.UUID,
+               entityType = VpcResponse.class,
+               description = "the ID of vpc to update")
+    private Long vpcId;
+
+    @Parameter(name = ApiConstants.LOAD_BALANCER_ID,
+               type = CommandType.UUID,
+               entityType = FirewallRuleResponse.class,
+               description = "the ID of the load balancer rule to update")
+    private Long loadBalancerId;
+
+    @Parameter(name = ApiConstants.NAME,
+               type = CommandType.STRING,
+               required = true,
+               description = "name of the load balancer config")
+    private String name;
+
+    @Parameter(name = ApiConstants.VALUE,
+               type = CommandType.STRING,
+               required = true,
+               description = "value of the load balancer config")
+    private String value;
+
+    @Parameter(name = ApiConstants.FORCED,
+               type = CommandType.BOOLEAN,
+               required = false,
+               description = "Force add a load balancer config. Existing config will be removed")
+    private Boolean forced;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getScope() {
+        return scope;
+    }
+
+    public Long getVpcId() {
+        return vpcId;
+    }
+
+    public Long getNetworkId() {
+        return networkId;
+    }
+
+    public Long getLoadBalancerId() {
+        return loadBalancerId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public boolean isForced() {
+        return (forced != null) ? forced : false;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public void execute() {
+
+        LoadBalancerConfig config = null;
+        try {
+            config = _entityMgr.findById(LoadBalancerConfig.class, getEntityId());
+            LoadBalancerConfigResponse lbConfigResponse = new LoadBalancerConfigResponse();
+            if (config != null) {
+                lbConfigResponse = _responseGenerator.createLoadBalancerConfigResponse(config);
+                setResponseObject(lbConfigResponse);
+            }
+            lbConfigResponse.setResponseName(getCommandName());
+        } catch (Exception ex) {
+            LOGGER.warn("Failed to create LB config due to exception ", ex);
+        }
+    }
+
+    @Override
+    public void create() {
+        try {
+            LoadBalancerConfig result = _lbConfigService.createLoadBalancerConfig(this);
+            this.setEntityId(result.getId());
+            this.setEntityUuid(result.getUuid());
+        } catch (InvalidParameterValueException e) {
+            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage());
+        }
+    }
+
+    @Override
+    public String getSyncObjType() {
+        if (networkId != null) {
+            return BaseAsyncCmd.networkSyncObject;
+        } else if (vpcId != null) {
+            return BaseAsyncCmd.vpcSyncObject;
+        }
+        return null;
+    }
+
+    @Override
+    public Long getSyncObjId() {
+        if (networkId != null) {
+            return getNetworkId();
+        } else if (vpcId != null) {

Review comment:
       This `else` statement does not make difference here, we could remove it.

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/ReplaceLoadBalancerConfigsCmd.java
##########
@@ -0,0 +1,173 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "replaceLoadBalancerConfigs", description = "Replaces load balancer configs of vpc/network/rule",
+        responseObject = SuccessResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        since = "4.15",
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class ReplaceLoadBalancerConfigsCmd extends BaseAsyncCmd {
+    public static final Logger LOGGER = Logger.getLogger(ReplaceLoadBalancerConfigsCmd.class.getName());
+    private static final String s_name = "replaceloadbalancerconfigsresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.SCOPE,
+               type = CommandType.STRING,
+               required = true,
+               description = "the scope of the config: network, vpc or rule")
+    private String scope;
+
+    @Parameter(name = ApiConstants.NETWORK_ID,
+               type = CommandType.UUID,
+               entityType = NetworkResponse.class,
+               description = "the ID of network to update")
+    private Long networkId;
+
+    @Parameter(name = ApiConstants.VPC_ID,
+               type = CommandType.UUID,
+               entityType = VpcResponse.class,
+               description = "the ID of vpc to update")
+    private Long vpcId;
+
+    @Parameter(name = ApiConstants.LOAD_BALANCER_ID,
+               type = CommandType.UUID,
+               entityType = FirewallRuleResponse.class,
+               description = "the ID of the load balancer rule to update")
+    private Long loadBalancerId;
+
+    @Parameter(name = ApiConstants.CONFIG,
+               type = CommandType.MAP,
+               description = "configs list, Example: config[0].global.maxconn=40960")
+    private Map<String, String> configList;
+
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getScope() {
+        return scope;
+    }
+
+    public Long getVpcId() {
+        return vpcId;
+    }
+
+    public Long getNetworkId() {
+        return networkId;
+    }
+
+    public Long getLoadBalancerId() {
+        return loadBalancerId;
+    }
+
+    public Map<String, String> getConfigList() {
+        if (configList == null || configList.isEmpty()) {
+            return null;
+        }
+
+        Collection<String> paramsCollection = configList.values();
+        return (Map<String, String>) (paramsCollection.toArray())[0];

Review comment:
       Is this code right?  `(paramsCollection.toArray())[0]`  returns a String and it's trying to convert the String to a `Map<String, String>`, which will cause a `ClassCastException`. Shouldn't it just returns `configList`?

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java
##########
@@ -255,7 +255,7 @@ public Boolean getOpenFirewall() {
     }
 
     public String getLbProtocol() {
-        return lbProtocol;
+        return lbProtocol != null ? lbProtocol.toLowerCase().trim() : null;

Review comment:
       We could use `org.apache.commons.lang3.StringUtils` here:
   
   ```java
   ...
   return StringUtils.trim(StringUtils.lowerCase(lbProtocol));
   ...
   ```

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/ListLoadBalancerConfigsCmd.java
##########
@@ -0,0 +1,143 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.LoadBalancerConfigResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig;
+import org.apache.log4j.Logger;
+
+@APICommand(name = "listLoadBalancerConfigs", description = "Lists load balancer configs.",
+        responseObject = LoadBalancerConfigResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        since = "4.15",
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class ListLoadBalancerConfigsCmd extends BaseListCmd {
+    public static final Logger LOGGER = Logger.getLogger(ListLoadBalancerConfigsCmd.class.getName());
+
+    private static final String s_name = "listloadbalancerconfigsresponse";
+
+    // ///////////////////////////////////////////////////
+    // ////////////// API parameters /////////////////////
+    // ///////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID,
+               type = CommandType.UUID,
+               entityType = LoadBalancerConfigResponse.class,
+               description = "the ID of the load balancer config")
+    private Long id;
+
+    @Parameter(name = ApiConstants.SCOPE,
+               type = CommandType.STRING,
+               required = true,
+               description = "the scope of the config: network, vpc or rule")
+    private String scope;
+
+    @Parameter(name = ApiConstants.NETWORK_ID,
+               type = CommandType.UUID,
+               entityType = NetworkResponse.class,
+               description = "the ID of network to update")
+    private Long networkId;
+
+    @Parameter(name = ApiConstants.VPC_ID,
+               type = CommandType.UUID,
+               entityType = VpcResponse.class,
+               description = "the ID of vpc to update")
+    private Long vpcId;
+
+    @Parameter(name = ApiConstants.LOAD_BALANCER_ID,
+               type = CommandType.UUID,
+               entityType = FirewallRuleResponse.class,
+               description = "the ID of the load balancer rule to update")
+    private Long loadBalancerId;
+
+    @Parameter(name = ApiConstants.NAME,
+               type = CommandType.STRING,
+               description = "name of the load balancer config")
+    private String name;
+
+    @Parameter(name = ApiConstants.LIST_ALL,
+               type = CommandType.BOOLEAN,
+               description = "If set to true, list all available configs for the scope. Default value is false")
+    private Boolean listAll;
+
+    // ///////////////////////////////////////////////////
+    // ///////////////// Accessors ///////////////////////
+    // ///////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getScope() {
+        return scope;
+    }
+
+    public Long getVpcId() {
+        return vpcId;
+    }
+
+    public Long getNetworkId() {
+        return networkId;
+    }
+
+    public Long getLoadBalancerId() {
+        return loadBalancerId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public boolean listAll() {
+        return listAll == null ? false : listAll;

Review comment:
       We could use `org.apache.commons.lang3.BooleanUtils` here:
   
   ```java
   ...
   return BooleanUtils.toBoolean(listAll);
   ...
   ```

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/ReplaceLoadBalancerConfigsCmd.java
##########
@@ -0,0 +1,173 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "replaceLoadBalancerConfigs", description = "Replaces load balancer configs of vpc/network/rule",
+        responseObject = SuccessResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        since = "4.15",
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class ReplaceLoadBalancerConfigsCmd extends BaseAsyncCmd {
+    public static final Logger LOGGER = Logger.getLogger(ReplaceLoadBalancerConfigsCmd.class.getName());
+    private static final String s_name = "replaceloadbalancerconfigsresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.SCOPE,
+               type = CommandType.STRING,
+               required = true,
+               description = "the scope of the config: network, vpc or rule")
+    private String scope;
+
+    @Parameter(name = ApiConstants.NETWORK_ID,
+               type = CommandType.UUID,
+               entityType = NetworkResponse.class,
+               description = "the ID of network to update")
+    private Long networkId;
+
+    @Parameter(name = ApiConstants.VPC_ID,
+               type = CommandType.UUID,
+               entityType = VpcResponse.class,
+               description = "the ID of vpc to update")
+    private Long vpcId;
+
+    @Parameter(name = ApiConstants.LOAD_BALANCER_ID,
+               type = CommandType.UUID,
+               entityType = FirewallRuleResponse.class,
+               description = "the ID of the load balancer rule to update")
+    private Long loadBalancerId;
+
+    @Parameter(name = ApiConstants.CONFIG,
+               type = CommandType.MAP,
+               description = "configs list, Example: config[0].global.maxconn=40960")
+    private Map<String, String> configList;
+
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getScope() {
+        return scope;
+    }
+
+    public Long getVpcId() {
+        return vpcId;
+    }
+
+    public Long getNetworkId() {
+        return networkId;
+    }
+
+    public Long getLoadBalancerId() {
+        return loadBalancerId;
+    }
+
+    public Map<String, String> getConfigList() {
+        if (configList == null || configList.isEmpty()) {
+            return null;
+        }
+
+        Collection<String> paramsCollection = configList.values();
+        return (Map<String, String>) (paramsCollection.toArray())[0];
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public void execute() {
+        List<? extends LoadBalancerConfig> configs = _lbConfigService.replaceLoadBalancerConfigs(this);
+        SuccessResponse response = new SuccessResponse(getCommandName());
+        this.setResponseObject(response);
+    }
+
+    @Override
+    public String getSyncObjType() {
+        if (networkId != null) {
+            return BaseAsyncCmd.networkSyncObject;
+        } else if (vpcId != null) {
+            return BaseAsyncCmd.vpcSyncObject;
+        }
+        return null;
+    }
+
+    @Override
+    public Long getSyncObjId() {
+        if (networkId != null) {
+            return networkId;
+        } else if (vpcId != null) {
+            return vpcId;
+        }
+        return null;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        if (networkId != null) {
+            Network network = _entityMgr.findById(Network.class, networkId);
+            if (network != null) {
+                return network.getAccountId();
+            }
+        } else if (vpcId != null) {
+            Vpc vpc = _entityMgr.findById(Vpc.class, vpcId);
+            if (vpc != null) {
+                return vpc.getAccountId();
+            }

Review comment:
       We could add this code to the helper that I mentioned before.

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLoadBalancerConfigCmd.java
##########
@@ -0,0 +1,148 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.LoadBalancerConfigResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "deleteLoadBalancerConfig", description = "Deletes a load balancer config.",
+        responseObject = SuccessResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        since = "4.15",
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class DeleteLoadBalancerConfigCmd extends BaseAsyncCmd {
+    public static final Logger LOGGER = Logger.getLogger(DeleteLoadBalancerConfigCmd.class.getName());
+    private static final String s_name = "deleteloadbalancerconfigresponse";
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID,
+               type = CommandType.UUID,
+               entityType = LoadBalancerConfigResponse.class,
+               required = true,
+               description = "the ID of the load balancer config")
+    private Long id;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public void execute() {
+        boolean result = _lbConfigService.deleteLoadBalancerConfig(this);
+
+        if (result) {
+            SuccessResponse response = new SuccessResponse(getCommandName());
+            this.setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete load balancer config");
+        }
+    }
+
+    @Override
+    public String getSyncObjType() {
+        LoadBalancerConfig config = _entityMgr.findById(LoadBalancerConfig.class, getId());
+        if (config == null) {
+            throw new InvalidParameterValueException("Unable to find load balancer config: " + id);
+        }
+        if (config.getNetworkId() != null) {
+            return BaseAsyncCmd.networkSyncObject;
+        } else if (config.getVpcId() != null) {
+            return BaseAsyncCmd.vpcSyncObject;
+        }
+        return null;

Review comment:
       This code is repeated along some classes, e.g. https://github.com/apache/cloudstack/blob/4125854da3d4ab815bcfeefaae18aee5dc69d1eb/api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerConfigCmd.java#L167-L173
   
   We could unify them in a helper. As well as some others code that are repeated.

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/ReplaceLoadBalancerConfigsCmd.java
##########
@@ -0,0 +1,173 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "replaceLoadBalancerConfigs", description = "Replaces load balancer configs of vpc/network/rule",
+        responseObject = SuccessResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        since = "4.15",
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class ReplaceLoadBalancerConfigsCmd extends BaseAsyncCmd {
+    public static final Logger LOGGER = Logger.getLogger(ReplaceLoadBalancerConfigsCmd.class.getName());
+    private static final String s_name = "replaceloadbalancerconfigsresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.SCOPE,
+               type = CommandType.STRING,
+               required = true,
+               description = "the scope of the config: network, vpc or rule")
+    private String scope;
+
+    @Parameter(name = ApiConstants.NETWORK_ID,
+               type = CommandType.UUID,
+               entityType = NetworkResponse.class,
+               description = "the ID of network to update")
+    private Long networkId;
+
+    @Parameter(name = ApiConstants.VPC_ID,
+               type = CommandType.UUID,
+               entityType = VpcResponse.class,
+               description = "the ID of vpc to update")
+    private Long vpcId;
+
+    @Parameter(name = ApiConstants.LOAD_BALANCER_ID,
+               type = CommandType.UUID,
+               entityType = FirewallRuleResponse.class,
+               description = "the ID of the load balancer rule to update")
+    private Long loadBalancerId;
+
+    @Parameter(name = ApiConstants.CONFIG,
+               type = CommandType.MAP,
+               description = "configs list, Example: config[0].global.maxconn=40960")
+    private Map<String, String> configList;
+
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getScope() {
+        return scope;
+    }
+
+    public Long getVpcId() {
+        return vpcId;
+    }
+
+    public Long getNetworkId() {
+        return networkId;
+    }
+
+    public Long getLoadBalancerId() {
+        return loadBalancerId;
+    }
+
+    public Map<String, String> getConfigList() {
+        if (configList == null || configList.isEmpty()) {

Review comment:
       We could use `org.apache.commons.collections.MapUtils` here:
   
   ```java
   ...
   if (MapUtils.isEmpty(configList)) {
   ...
   ```

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/UpdateLoadBalancerConfigCmd.java
##########
@@ -0,0 +1,156 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.LoadBalancerConfigResponse;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "updateLoadBalancerConfig", description = "Updates a load balancer config",
+        responseObject = LoadBalancerConfigResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        since = "4.15",
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class UpdateLoadBalancerConfigCmd extends BaseAsyncCmd {
+    public static final Logger LOGGER = Logger.getLogger(UpdateLoadBalancerConfigCmd.class.getName());
+    private static final String s_name = "updateloadbalancerconfigresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID,
+               type = CommandType.UUID,
+               entityType = LoadBalancerConfigResponse.class,
+               required = true,
+               description = "the ID of the load balancer config to update")
+    private Long id;
+
+    @Parameter(name = ApiConstants.VALUE,
+               type = CommandType.STRING,
+               required = true,
+               description = "value of the load balancer config")
+    private String value;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public void execute() {
+        LoadBalancerConfig result = _lbConfigService.updateLoadBalancerConfig(this);
+        if (result != null) {
+            LoadBalancerConfigResponse response = _responseGenerator.createLoadBalancerConfigResponse(result);
+            response.setResponseName(getCommandName());
+            this.setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update load balancer config");
+        }
+    }
+
+    @Override
+    public String getSyncObjType() {
+        LoadBalancerConfig config = _entityMgr.findById(LoadBalancerConfig.class, getId());
+        if (config == null) {
+            throw new InvalidParameterValueException("Unable to find load balancer config: " + id);
+        }
+        if (config.getNetworkId() != null) {
+            return BaseAsyncCmd.networkSyncObject;
+        } else if (config.getVpcId() != null) {
+            return BaseAsyncCmd.vpcSyncObject;
+        }
+        return null;

Review comment:
       We could add this code to the helper that I mentioned before.

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerConfigCmd.java
##########
@@ -0,0 +1,216 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.LoadBalancerConfigResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig.Scope;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.rules.LoadBalancer;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "createLoadBalancerConfig", description = "Creates a load balancer config",
+        responseObject = LoadBalancerConfigResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        since = "4.15",
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class CreateLoadBalancerConfigCmd extends BaseAsyncCreateCmd {
+    public static final Logger LOGGER = Logger.getLogger(CreateLoadBalancerConfigCmd.class.getName());
+
+    private static final String s_name = "createloadbalancerconfigresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.SCOPE,
+               type = CommandType.STRING,
+               required = true,
+               description = "the scope of the config: network, vpc or rule")
+    private String scope;
+
+    @Parameter(name = ApiConstants.NETWORK_ID,
+               type = CommandType.UUID,
+               entityType = NetworkResponse.class,
+               description = "the ID of network to update")
+    private Long networkId;
+
+    @Parameter(name = ApiConstants.VPC_ID,
+               type = CommandType.UUID,
+               entityType = VpcResponse.class,
+               description = "the ID of vpc to update")
+    private Long vpcId;
+
+    @Parameter(name = ApiConstants.LOAD_BALANCER_ID,
+               type = CommandType.UUID,
+               entityType = FirewallRuleResponse.class,
+               description = "the ID of the load balancer rule to update")
+    private Long loadBalancerId;
+
+    @Parameter(name = ApiConstants.NAME,
+               type = CommandType.STRING,
+               required = true,
+               description = "name of the load balancer config")
+    private String name;
+
+    @Parameter(name = ApiConstants.VALUE,
+               type = CommandType.STRING,
+               required = true,
+               description = "value of the load balancer config")
+    private String value;
+
+    @Parameter(name = ApiConstants.FORCED,
+               type = CommandType.BOOLEAN,
+               required = false,
+               description = "Force add a load balancer config. Existing config will be removed")
+    private Boolean forced;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getScope() {
+        return scope;
+    }
+
+    public Long getVpcId() {
+        return vpcId;
+    }
+
+    public Long getNetworkId() {
+        return networkId;
+    }
+
+    public Long getLoadBalancerId() {
+        return loadBalancerId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public boolean isForced() {
+        return (forced != null) ? forced : false;

Review comment:
       We could use `org.apache.commons.lang3.BooleanUtils` here:
   
   ```java
   ...
   return BooleanUtils.toBoolean(forced);
   ...
   ```

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/ReplaceLoadBalancerConfigsCmd.java
##########
@@ -0,0 +1,173 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "replaceLoadBalancerConfigs", description = "Replaces load balancer configs of vpc/network/rule",
+        responseObject = SuccessResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        since = "4.15",
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class ReplaceLoadBalancerConfigsCmd extends BaseAsyncCmd {
+    public static final Logger LOGGER = Logger.getLogger(ReplaceLoadBalancerConfigsCmd.class.getName());
+    private static final String s_name = "replaceloadbalancerconfigsresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.SCOPE,
+               type = CommandType.STRING,
+               required = true,
+               description = "the scope of the config: network, vpc or rule")
+    private String scope;
+
+    @Parameter(name = ApiConstants.NETWORK_ID,
+               type = CommandType.UUID,
+               entityType = NetworkResponse.class,
+               description = "the ID of network to update")
+    private Long networkId;
+
+    @Parameter(name = ApiConstants.VPC_ID,
+               type = CommandType.UUID,
+               entityType = VpcResponse.class,
+               description = "the ID of vpc to update")
+    private Long vpcId;
+
+    @Parameter(name = ApiConstants.LOAD_BALANCER_ID,
+               type = CommandType.UUID,
+               entityType = FirewallRuleResponse.class,
+               description = "the ID of the load balancer rule to update")
+    private Long loadBalancerId;
+
+    @Parameter(name = ApiConstants.CONFIG,
+               type = CommandType.MAP,
+               description = "configs list, Example: config[0].global.maxconn=40960")
+    private Map<String, String> configList;
+
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getScope() {
+        return scope;
+    }
+
+    public Long getVpcId() {
+        return vpcId;
+    }
+
+    public Long getNetworkId() {
+        return networkId;
+    }
+
+    public Long getLoadBalancerId() {
+        return loadBalancerId;
+    }
+
+    public Map<String, String> getConfigList() {
+        if (configList == null || configList.isEmpty()) {
+            return null;
+        }
+
+        Collection<String> paramsCollection = configList.values();
+        return (Map<String, String>) (paramsCollection.toArray())[0];
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public void execute() {
+        List<? extends LoadBalancerConfig> configs = _lbConfigService.replaceLoadBalancerConfigs(this);
+        SuccessResponse response = new SuccessResponse(getCommandName());
+        this.setResponseObject(response);
+    }
+
+    @Override
+    public String getSyncObjType() {
+        if (networkId != null) {
+            return BaseAsyncCmd.networkSyncObject;
+        } else if (vpcId != null) {
+            return BaseAsyncCmd.vpcSyncObject;
+        }
+        return null;

Review comment:
       We could add this code to the helper that I mentioned before.

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerConfigCmd.java
##########
@@ -0,0 +1,216 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.LoadBalancerConfigResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig.Scope;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.rules.LoadBalancer;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "createLoadBalancerConfig", description = "Creates a load balancer config",
+        responseObject = LoadBalancerConfigResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        since = "4.15",
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class CreateLoadBalancerConfigCmd extends BaseAsyncCreateCmd {
+    public static final Logger LOGGER = Logger.getLogger(CreateLoadBalancerConfigCmd.class.getName());
+
+    private static final String s_name = "createloadbalancerconfigresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.SCOPE,
+               type = CommandType.STRING,
+               required = true,
+               description = "the scope of the config: network, vpc or rule")
+    private String scope;
+
+    @Parameter(name = ApiConstants.NETWORK_ID,
+               type = CommandType.UUID,
+               entityType = NetworkResponse.class,
+               description = "the ID of network to update")
+    private Long networkId;
+
+    @Parameter(name = ApiConstants.VPC_ID,
+               type = CommandType.UUID,
+               entityType = VpcResponse.class,
+               description = "the ID of vpc to update")
+    private Long vpcId;
+
+    @Parameter(name = ApiConstants.LOAD_BALANCER_ID,
+               type = CommandType.UUID,
+               entityType = FirewallRuleResponse.class,
+               description = "the ID of the load balancer rule to update")
+    private Long loadBalancerId;
+
+    @Parameter(name = ApiConstants.NAME,
+               type = CommandType.STRING,
+               required = true,
+               description = "name of the load balancer config")
+    private String name;
+
+    @Parameter(name = ApiConstants.VALUE,
+               type = CommandType.STRING,
+               required = true,
+               description = "value of the load balancer config")
+    private String value;
+
+    @Parameter(name = ApiConstants.FORCED,
+               type = CommandType.BOOLEAN,
+               required = false,
+               description = "Force add a load balancer config. Existing config will be removed")
+    private Boolean forced;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getScope() {
+        return scope;
+    }
+
+    public Long getVpcId() {
+        return vpcId;
+    }
+
+    public Long getNetworkId() {
+        return networkId;
+    }
+
+    public Long getLoadBalancerId() {
+        return loadBalancerId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public boolean isForced() {
+        return (forced != null) ? forced : false;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public void execute() {
+
+        LoadBalancerConfig config = null;
+        try {
+            config = _entityMgr.findById(LoadBalancerConfig.class, getEntityId());
+            LoadBalancerConfigResponse lbConfigResponse = new LoadBalancerConfigResponse();
+            if (config != null) {
+                lbConfigResponse = _responseGenerator.createLoadBalancerConfigResponse(config);
+                setResponseObject(lbConfigResponse);
+            }
+            lbConfigResponse.setResponseName(getCommandName());
+        } catch (Exception ex) {
+            LOGGER.warn("Failed to create LB config due to exception ", ex);
+        }
+    }
+
+    @Override
+    public void create() {
+        try {
+            LoadBalancerConfig result = _lbConfigService.createLoadBalancerConfig(this);
+            this.setEntityId(result.getId());
+            this.setEntityUuid(result.getUuid());
+        } catch (InvalidParameterValueException e) {
+            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage());
+        }
+    }
+
+    @Override
+    public String getSyncObjType() {
+        if (networkId != null) {
+            return BaseAsyncCmd.networkSyncObject;
+        } else if (vpcId != null) {
+            return BaseAsyncCmd.vpcSyncObject;
+        }
+        return null;
+    }
+
+    @Override
+    public Long getSyncObjId() {
+        if (networkId != null) {
+            return getNetworkId();
+        } else if (vpcId != null) {
+            return getVpcId();
+        }
+        return null;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        if (Scope.Network.name().equalsIgnoreCase(scope) && networkId != null) {
+            Network network = _entityMgr.findById(Network.class, networkId);
+            if (network != null) {
+                return network.getAccountId();
+            }
+        } else if (Scope.Vpc.name().equalsIgnoreCase(scope) && vpcId != null) {
+            Vpc vpc = _entityMgr.findById(Vpc.class, vpcId);
+            if (vpc != null) {
+                return vpc.getAccountId();
+            }
+        } else if (Scope.LoadBalancerRule.name().equalsIgnoreCase(scope) && loadBalancerId != null) {
+            LoadBalancer lb = _entityMgr.findById(LoadBalancer.class, loadBalancerId);
+            if (lb != null) {
+                return lb.getAccountId();
+            }
+        }

Review comment:
       This code is repeated, but changing parameters; We could extract it to a method.

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerConfigCmd.java
##########
@@ -0,0 +1,216 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.LoadBalancerConfigResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig.Scope;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.rules.LoadBalancer;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "createLoadBalancerConfig", description = "Creates a load balancer config",
+        responseObject = LoadBalancerConfigResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        since = "4.15",
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class CreateLoadBalancerConfigCmd extends BaseAsyncCreateCmd {
+    public static final Logger LOGGER = Logger.getLogger(CreateLoadBalancerConfigCmd.class.getName());
+
+    private static final String s_name = "createloadbalancerconfigresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.SCOPE,
+               type = CommandType.STRING,
+               required = true,
+               description = "the scope of the config: network, vpc or rule")
+    private String scope;
+
+    @Parameter(name = ApiConstants.NETWORK_ID,
+               type = CommandType.UUID,
+               entityType = NetworkResponse.class,
+               description = "the ID of network to update")
+    private Long networkId;
+
+    @Parameter(name = ApiConstants.VPC_ID,
+               type = CommandType.UUID,
+               entityType = VpcResponse.class,
+               description = "the ID of vpc to update")
+    private Long vpcId;
+
+    @Parameter(name = ApiConstants.LOAD_BALANCER_ID,
+               type = CommandType.UUID,
+               entityType = FirewallRuleResponse.class,
+               description = "the ID of the load balancer rule to update")
+    private Long loadBalancerId;
+
+    @Parameter(name = ApiConstants.NAME,
+               type = CommandType.STRING,
+               required = true,
+               description = "name of the load balancer config")
+    private String name;
+
+    @Parameter(name = ApiConstants.VALUE,
+               type = CommandType.STRING,
+               required = true,
+               description = "value of the load balancer config")
+    private String value;
+
+    @Parameter(name = ApiConstants.FORCED,
+               type = CommandType.BOOLEAN,
+               required = false,
+               description = "Force add a load balancer config. Existing config will be removed")
+    private Boolean forced;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getScope() {
+        return scope;
+    }
+
+    public Long getVpcId() {
+        return vpcId;
+    }
+
+    public Long getNetworkId() {
+        return networkId;
+    }
+
+    public Long getLoadBalancerId() {
+        return loadBalancerId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public boolean isForced() {
+        return (forced != null) ? forced : false;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public void execute() {
+
+        LoadBalancerConfig config = null;
+        try {
+            config = _entityMgr.findById(LoadBalancerConfig.class, getEntityId());
+            LoadBalancerConfigResponse lbConfigResponse = new LoadBalancerConfigResponse();
+            if (config != null) {
+                lbConfigResponse = _responseGenerator.createLoadBalancerConfigResponse(config);
+                setResponseObject(lbConfigResponse);
+            }
+            lbConfigResponse.setResponseName(getCommandName());
+        } catch (Exception ex) {
+            LOGGER.warn("Failed to create LB config due to exception ", ex);
+        }
+    }
+
+    @Override
+    public void create() {
+        try {
+            LoadBalancerConfig result = _lbConfigService.createLoadBalancerConfig(this);
+            this.setEntityId(result.getId());
+            this.setEntityUuid(result.getUuid());
+        } catch (InvalidParameterValueException e) {
+            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage());
+        }
+    }
+
+    @Override
+    public String getSyncObjType() {
+        if (networkId != null) {
+            return BaseAsyncCmd.networkSyncObject;
+        } else if (vpcId != null) {

Review comment:
       This `else` statement does not make difference here, we could remove it.

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/DeleteLoadBalancerConfigCmd.java
##########
@@ -0,0 +1,148 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.LoadBalancerConfigResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "deleteLoadBalancerConfig", description = "Deletes a load balancer config.",
+        responseObject = SuccessResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        since = "4.15",
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class DeleteLoadBalancerConfigCmd extends BaseAsyncCmd {
+    public static final Logger LOGGER = Logger.getLogger(DeleteLoadBalancerConfigCmd.class.getName());
+    private static final String s_name = "deleteloadbalancerconfigresponse";
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID,
+               type = CommandType.UUID,
+               entityType = LoadBalancerConfigResponse.class,
+               required = true,
+               description = "the ID of the load balancer config")
+    private Long id;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public void execute() {
+        boolean result = _lbConfigService.deleteLoadBalancerConfig(this);
+
+        if (result) {
+            SuccessResponse response = new SuccessResponse(getCommandName());
+            this.setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete load balancer config");
+        }
+    }
+
+    @Override
+    public String getSyncObjType() {
+        LoadBalancerConfig config = _entityMgr.findById(LoadBalancerConfig.class, getId());
+        if (config == null) {
+            throw new InvalidParameterValueException("Unable to find load balancer config: " + id);
+        }
+        if (config.getNetworkId() != null) {
+            return BaseAsyncCmd.networkSyncObject;
+        } else if (config.getVpcId() != null) {
+            return BaseAsyncCmd.vpcSyncObject;
+        }
+        return null;
+    }
+
+    @Override
+    public Long getSyncObjId() {
+        LoadBalancerConfig config = _entityMgr.findById(LoadBalancerConfig.class, getId());
+        if (config == null) {
+            throw new InvalidParameterValueException("Unable to find load balancer config: " + id);
+        }
+        if (config.getNetworkId() != null) {
+            return config.getNetworkId();
+        } else if (config.getVpcId() != null) {
+            return config.getVpcId();
+        }
+        return null;

Review comment:
       We could add this code to the helper that I mentioned before.

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/ReplaceLoadBalancerConfigsCmd.java
##########
@@ -0,0 +1,173 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "replaceLoadBalancerConfigs", description = "Replaces load balancer configs of vpc/network/rule",
+        responseObject = SuccessResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        since = "4.15",
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class ReplaceLoadBalancerConfigsCmd extends BaseAsyncCmd {
+    public static final Logger LOGGER = Logger.getLogger(ReplaceLoadBalancerConfigsCmd.class.getName());
+    private static final String s_name = "replaceloadbalancerconfigsresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.SCOPE,
+               type = CommandType.STRING,
+               required = true,
+               description = "the scope of the config: network, vpc or rule")
+    private String scope;
+
+    @Parameter(name = ApiConstants.NETWORK_ID,
+               type = CommandType.UUID,
+               entityType = NetworkResponse.class,
+               description = "the ID of network to update")
+    private Long networkId;
+
+    @Parameter(name = ApiConstants.VPC_ID,
+               type = CommandType.UUID,
+               entityType = VpcResponse.class,
+               description = "the ID of vpc to update")
+    private Long vpcId;
+
+    @Parameter(name = ApiConstants.LOAD_BALANCER_ID,
+               type = CommandType.UUID,
+               entityType = FirewallRuleResponse.class,
+               description = "the ID of the load balancer rule to update")
+    private Long loadBalancerId;
+
+    @Parameter(name = ApiConstants.CONFIG,
+               type = CommandType.MAP,
+               description = "configs list, Example: config[0].global.maxconn=40960")
+    private Map<String, String> configList;
+
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getScope() {
+        return scope;
+    }
+
+    public Long getVpcId() {
+        return vpcId;
+    }
+
+    public Long getNetworkId() {
+        return networkId;
+    }
+
+    public Long getLoadBalancerId() {
+        return loadBalancerId;
+    }
+
+    public Map<String, String> getConfigList() {
+        if (configList == null || configList.isEmpty()) {
+            return null;
+        }
+
+        Collection<String> paramsCollection = configList.values();
+        return (Map<String, String>) (paramsCollection.toArray())[0];
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public void execute() {
+        List<? extends LoadBalancerConfig> configs = _lbConfigService.replaceLoadBalancerConfigs(this);
+        SuccessResponse response = new SuccessResponse(getCommandName());
+        this.setResponseObject(response);
+    }
+
+    @Override
+    public String getSyncObjType() {
+        if (networkId != null) {
+            return BaseAsyncCmd.networkSyncObject;
+        } else if (vpcId != null) {
+            return BaseAsyncCmd.vpcSyncObject;
+        }
+        return null;
+    }
+
+    @Override
+    public Long getSyncObjId() {
+        if (networkId != null) {
+            return networkId;
+        } else if (vpcId != null) {
+            return vpcId;
+        }
+        return null;

Review comment:
       We could add this code to the helper that I mentioned before.

##########
File path: api/src/main/java/org/apache/cloudstack/network/lb/LoadBalancerConfigKey.java
##########
@@ -0,0 +1,221 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.network.lb;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.cloudstack.network.lb.LoadBalancerConfig.SSLConfiguration;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig.Scope;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.cloud.utils.Pair;
+
+public enum LoadBalancerConfigKey {
+
+    LbStatsEnable(Category.Stats, "lb.stats.enable", "LB stats enable", Boolean.class, "true", "Enable statistics reporting with default settings, default is 'true'", Scope.Network, Scope.Vpc),
+
+    LbStatsUri(Category.Stats, "lb.stats.uri", "LB stats URI", String.class, "/admin?stats", "Enable statistics and define the URI prefix to access them, default is '/admin?stats'", Scope.Network, Scope.Vpc),
+
+    LbStatsAuth(Category.Stats, "lb.stats.auth", "LB stats auth", String.class, "admin1:AdMiN123", "Enable statistics with authentication and grant access to an account, default is 'admin1:AdMiN123'", Scope.Network, Scope.Vpc),
+
+    GlobalStatsSocket(Category.Stats, "global.stats.socket", "Stats socket enabled/disabled", Boolean.class, "false", "Binds a UNIX socket to /var/run/haproxy.socket, default is 'false'", Scope.Network, Scope.Vpc),
+
+    LbTimeoutConnect(Category.General, "lb.timeout.connect", "Maximum time (in ms) to wait for a connection to succeed", Long.class, "5000", "Set the maximum time to wait for a connection attempt to a server to succeed.", Scope.Network, Scope.Vpc, Scope.LoadBalancerRule),
+
+    LbTimeoutServer(Category.General, "lb.timeout.server", "Maximum inactivity time (in ms) on server side", Long.class, "50000", "Set the maximum inactivity time on the server side.", Scope.Network, Scope.Vpc, Scope.LoadBalancerRule),
+
+    LbTimeoutClient(Category.General, "lb.timeout.client", "Maximum inactivity time (in ms) on client side", Long.class, "50000", "Set the maximum inactivity time on the client side.", Scope.Network, Scope.Vpc, Scope.LoadBalancerRule),
+
+    LbHttp(Category.LoadBalancer, "lb.http", "LB http enabled/disabled", Boolean.class, "true for port 80; false for other ports", "If LB is http, default is 'true' for port 80 and 'false' for others'", Scope.LoadBalancerRule),
+
+    LbHttp2(Category.LoadBalancer, "lb.http2", "Enable/disable HTTP2 support", Boolean.class, "false", "Enable or disable HTTP2 support in HAproxy", Scope.LoadBalancerRule),
+
+    LbHttpKeepalive(Category.LoadBalancer, "lb.http.keepalive", "LB http keepalive enabled/disabled", Boolean.class, "<Inherited from network offering>", "Enable or disable HTTP keep-alive, default is inherited from network offering", Scope.LoadBalancerRule),
+
+    LbBackendHttps(Category.LoadBalancer, "lb.backend.https", "If backend server is https", Boolean.class, "false", "If backend server is https. If yes, use 'check ssl verify none' instead of 'check'", Scope.LoadBalancerRule),
+
+    LbTransparent(Category.LoadBalancer, "lb.transparent.mode", "LB transparent mode enabled/disabled", Boolean.class, "false", "Enable or disable transparent mode, default is 'false'", Scope.LoadBalancerRule),
+
+    GlobalMaxConn(Category.LoadBalancer, "global.maxconn", "LB max connection", Long.class, "4096", "Maximum per process number of concurrent connections, default is '4096'", Scope.Network, Scope.Vpc),
+
+    GlobalMaxPipes(Category.LoadBalancer, "global.maxpipes", "LB max pipes", Long.class, "<global.maxconn/4>", "Maximum number of per process pipes, default is 'maxconn/4'", Scope.Network, Scope.Vpc),
+
+    LbMaxConn(Category.LoadBalancer, "lb.maxconn", "LB max connection", Long.class, "<2000 in haproxy>", "Maximum per process number of concurrent connections per site/vm", Scope.LoadBalancerRule),
+
+    LbFullConn(Category.LoadBalancer, "lb.fullconn", "LB full connection", Long.class, "<maxconn/10 in haproxy>", "Specify at what backend load the servers will reach their maxconn, default is 'maxconn/10'", Scope.LoadBalancerRule),
+
+    LbServerMaxConn(Category.LoadBalancer, "lb.server.maxconn", "LB max connection per server", Long.class, "<0 means unlimited in haproxy>", "LB max connection per server, default is ''", Scope.LoadBalancerRule),
+
+    LbServerMinConn(Category.LoadBalancer, "lb.server.minconn", "LB minimum connection per server", Long.class, "", "LB minimum connection per server, default is ''", Scope.LoadBalancerRule),
+
+    LbServerMaxQueue(Category.LoadBalancer, "lb.server.maxqueue", "Max conn wait in queue per server", Long.class, "<0 means unlimited in haproxy>", "Maximum number of connections which will wait in queue for this server, default is ''", Scope.LoadBalancerRule),
+
+    LbSslConfiguration(Category.LoadBalancer, "lb.ssl.configuration", "SSL configuration, could be 'none', 'old' or 'intermediate'", String.class, "Inherited from global setting" , "if 'none', no SSL configurations will be added, if 'old', refer to https://ssl-config.mozilla.org/#server=haproxy&server-version=1.8.17&config=old&openssl-version=1.0.2l if 'intermediate', refer to https://ssl-config.mozilla.org/#server=haproxy&server-version=1.8.17&config=intermediate&openssl-version=1.0.2l default value is 'none'", Scope.LoadBalancerRule);
+
+    public static enum Category {
+        General, Advanced, Stats, LoadBalancer
+    }
+
+    private final Category _category;
+    private final Scope[] _scope;
+    private final String _key;
+    private final String _displayText;
+    private final String _description;
+    private final Class<?> _type;
+    private final String _defaultValue;
+
+    private LoadBalancerConfigKey(Category category, String key, String displayText, Class<?> type, String defaultValue, String description, Scope... scope) {
+        _category = category;
+        _scope = scope;
+        _key = key;
+        _displayText = displayText;
+        _type = type;
+        _defaultValue = defaultValue;
+        _description = description;
+    }
+
+    public Category category() {
+        return _category;
+    }
+
+    public Class<?> type() {
+        return _type;
+    }
+
+    public String key() {
+        return _key;
+    }
+
+    public String displayText() {
+        return _displayText;
+    }
+
+    public String defaultValue() {
+        return _defaultValue;
+    }
+
+    public String description() {
+        return _description;
+    }
+
+    public Scope[] scope() {
+        return _scope;
+    }
+
+    @Override
+    public String toString() {
+        return _key;
+    }
+
+    private static final HashMap<Scope, Map<String, LoadBalancerConfigKey>> Configs = new HashMap<Scope, Map<String, LoadBalancerConfigKey>>();
+    static {
+        Configs.put(Scope.Network, new LinkedHashMap<String, LoadBalancerConfigKey>());
+        Configs.put(Scope.Vpc, new LinkedHashMap<String, LoadBalancerConfigKey>());
+        Configs.put(Scope.LoadBalancerRule, new LinkedHashMap<String, LoadBalancerConfigKey>());
+        for (LoadBalancerConfigKey c : LoadBalancerConfigKey.values()) {
+            Scope[] scopes = c.scope();
+            for (Scope scope : scopes) {
+                Map<String, LoadBalancerConfigKey> currentConfigs = Configs.get(scope);
+                currentConfigs.put(c.key(), c);
+                Configs.put(scope, currentConfigs);
+            }
+        }
+    }
+
+    public static Map<String, LoadBalancerConfigKey> getConfigsByScope(Scope scope) {
+        return Configs.get(scope);
+    }
+
+    public static LoadBalancerConfigKey getConfigsByScopeAndName(Scope scope, String name) {
+        Map<String, LoadBalancerConfigKey> configs = Configs.get(scope);
+        if (configs.keySet().contains(name)) {
+            return configs.get(name);
+        }
+        return null;

Review comment:
       The `get` method already returns `null` if the map does not contains the key, so we can remove this validation.

##########
File path: core/src/main/java/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java
##########
@@ -72,4 +81,36 @@ public NicTO getNic() {
     public Long getVpcId() {
         return vpcId;
     }
+
+    public LoadBalancerConfigTO[] getNetworkLbConfigs() {
+        return this.networkLbConfigs;
+    }
+
+    public void setNetworkLbConfigs(List<? extends LoadBalancerConfig> networkLbConfigs) {
+        if (networkLbConfigs == null || networkLbConfigs.size() == 0) {

Review comment:
       We could use `org.apache.commons.lang3.ArrayUtils` here:
   
   ```java
   ...
   if (ArrayUtils.isEmpty(networkLbConfigs)) {
   ...
   ```

##########
File path: core/src/main/java/com/cloud/network/HAProxyConfigurator.java
##########
@@ -505,8 +601,35 @@ private String getLbSubRuleForStickiness(final LoadBalancerTO lbTO) {
             .append(" ")
             .append(dest.getDestIp())
             .append(":")
-            .append(dest.getDestPort())
-            .append(" check");
+            .append(dest.getDestPort());
+            if ("true".equalsIgnoreCase(lbConfigsMap.get(LoadBalancerConfigKey.LbBackendHttps.key()))) {
+                sb.append(" check ssl verify none");
+            } else {
+                sb.append(" check");
+            }
+
+            if (sslOffloading) {
+                sb.append(getCustomizedSslConfigs(lbConfigsMap, lbCmd));
+            }
+
+            if (lbConfigsMap.get(LoadBalancerConfigKey.LbServerMaxConn.key()) != null) {
+                long maxConnEach = Long.parseLong(lbConfigsMap.get(LoadBalancerConfigKey.LbServerMaxConn.key()));
+                if (maxConnEach > 0) {
+                    sb.append(" maxconn ").append(maxConnEach);
+                }
+            }
+            if (lbConfigsMap.get(LoadBalancerConfigKey.LbServerMinConn.key()) != null) {
+                long minConnEach = Long.parseLong(lbConfigsMap.get(LoadBalancerConfigKey.LbServerMinConn.key()));
+                if (minConnEach > 0) {
+                    sb.append(" minconn ").append(minConnEach);
+                }
+            }
+            if (lbConfigsMap.get(LoadBalancerConfigKey.LbServerMaxQueue.key()) != null) {
+                long maxQueueEach = Long.parseLong(lbConfigsMap.get(LoadBalancerConfigKey.LbServerMaxQueue.key()));
+                if (maxQueueEach > 0) {
+                    sb.append(" maxqueue ").append(maxQueueEach);
+                }
+            }

Review comment:
       This code seems repeated, but changing parameters; We could extract it to a method.

##########
File path: core/src/main/java/com/cloud/network/HAProxyConfigurator.java
##########
@@ -531,42 +654,111 @@ private String getLbSubRuleForStickiness(final LoadBalancerTO lbTO) {
                 }
             }
             if (httpbasedStickiness) {
-                result.addAll(dstWithCookieSubRule);
+                backendConfigs.addAll(dstWithCookieSubRule);
             } else {
-                result.addAll(dstSubRule);
+                backendConfigs.addAll(dstSubRule);
             }
-            result.add(stickinessSubRule);
+            backendConfigs.add(stickinessSubRule);
         } else {
-            result.addAll(dstSubRule);
+            backendConfigs.addAll(dstSubRule);
         }
         if (stickinessSubRule != null && !destsAvailable) {
             s_logger.warn("Haproxy stickiness policy for lb rule: " + lbTO.getSrcIp() + ":" + lbTO.getSrcPort() + ": Not Applied, cause:  backends are unavailable");
         }
-        if (publicPort == NetUtils.HTTP_PORT && !keepAliveEnabled || httpbasedStickiness) {
+        boolean http = false;
+        String cfgLbHttp = lbConfigsMap.get(LoadBalancerConfigKey.LbHttp.key());
+        if (publicPort == NetUtils.HTTP_PORT && cfgLbHttp == null) {
+            http = true;
+        } else if (cfgLbHttp != null && cfgLbHttp.equalsIgnoreCase("true")) {
+            http = true;
+        }
+
+        boolean keepAliveEnabled = lbCmd.keepAliveEnabled;
+        String cfgLbHttpKeepalive = lbConfigsMap.get(LoadBalancerConfigKey.LbHttpKeepalive.key());
+        if (cfgLbHttpKeepalive != null && cfgLbHttpKeepalive.equalsIgnoreCase("true")) {
+            keepAliveEnabled = true;
+        } else if (cfgLbHttpKeepalive != null && cfgLbHttpKeepalive.equalsIgnoreCase("false")) {
+            keepAliveEnabled = false;
+        }
+
+        if (http || httpbasedStickiness || sslOffloading) {
             sb = new StringBuilder();
             sb.append("\t").append("mode http");
+            frontendConfigs.add(sb.toString());
+            backendConfigsForHttp.add(sb.toString());
+            if (keepAliveEnabled) {
+                sb = new StringBuilder();
+                sb.append("\t").append("no option forceclose");
+                frontendConfigs.add(sb.toString());
+                backendConfigsForHttp.add(sb.toString());
+            } else {
+                sb = new StringBuilder();
+                sb.append("\t").append("option httpclose");
+                frontendConfigs.add(sb.toString());
+                backendConfigsForHttp.add(sb.toString());
+            }

Review comment:
       This code seems repeated, but changing parameters; We could extract it to a method.

##########
File path: core/src/main/java/com/cloud/network/HAProxyConfigurator.java
##########
@@ -531,42 +654,111 @@ private String getLbSubRuleForStickiness(final LoadBalancerTO lbTO) {
                 }
             }
             if (httpbasedStickiness) {
-                result.addAll(dstWithCookieSubRule);
+                backendConfigs.addAll(dstWithCookieSubRule);
             } else {
-                result.addAll(dstSubRule);
+                backendConfigs.addAll(dstSubRule);
             }
-            result.add(stickinessSubRule);
+            backendConfigs.add(stickinessSubRule);
         } else {
-            result.addAll(dstSubRule);
+            backendConfigs.addAll(dstSubRule);
         }
         if (stickinessSubRule != null && !destsAvailable) {
             s_logger.warn("Haproxy stickiness policy for lb rule: " + lbTO.getSrcIp() + ":" + lbTO.getSrcPort() + ": Not Applied, cause:  backends are unavailable");
         }
-        if (publicPort == NetUtils.HTTP_PORT && !keepAliveEnabled || httpbasedStickiness) {
+        boolean http = false;
+        String cfgLbHttp = lbConfigsMap.get(LoadBalancerConfigKey.LbHttp.key());
+        if (publicPort == NetUtils.HTTP_PORT && cfgLbHttp == null) {
+            http = true;
+        } else if (cfgLbHttp != null && cfgLbHttp.equalsIgnoreCase("true")) {
+            http = true;
+        }
+
+        boolean keepAliveEnabled = lbCmd.keepAliveEnabled;
+        String cfgLbHttpKeepalive = lbConfigsMap.get(LoadBalancerConfigKey.LbHttpKeepalive.key());
+        if (cfgLbHttpKeepalive != null && cfgLbHttpKeepalive.equalsIgnoreCase("true")) {
+            keepAliveEnabled = true;
+        } else if (cfgLbHttpKeepalive != null && cfgLbHttpKeepalive.equalsIgnoreCase("false")) {
+            keepAliveEnabled = false;
+        }
+
+        if (http || httpbasedStickiness || sslOffloading) {
             sb = new StringBuilder();
             sb.append("\t").append("mode http");
+            frontendConfigs.add(sb.toString());
+            backendConfigsForHttp.add(sb.toString());
+            if (keepAliveEnabled) {
+                sb = new StringBuilder();
+                sb.append("\t").append("no option forceclose");
+                frontendConfigs.add(sb.toString());
+                backendConfigsForHttp.add(sb.toString());
+            } else {
+                sb = new StringBuilder();
+                sb.append("\t").append("option httpclose");
+                frontendConfigs.add(sb.toString());
+                backendConfigsForHttp.add(sb.toString());
+            }
+        }
+
+        if (isTransparent) {
+            sb = new StringBuilder();
+            sb.append("frontend ").append(poolName);
             result.add(sb.toString());
+            result.addAll(frontendConfigs);
             sb = new StringBuilder();
-            sb.append("\t").append("option httpclose");
+            sb.append("\tacl local_subnet src ").append(lbCmd.getNetworkCidr());
+            sb.append("\n\tuse_backend ").append(poolName).append("-backend-local if local_subnet");
+            sb.append("\n\tdefault_backend ").append(poolName).append("-backend");
+            sb.append("\n\n");
+            sb.append("backend ").append(poolName).append("-backend");
+            result.add(sb.toString());
+            result.addAll(backendConfigsForHttp);
+            result.addAll(backendConfigs);
+            sb = new StringBuilder();
+            sb.append("\t").append("source 0.0.0.0 usesrc clientip");
+            sb.append("\n\n");
+            sb.append("backend ").append(poolName).append("-backend-local");
             result.add(sb.toString());
+            result.addAll(backendConfigsForHttp);
+            result.addAll(backendConfigs);
+        } else {
+            // add line like this: "listen  65_37_141_30-80\n\tbind 65.37.141.30:80"
+            sb = new StringBuilder();
+            sb.append("listen ").append(poolName);

Review comment:
       Instead of using `StringBuilder`, we could use `String.format`, it is more clean and readable.

##########
File path: core/src/main/java/com/cloud/network/HAProxyConfigurator.java
##########
@@ -467,24 +484,103 @@ private String getLbSubRuleForStickiness(final LoadBalancerTO lbTO) {
         return sb.toString();
     }
 
-    private List<String> getRulesForPool(final LoadBalancerTO lbTO, final boolean keepAliveEnabled) {
+    private String getCustomizedSslConfigs(HashMap<String, String> lbConfigsMap, final LoadBalancerConfigCommand lbCmd){
+        String lbSslConfiguration = lbConfigsMap.get(LoadBalancerConfigKey.LbSslConfiguration.key());
+        if (lbSslConfiguration == null) {
+            lbSslConfiguration = lbCmd.lbSslConfiguration;
+        }
+        if (SSLConfiguration.OLD.toString().equalsIgnoreCase(lbSslConfiguration)) {
+            return sslConfigurationOld;
+        } else if (SSLConfiguration.INTERMEDIATE.toString().equalsIgnoreCase(lbSslConfiguration)) {
+            return sslConfigurationIntermediate;
+        }
+        return "";
+    }
+
+    private List<String> getRulesForPool(final LoadBalancerTO lbTO, final LoadBalancerConfigCommand lbCmd, HashMap<String, String> networkLbConfigsMap) {
         StringBuilder sb = new StringBuilder();
         final String poolName = sb.append(lbTO.getSrcIp().replace(".", "_")).append('-').append(lbTO.getSrcPort()).toString();
         final String publicIP = lbTO.getSrcIp();
         final int publicPort = lbTO.getSrcPort();
         final String algorithm = lbTO.getAlgorithm();
 
+        final LoadBalancerConfigTO[] lbConfigs = lbTO.getLbConfigs();
+        final HashMap<String, String> lbConfigsMap = new HashMap<String, String>();
+        if (lbConfigs != null) {
+            for (LoadBalancerConfigTO lbConfig: lbConfigs) {
+                lbConfigsMap.put(lbConfig.getName(), lbConfig.getValue());
+            }
+        }
+
+        boolean isTransparent = false;
+        if ("true".equalsIgnoreCase(lbConfigsMap.get(LoadBalancerConfigKey.LbTransparent.key()))) {
+            isTransparent = true;
+        }
+
+        boolean sslOffloading = false;
+        if (lbTO.getSslCert() != null && ! lbTO.getSslCert().isRevoked()
+                && lbTO.getLbProtocol() != null && lbTO.getLbProtocol().equals(NetUtils.SSL_PROTO)) {
+            sslOffloading = true;
+        }
+
+        final List<String> frontendConfigs = new ArrayList<String>();
+        final List<String> backendConfigs = new ArrayList<String>();
+        final List<String> backendConfigsForHttp = new ArrayList<String>();
         final List<String> result = new ArrayList<String>();
-        // add line like this: "listen  65_37_141_30-80\n\tbind 65.37.141.30:80"
-        sb = new StringBuilder();
-        sb.append("listen ").append(poolName);
-        result.add(sb.toString());
+
         sb = new StringBuilder();
         sb.append("\tbind ").append(publicIP).append(":").append(publicPort);
-        result.add(sb.toString());
+        if (sslOffloading) {
+            sb.append(" ssl crt ").append(SSL_CERTS_DIR).append(poolName).append(".pem");
+            // check for http2 support
+            if ("true".equalsIgnoreCase(lbConfigsMap.get(LoadBalancerConfigKey.LbHttp2.key()))) {
+                sb.append(" alpn h2,http/1.1");
+            }
+
+            sb.append(getCustomizedSslConfigs(lbConfigsMap, lbCmd));
+
+            sb.append("\n\thttp-request add-header X-Forwarded-Proto https");
+        }
+        frontendConfigs.add(sb.toString());
         sb = new StringBuilder();
         sb.append("\t").append("balance ").append(algorithm);
-        result.add(sb.toString());
+        backendConfigs.add(sb.toString());
+
+        String timeoutConnect = lbConfigsMap.get(LoadBalancerConfigKey.LbTimeoutConnect.key());
+        if (timeoutConnect != null) {
+            sb = new StringBuilder();
+            sb.append("\t").append("timeout connect    " + timeoutConnect);
+            backendConfigs.add(sb.toString());
+        }
+        String timeoutClient = lbConfigsMap.get(LoadBalancerConfigKey.LbTimeoutClient.key());
+        if (timeoutClient != null) {
+            sb = new StringBuilder();
+            sb.append("\t").append("timeout client     " + timeoutClient);
+            frontendConfigs.add(sb.toString());
+        }
+        String timeoutServer = lbConfigsMap.get(LoadBalancerConfigKey.LbTimeoutServer.key());
+        if (timeoutServer != null) {
+            sb = new StringBuilder();
+            sb.append("\t").append("timeout server     " + timeoutServer);
+            backendConfigs.add(sb.toString());
+        }
+
+        if (lbConfigsMap.get(LoadBalancerConfigKey.LbMaxConn.key()) != null) {
+            long maxConnValue = Long.parseLong(lbConfigsMap.get(LoadBalancerConfigKey.LbMaxConn.key()));
+            if (maxConnValue > 0) {
+                sb = new StringBuilder();
+                sb.append("\tmaxconn ").append(maxConnValue);
+                frontendConfigs.add(sb.toString());
+            }
+        }
+        if (lbConfigsMap.get(LoadBalancerConfigKey.LbFullConn.key()) != null) {
+            long fullConnValue = Long.parseLong(lbConfigsMap.get(LoadBalancerConfigKey.LbFullConn.key()));
+            if (fullConnValue > 0) {
+                sb = new StringBuilder();
+                sb.append("\tfullconn ").append(fullConnValue);
+                backendConfigs.add(sb.toString());
+            }
+        }

Review comment:
       This code seems repeated, but changing parameters; We could extract it to a method.

##########
File path: engine/schema/src/main/java/com/cloud/network/dao/LoadBalancerConfigDaoImpl.java
##########
@@ -0,0 +1,163 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.network.dao;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.cloudstack.network.lb.LoadBalancerConfig.Scope;
+
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+import com.cloud.utils.db.TransactionLegacy;
+
+public class LoadBalancerConfigDaoImpl extends GenericDaoBase<LoadBalancerConfigVO, Long> implements LoadBalancerConfigDao {
+
+    final SearchBuilder<LoadBalancerConfigVO> AllFieldsSearch;
+
+    public LoadBalancerConfigDaoImpl() {
+        AllFieldsSearch = createSearchBuilder();
+        AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ);
+        AllFieldsSearch.and("ids", AllFieldsSearch.entity().getId(), Op.IN);
+        AllFieldsSearch.and("uuid", AllFieldsSearch.entity().getUuid(), Op.EQ);
+        AllFieldsSearch.and("scope", AllFieldsSearch.entity().getScope(), Op.EQ);
+        AllFieldsSearch.and("networkId", AllFieldsSearch.entity().getNetworkId(), Op.EQ);
+        AllFieldsSearch.and("vpcId", AllFieldsSearch.entity().getVpcId(), Op.EQ);
+        AllFieldsSearch.and("loadBalancerId", AllFieldsSearch.entity().getLoadBalancerId(), Op.EQ);
+        AllFieldsSearch.and("name", AllFieldsSearch.entity().getName(), Op.EQ);
+        AllFieldsSearch.and("value", AllFieldsSearch.entity().getValue(), Op.EQ);
+        AllFieldsSearch.done();
+    }
+
+    @Override
+    public List<LoadBalancerConfigVO> listByNetworkId(Long networkId) {
+        SearchCriteria<LoadBalancerConfigVO> sc = AllFieldsSearch.create();
+        sc.setParameters("scope", Scope.Network);
+        sc.setParameters("networkId", networkId);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<LoadBalancerConfigVO> listByVpcId(Long vpcId) {
+        SearchCriteria<LoadBalancerConfigVO> sc = AllFieldsSearch.create();
+        sc.setParameters("scope", Scope.Vpc);
+        sc.setParameters("vpcId", vpcId);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<LoadBalancerConfigVO> listByLoadBalancerId(Long loadBalancerId) {
+        SearchCriteria<LoadBalancerConfigVO> sc = AllFieldsSearch.create();
+        sc.setParameters("scope", Scope.LoadBalancerRule);
+        sc.setParameters("loadBalancerId", loadBalancerId);
+        return listBy(sc);
+    }
+
+    @Override
+    public void removeByNetworkId(Long networkId) {
+        SearchCriteria<LoadBalancerConfigVO> sc = AllFieldsSearch.create();
+        sc.setParameters("scope", Scope.Network);
+        sc.setParameters("networkId", networkId);
+        remove(sc);
+    }
+
+    @Override
+    public void removeByVpcId(Long vpcId) {
+        SearchCriteria<LoadBalancerConfigVO> sc = AllFieldsSearch.create();
+        sc.setParameters("scope", Scope.Vpc);
+        sc.setParameters("vpcId", vpcId);
+        remove(sc);
+    }
+
+    @Override
+    public void removeByLoadBalancerId(Long loadBalancerId) {
+        SearchCriteria<LoadBalancerConfigVO> sc = AllFieldsSearch.create();
+        sc.setParameters("scope", Scope.LoadBalancerRule);
+        sc.setParameters("loadBalancerId", loadBalancerId);
+        remove(sc);
+    }
+
+    @Override
+    public LoadBalancerConfigVO findConfig(Scope scope, Long networkId, Long vpcId, Long loadBalancerId, String name) {
+        SearchCriteria<LoadBalancerConfigVO> sc = AllFieldsSearch.create();
+        if (scope != null) {
+            sc.setParameters("scope", scope);
+        }
+        if (networkId != null) {
+            sc.setParameters("networkId", networkId);
+        }
+        if (vpcId != null) {
+            sc.setParameters("vpcId", vpcId);
+        }
+        if (loadBalancerId != null) {
+            sc.setParameters("loadBalancerId", loadBalancerId);
+        }
+        if (name != null) {
+            sc.setParameters("name", name);
+        }

Review comment:
       This code seems repeated, but changing parameters; We could extract it to a method or create a `setParametersIfNotNull` in `SearchCriteria`.

##########
File path: server/src/main/java/com/cloud/api/ApiResponseHelper.java
##########
@@ -1040,6 +1043,78 @@ public LoadBalancerResponse createLoadBalancerResponse(LoadBalancer loadBalancer
         return lbResponse;
     }
 
+    @Override
+    public LoadBalancerConfigResponse createLoadBalancerConfigResponse(LoadBalancerConfig config) {
+        Network network = null;
+        Vpc vpc = null;
+        LoadBalancer lb = null;
+        if (config.getNetworkId() != null) {
+            network = ApiDBUtils.findNetworkById(config.getNetworkId());
+        }
+        if (config.getVpcId() != null) {
+            vpc = ApiDBUtils.findVpcById(config.getVpcId());
+        }
+        if (config.getLoadBalancerId() != null) {
+            lb = ApiDBUtils.findLoadBalancerById(config.getLoadBalancerId());
+        }
+        return setLoadBalancerConfigResponse(network, vpc, lb, config);
+    }
+
+    @Override
+    public List<LoadBalancerConfigResponse> createLoadBalancerConfigResponse(List<? extends LoadBalancerConfig> configs) {
+        List<LoadBalancerConfigResponse> lbConfigResponses = new ArrayList<LoadBalancerConfigResponse>();
+        if (configs == null || configs.size() == 0) {
+            return lbConfigResponses;
+        }
+        LoadBalancerConfig config = configs.get(0);
+        Network network = null;
+        Vpc vpc = null;
+        LoadBalancer lb = null;
+        if (config.getNetworkId() != null) {
+            network = ApiDBUtils.findNetworkById(config.getNetworkId());
+        }
+        if (config.getVpcId() != null) {
+            vpc = ApiDBUtils.findVpcById(config.getVpcId());
+        }
+        if (config.getLoadBalancerId() != null) {
+            lb = ApiDBUtils.findLoadBalancerById(config.getLoadBalancerId());
+        }

Review comment:
       We could add this code to the helper that I mentioned before, as it is repeated in others methods.

##########
File path: server/src/main/java/com/cloud/api/ApiResponseHelper.java
##########
@@ -1040,6 +1043,78 @@ public LoadBalancerResponse createLoadBalancerResponse(LoadBalancer loadBalancer
         return lbResponse;
     }
 
+    @Override
+    public LoadBalancerConfigResponse createLoadBalancerConfigResponse(LoadBalancerConfig config) {
+        Network network = null;
+        Vpc vpc = null;
+        LoadBalancer lb = null;
+        if (config.getNetworkId() != null) {
+            network = ApiDBUtils.findNetworkById(config.getNetworkId());
+        }
+        if (config.getVpcId() != null) {
+            vpc = ApiDBUtils.findVpcById(config.getVpcId());
+        }
+        if (config.getLoadBalancerId() != null) {
+            lb = ApiDBUtils.findLoadBalancerById(config.getLoadBalancerId());
+        }
+        return setLoadBalancerConfigResponse(network, vpc, lb, config);
+    }
+
+    @Override
+    public List<LoadBalancerConfigResponse> createLoadBalancerConfigResponse(List<? extends LoadBalancerConfig> configs) {
+        List<LoadBalancerConfigResponse> lbConfigResponses = new ArrayList<LoadBalancerConfigResponse>();
+        if (configs == null || configs.size() == 0) {

Review comment:
       We could use `org.apache.commons.collections.CollectionUtils` here:
   
   ```java
   ...
   if (CollectionUtils.isEmpty(configs)) {
   ...
   ```

##########
File path: server/src/main/java/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
##########
@@ -1757,6 +1840,52 @@ private void updateWithLbRules(final DomainRouterJoinVO routerJoinVO, final Stri
         }
     }
 
+    private void updateLbValues(final HashMap<String, String> lbConfigsMap, StringBuilder loadBalancingData) {
+        String lbMaxConn = lbConfigsMap.getOrDefault(LoadBalancerConfigKey.LbMaxConn.key(), null);
+        String lbFullConn = lbConfigsMap.getOrDefault(LoadBalancerConfigKey.LbFullConn.key(), null);
+        String lbTimeoutConnect = lbConfigsMap.getOrDefault(LoadBalancerConfigKey.LbTimeoutConnect.key(), null);
+        String lbTimeoutServer = lbConfigsMap.getOrDefault(LoadBalancerConfigKey.LbTimeoutServer.key(), null);
+        String lbTimeoutClient = lbConfigsMap.getOrDefault(LoadBalancerConfigKey.LbTimeoutClient.key(), null);
+        String lbBackendHttps = lbConfigsMap.getOrDefault(LoadBalancerConfigKey.LbBackendHttps.key(), null);
+        String lbHttp2 = lbConfigsMap.getOrDefault(LoadBalancerConfigKey.LbHttp2.key(), null);
+
+        // Process lb.server values
+        String serverMaxconn = lbConfigsMap.getOrDefault(LoadBalancerConfigKey.LbServerMaxConn.key(), null);
+        String serverMinconn = lbConfigsMap.getOrDefault(LoadBalancerConfigKey.LbServerMinConn.key(), null);
+        String serverMaxqueue = lbConfigsMap.getOrDefault(LoadBalancerConfigKey.LbServerMaxQueue.key(), null);
+
+        if (lbMaxConn != null) {
+            loadBalancingData.append(",lb.maxconn=").append(lbMaxConn);
+        }
+        if (lbFullConn != null) {
+            loadBalancingData.append(",lb.fullconn=").append(lbFullConn);
+        }
+        if (lbTimeoutConnect != null) {
+            loadBalancingData.append(",lb.timeout.connect=").append(lbTimeoutConnect);
+        }
+        if (lbTimeoutServer != null) {
+            loadBalancingData.append(",lb.timeout.server=").append(lbTimeoutServer);
+        }
+        if (lbTimeoutClient != null) {
+            loadBalancingData.append(",lb.timeout.client=").append(lbTimeoutClient);
+        }
+        if (lbBackendHttps != null) {
+            loadBalancingData.append(",lb.backend.https=").append(lbBackendHttps);
+        }
+        if (lbHttp2 != null) {
+            loadBalancingData.append(",http2=").append(lbHttp2);
+        }
+        if (serverMaxconn != null) {
+            loadBalancingData.append(",server.maxconn=").append(serverMaxconn);
+        }
+        if (serverMinconn != null) {
+            loadBalancingData.append(",server.minconn=").append(serverMinconn);
+        }
+        if (serverMaxqueue != null) {
+            loadBalancingData.append(",server.maxqueue=").append(serverMaxqueue);
+        }

Review comment:
       This code seems repeated, but changing parameters; We could extract it to a method.

##########
File path: server/src/main/java/org/apache/cloudstack/network/lb/LoadBalancerConfigManagerImpl.java
##########
@@ -0,0 +1,396 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.network.lb;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.dao.LoadBalancerConfigDao;
+import com.cloud.network.dao.LoadBalancerConfigVO;
+import com.cloud.network.dao.LoadBalancerDao;
+import com.cloud.network.dao.LoadBalancerVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkServiceMapDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.lb.LoadBalancingRulesManager;
+import com.cloud.network.rules.LoadBalancerContainer.Scheme;
+import com.cloud.network.vpc.VpcVO;
+import com.cloud.network.vpc.dao.VpcDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+import org.apache.cloudstack.api.command.user.loadbalancer.CreateLoadBalancerConfigCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.DeleteLoadBalancerConfigCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerConfigsCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.ReplaceLoadBalancerConfigsCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.UpdateLoadBalancerConfigCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig.Scope;
+import org.apache.log4j.Logger;
+
+public class LoadBalancerConfigManagerImpl extends ManagerBase implements LoadBalancerConfigService, LoadBalancerConfigManager {
+    private static final Logger LOGGER = Logger.getLogger(LoadBalancerConfigManagerImpl.class);
+
+    @Inject
+    LoadBalancerConfigDao _lbConfigDao;
+    @Inject
+    NetworkDao _networkDao;
+    @Inject
+    VpcDao _vpcDao;
+    @Inject
+    LoadBalancerDao _lbDao;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    LoadBalancingRulesManager _lbMgr;
+    @Inject
+    NetworkServiceMapDao _ntwkSrvcDao;
+
+    @Override
+    public List<? extends LoadBalancerConfig> searchForLoadBalancerConfigs(ListLoadBalancerConfigsCmd cmd) {
+        Long id = cmd.getId();
+        String scopeStr = cmd.getScope();
+        Long networkId = cmd.getNetworkId();
+        Long vpcId = cmd.getVpcId();
+        Long loadBalancerId = cmd.getLoadBalancerId();
+        String name = cmd.getName();
+
+        if (id == null && scopeStr == null) {
+            throw new InvalidParameterValueException("At least one of id/scope is required");
+        }
+
+        //validate parameters
+        Scope scope = null;
+        if (scopeStr != null) {
+            scope = LoadBalancerConfigKey.getScopeFromString(scopeStr);
+            if (scope == null) {
+                throw new InvalidParameterValueException("Invalid scope " + scopeStr);
+            }
+            checkPermission(scope, networkId, vpcId, loadBalancerId, cmd.listAll());
+        }
+
+        if (id != null) {
+            LoadBalancerConfigVO config = _lbConfigDao.findById(id);
+            if (config == null) {
+                throw new InvalidParameterValueException("Cannot find load balancer config by id " + id);
+            }
+            checkPermission(config);
+        }
+
+        if (cmd.listAll()) {
+            if (id != null || name != null) {
+                throw new InvalidParameterValueException("id and name must be null if listall is true");
+            }
+        }
+
+        SearchCriteria<LoadBalancerConfigVO> sc = _lbConfigDao.createSearchCriteria();
+        if (id != null) {
+            sc.addAnd("id", SearchCriteria.Op.EQ, id);
+        }
+        if (scope != null) {
+            sc.addAnd("scope", SearchCriteria.Op.EQ, scope);
+        }
+        if (networkId != null) {
+            sc.addAnd("networkId", SearchCriteria.Op.EQ, networkId);
+        }
+        if (vpcId != null) {
+            sc.addAnd("vpcId", SearchCriteria.Op.EQ, vpcId);
+        }
+        if (loadBalancerId != null) {
+            sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId);
+        }
+        if (name != null) {
+            sc.addAnd("name", SearchCriteria.Op.EQ, name);
+        }
+        List<LoadBalancerConfigVO> configs = new ArrayList<LoadBalancerConfigVO>();
+        if (id != null || networkId != null || vpcId != null || loadBalancerId != null) {
+            configs = _lbConfigDao.search(sc, null);
+        }
+        if (cmd.listAll()) {
+            LOGGER.debug("Adding config keys for scope " + scope);
+            Map<String, LoadBalancerConfigVO> configsMap = new LinkedHashMap<String, LoadBalancerConfigVO>();
+            for (LoadBalancerConfigVO config : configs) {
+                configsMap.put(config.getName(), config);
+            }
+            List<LoadBalancerConfigVO> result = new ArrayList<LoadBalancerConfigVO>();
+            Map<String, LoadBalancerConfigKey> configKeys = LoadBalancerConfigKey.getConfigsByScope(scope);
+            for (LoadBalancerConfigKey configKey : configKeys.values()) {
+                if (configsMap.get(configKey.key()) != null) {
+                    result.add(configsMap.get(configKey.key()));
+                } else {
+                    result.add(new LoadBalancerConfigVO(scope, null, null, null, configKey, null));
+                }
+            }
+            return result;
+        } else {
+            return configs;
+        }
+    }
+
+    @Override
+    public LoadBalancerConfig createLoadBalancerConfig(CreateLoadBalancerConfigCmd cmd) {
+        String scopeStr = cmd.getScope();
+        Long networkId = cmd.getNetworkId();
+        Long vpcId = cmd.getVpcId();
+        Long loadBalancerId = cmd.getLoadBalancerId();
+        String name = cmd.getName();
+        String value = cmd.getValue();
+
+        //validate parameters
+        Scope scope = LoadBalancerConfigKey.getScopeFromString(scopeStr);
+        if (scope == null) {
+            throw new InvalidParameterValueException("Invalid scope " + scopeStr);
+        }
+        LoadBalancerConfigKey configKey = validateParameters(scope, name, value);
+
+        checkPermission(scope, networkId, vpcId, loadBalancerId);
+
+        LoadBalancerConfigVO existingConfig = _lbConfigDao.findConfig(scope, networkId, vpcId, loadBalancerId, name);
+        if (existingConfig != null) {
+            if (cmd.isForced()) {
+                _lbConfigDao.remove(existingConfig.getId());
+            } else {
+                throw new InvalidParameterValueException("config " + name + " already exists, please add forced=true or update it instead");           }
+        }
+        LoadBalancerConfigVO config = _lbConfigDao.persist(new LoadBalancerConfigVO(scope, networkId, vpcId, loadBalancerId, configKey, value));
+
+        applyLbConfigsForNetwork(config.getNetworkId(), config.getVpcId(), config.getLoadBalancerId());
+
+        return config;
+    }
+
+    @Override
+    public boolean deleteLoadBalancerConfig(DeleteLoadBalancerConfigCmd cmd) {
+        Long id = cmd.getId();
+        LoadBalancerConfigVO config = _lbConfigDao.findById(id);
+        if (config == null) {
+            throw new InvalidParameterValueException("Cannot find load balancer config by id " + id);
+        }
+        checkPermission(config);
+
+        boolean result = _lbConfigDao.remove(id);
+
+        applyLbConfigsForNetwork(config.getNetworkId(), config.getVpcId(), config.getLoadBalancerId());
+
+        return result;
+    }
+
+    @Override
+    public LoadBalancerConfig updateLoadBalancerConfig(UpdateLoadBalancerConfigCmd cmd) {
+        Long id = cmd.getId();
+        String value = cmd.getValue();
+
+        LoadBalancerConfigVO config = _lbConfigDao.findById(id);
+        if (config == null) {
+            throw new InvalidParameterValueException("Cannot find load balancer config by id " + id);
+        }
+        //validate parameters
+        LoadBalancerConfigKey configKey = validateParameters(config.getScope(), config.getName(), value);
+
+        checkPermission(config);
+        config.setValue(value);
+
+        _lbConfigDao.update(config.getId(), config);
+
+        applyLbConfigsForNetwork(config.getNetworkId(), config.getVpcId(), config.getLoadBalancerId());
+
+        return config;
+    }
+
+    @Override
+    public List<? extends LoadBalancerConfig> replaceLoadBalancerConfigs(ReplaceLoadBalancerConfigsCmd cmd) {
+        String scopeStr = cmd.getScope();
+        Long networkId = cmd.getNetworkId();
+        Long vpcId = cmd.getVpcId();
+        Long loadBalancerId = cmd.getLoadBalancerId();
+        Map<String, String> configList = cmd.getConfigList();
+        if (configList == null) {
+            throw new InvalidParameterValueException("Invalid config list");
+        }
+
+        //validate parameters
+        Scope scope = LoadBalancerConfigKey.getScopeFromString(scopeStr);
+        if (scope == null) {
+            throw new InvalidParameterValueException("Invalid scope " + scopeStr);
+        }
+        List<LoadBalancerConfigVO> configs = new ArrayList<LoadBalancerConfigVO>();
+        for (String name : configList.keySet()) {
+            String value = configList.get(name);
+            LoadBalancerConfigKey configKey = validateParameters(scope, name, value);
+            configs.add(new LoadBalancerConfigVO(scope, networkId, vpcId, loadBalancerId, configKey, value));
+        }
+
+        checkPermission(scope, networkId, vpcId, loadBalancerId);
+
+        configs = _lbConfigDao.saveConfigs(configs);
+
+        applyLbConfigsForNetwork(networkId, vpcId, loadBalancerId);
+
+        return configs;
+    }
+
+    private LoadBalancerConfigKey validateParameters(Scope scope, String name, String value) {
+        Pair<LoadBalancerConfigKey, String> res = LoadBalancerConfigKey.validate(scope, name, value);
+        if (res.second() != null) {
+            throw new InvalidParameterValueException(res.second());
+        }
+        return res.first();
+    }
+
+    private void checkPermission(LoadBalancerConfigVO config) {
+        checkPermission(config.getScope(), config.getNetworkId(), config.getVpcId(), config.getLoadBalancerId());
+    }
+
+    private void checkPermission(Scope scope, Long networkId, Long vpcId, Long loadBalancerId) {
+        checkPermission(scope, networkId, vpcId, loadBalancerId, false);
+    }
+
+    private void checkPermission(Scope scope, Long networkId, Long vpcId, Long loadBalancerId, Boolean listAll) {
+        Account caller = CallContext.current().getCallingAccount();
+        if (scope == Scope.Network) {
+            if (networkId == null) {
+                if (listAll) {
+                    return;
+                }
+                throw new InvalidParameterValueException("networkId is required");
+            }
+            if (vpcId != null || loadBalancerId != null) {
+                throw new InvalidParameterValueException("vpcId and loadBalancerId should be null if scope is Network");
+            }
+            if (networkId == null) {
+                throw new InvalidParameterValueException("networkId is required");
+            }
+            NetworkVO network = _networkDao.findById(networkId);
+            if (network == null) {
+                throw new InvalidParameterValueException("Cannot find network by id " + networkId);
+            }
+            // Perform permission check
+            _accountMgr.checkAccess(caller, null, true, network);
+            if (network.getVpcId() != null) {
+                throw new InvalidParameterValueException("network " + network.getName() + " is a VPC tier, please add LB configs to VPC instead");
+            }
+        } else if (scope == Scope.Vpc) {
+            if (vpcId == null) {
+                if (listAll) {
+                    return;
+                }
+                throw new InvalidParameterValueException("vpcId is required");
+            }
+            if (networkId != null || loadBalancerId != null) {
+                throw new InvalidParameterValueException("networkId and loadBalancerId should be null if scope is Vpc");
+            }
+            VpcVO vpc = _vpcDao.findById(vpcId);
+            if (vpc == null) {
+                throw new InvalidParameterValueException("Cannot find vpc by id " + vpcId);
+            }
+            // Perform permission check
+            _accountMgr.checkAccess(caller, null, true, vpc);
+        } else if (scope == Scope.LoadBalancerRule) {
+            if (loadBalancerId == null) {
+                if (listAll) {
+                    return;
+                }
+                throw new InvalidParameterValueException("loadBalancerId is required");
+            }
+            if (networkId != null || vpcId != null) {
+                throw new InvalidParameterValueException("networkId and vpcId should be null if scope is LoadBalancerRule");
+            }
+            LoadBalancerVO rule = _lbDao.findById(loadBalancerId);
+            if (rule == null) {
+                throw new InvalidParameterValueException("Cannot find load balancer rule by id " + loadBalancerId);
+            }
+            if (networkId != null) {
+                // Perform permission check
+                checkPermission(Scope.Network, rule.getNetworkId(), null, null);
+            }
+        }

Review comment:
       This code seems repeated, but changing parameters; We could extract it to a method.

##########
File path: server/src/main/java/org/apache/cloudstack/network/lb/LoadBalancerConfigManagerImpl.java
##########
@@ -0,0 +1,396 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.network.lb;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.dao.LoadBalancerConfigDao;
+import com.cloud.network.dao.LoadBalancerConfigVO;
+import com.cloud.network.dao.LoadBalancerDao;
+import com.cloud.network.dao.LoadBalancerVO;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkServiceMapDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.lb.LoadBalancingRulesManager;
+import com.cloud.network.rules.LoadBalancerContainer.Scheme;
+import com.cloud.network.vpc.VpcVO;
+import com.cloud.network.vpc.dao.VpcDao;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.utils.Pair;
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+import org.apache.cloudstack.api.command.user.loadbalancer.CreateLoadBalancerConfigCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.DeleteLoadBalancerConfigCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.ListLoadBalancerConfigsCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.ReplaceLoadBalancerConfigsCmd;
+import org.apache.cloudstack.api.command.user.loadbalancer.UpdateLoadBalancerConfigCmd;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig.Scope;
+import org.apache.log4j.Logger;
+
+public class LoadBalancerConfigManagerImpl extends ManagerBase implements LoadBalancerConfigService, LoadBalancerConfigManager {
+    private static final Logger LOGGER = Logger.getLogger(LoadBalancerConfigManagerImpl.class);
+
+    @Inject
+    LoadBalancerConfigDao _lbConfigDao;
+    @Inject
+    NetworkDao _networkDao;
+    @Inject
+    VpcDao _vpcDao;
+    @Inject
+    LoadBalancerDao _lbDao;
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    LoadBalancingRulesManager _lbMgr;
+    @Inject
+    NetworkServiceMapDao _ntwkSrvcDao;
+
+    @Override
+    public List<? extends LoadBalancerConfig> searchForLoadBalancerConfigs(ListLoadBalancerConfigsCmd cmd) {
+        Long id = cmd.getId();
+        String scopeStr = cmd.getScope();
+        Long networkId = cmd.getNetworkId();
+        Long vpcId = cmd.getVpcId();
+        Long loadBalancerId = cmd.getLoadBalancerId();
+        String name = cmd.getName();
+
+        if (id == null && scopeStr == null) {
+            throw new InvalidParameterValueException("At least one of id/scope is required");
+        }
+
+        //validate parameters
+        Scope scope = null;
+        if (scopeStr != null) {
+            scope = LoadBalancerConfigKey.getScopeFromString(scopeStr);
+            if (scope == null) {
+                throw new InvalidParameterValueException("Invalid scope " + scopeStr);
+            }
+            checkPermission(scope, networkId, vpcId, loadBalancerId, cmd.listAll());
+        }
+
+        if (id != null) {
+            LoadBalancerConfigVO config = _lbConfigDao.findById(id);
+            if (config == null) {
+                throw new InvalidParameterValueException("Cannot find load balancer config by id " + id);
+            }
+            checkPermission(config);
+        }
+
+        if (cmd.listAll()) {
+            if (id != null || name != null) {
+                throw new InvalidParameterValueException("id and name must be null if listall is true");
+            }
+        }
+
+        SearchCriteria<LoadBalancerConfigVO> sc = _lbConfigDao.createSearchCriteria();
+        if (id != null) {
+            sc.addAnd("id", SearchCriteria.Op.EQ, id);
+        }
+        if (scope != null) {
+            sc.addAnd("scope", SearchCriteria.Op.EQ, scope);
+        }
+        if (networkId != null) {
+            sc.addAnd("networkId", SearchCriteria.Op.EQ, networkId);
+        }
+        if (vpcId != null) {
+            sc.addAnd("vpcId", SearchCriteria.Op.EQ, vpcId);
+        }
+        if (loadBalancerId != null) {
+            sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId);
+        }
+        if (name != null) {
+            sc.addAnd("name", SearchCriteria.Op.EQ, name);
+        }

Review comment:
       This code seems repeated, but changing parameters; We could extract it to a method or create an `addAndNotNull` to `SearchCriteria`.

##########
File path: core/src/main/java/com/cloud/network/HAProxyConfigurator.java
##########
@@ -467,24 +484,103 @@ private String getLbSubRuleForStickiness(final LoadBalancerTO lbTO) {
         return sb.toString();
     }
 
-    private List<String> getRulesForPool(final LoadBalancerTO lbTO, final boolean keepAliveEnabled) {
+    private String getCustomizedSslConfigs(HashMap<String, String> lbConfigsMap, final LoadBalancerConfigCommand lbCmd){
+        String lbSslConfiguration = lbConfigsMap.get(LoadBalancerConfigKey.LbSslConfiguration.key());
+        if (lbSslConfiguration == null) {
+            lbSslConfiguration = lbCmd.lbSslConfiguration;
+        }
+        if (SSLConfiguration.OLD.toString().equalsIgnoreCase(lbSslConfiguration)) {
+            return sslConfigurationOld;
+        } else if (SSLConfiguration.INTERMEDIATE.toString().equalsIgnoreCase(lbSslConfiguration)) {
+            return sslConfigurationIntermediate;
+        }
+        return "";
+    }
+
+    private List<String> getRulesForPool(final LoadBalancerTO lbTO, final LoadBalancerConfigCommand lbCmd, HashMap<String, String> networkLbConfigsMap) {
         StringBuilder sb = new StringBuilder();
         final String poolName = sb.append(lbTO.getSrcIp().replace(".", "_")).append('-').append(lbTO.getSrcPort()).toString();
         final String publicIP = lbTO.getSrcIp();
         final int publicPort = lbTO.getSrcPort();
         final String algorithm = lbTO.getAlgorithm();
 
+        final LoadBalancerConfigTO[] lbConfigs = lbTO.getLbConfigs();
+        final HashMap<String, String> lbConfigsMap = new HashMap<String, String>();
+        if (lbConfigs != null) {
+            for (LoadBalancerConfigTO lbConfig: lbConfigs) {
+                lbConfigsMap.put(lbConfig.getName(), lbConfig.getValue());
+            }
+        }
+
+        boolean isTransparent = false;
+        if ("true".equalsIgnoreCase(lbConfigsMap.get(LoadBalancerConfigKey.LbTransparent.key()))) {
+            isTransparent = true;
+        }
+
+        boolean sslOffloading = false;
+        if (lbTO.getSslCert() != null && ! lbTO.getSslCert().isRevoked()
+                && lbTO.getLbProtocol() != null && lbTO.getLbProtocol().equals(NetUtils.SSL_PROTO)) {
+            sslOffloading = true;
+        }
+
+        final List<String> frontendConfigs = new ArrayList<String>();
+        final List<String> backendConfigs = new ArrayList<String>();
+        final List<String> backendConfigsForHttp = new ArrayList<String>();
         final List<String> result = new ArrayList<String>();
-        // add line like this: "listen  65_37_141_30-80\n\tbind 65.37.141.30:80"
-        sb = new StringBuilder();
-        sb.append("listen ").append(poolName);
-        result.add(sb.toString());
+
         sb = new StringBuilder();
         sb.append("\tbind ").append(publicIP).append(":").append(publicPort);
-        result.add(sb.toString());
+        if (sslOffloading) {
+            sb.append(" ssl crt ").append(SSL_CERTS_DIR).append(poolName).append(".pem");
+            // check for http2 support
+            if ("true".equalsIgnoreCase(lbConfigsMap.get(LoadBalancerConfigKey.LbHttp2.key()))) {
+                sb.append(" alpn h2,http/1.1");
+            }
+
+            sb.append(getCustomizedSslConfigs(lbConfigsMap, lbCmd));
+
+            sb.append("\n\thttp-request add-header X-Forwarded-Proto https");
+        }
+        frontendConfigs.add(sb.toString());
         sb = new StringBuilder();
         sb.append("\t").append("balance ").append(algorithm);
-        result.add(sb.toString());
+        backendConfigs.add(sb.toString());
+
+        String timeoutConnect = lbConfigsMap.get(LoadBalancerConfigKey.LbTimeoutConnect.key());
+        if (timeoutConnect != null) {
+            sb = new StringBuilder();
+            sb.append("\t").append("timeout connect    " + timeoutConnect);
+            backendConfigs.add(sb.toString());
+        }
+        String timeoutClient = lbConfigsMap.get(LoadBalancerConfigKey.LbTimeoutClient.key());
+        if (timeoutClient != null) {
+            sb = new StringBuilder();
+            sb.append("\t").append("timeout client     " + timeoutClient);
+            frontendConfigs.add(sb.toString());
+        }
+        String timeoutServer = lbConfigsMap.get(LoadBalancerConfigKey.LbTimeoutServer.key());
+        if (timeoutServer != null) {
+            sb = new StringBuilder();
+            sb.append("\t").append("timeout server     " + timeoutServer);
+            backendConfigs.add(sb.toString());
+        }
+
+        if (lbConfigsMap.get(LoadBalancerConfigKey.LbMaxConn.key()) != null) {
+            long maxConnValue = Long.parseLong(lbConfigsMap.get(LoadBalancerConfigKey.LbMaxConn.key()));
+            if (maxConnValue > 0) {
+                sb = new StringBuilder();
+                sb.append("\tmaxconn ").append(maxConnValue);
+                frontendConfigs.add(sb.toString());
+            }
+        }
+        if (lbConfigsMap.get(LoadBalancerConfigKey.LbFullConn.key()) != null) {
+            long fullConnValue = Long.parseLong(lbConfigsMap.get(LoadBalancerConfigKey.LbFullConn.key()));
+            if (fullConnValue > 0) {
+                sb = new StringBuilder();
+                sb.append("\tfullconn ").append(fullConnValue);
+                backendConfigs.add(sb.toString());
+            }
+        }

Review comment:
       Also, instead of using `StringBuilder`, we could use `String.format`, it is more clean and readable.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-870556324


   @weizhouapache a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-918877344


   > Ping @weizhouapache I think some more work may be needed on this as now Debian 11 has moved to haproxy 2.x, should this be targeted for next milestone. I worry it may not be stable within two weeks, ie current tentative RC date.
   
   @rhtyd it is ok to me.
   @ravening @soreana what do you think ?
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-998918814


   > @weizhouapache @rhtyd I have created a new pr for this in #5799
   
   @ravening 
   great. closing this ticket then.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] sureshanaparti commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
sureshanaparti commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r520553964



##########
File path: core/src/main/java/com/cloud/network/HAProxyConfigurator.java
##########
@@ -531,42 +654,111 @@ private String getLbSubRuleForStickiness(final LoadBalancerTO lbTO) {
                 }
             }
             if (httpbasedStickiness) {
-                result.addAll(dstWithCookieSubRule);
+                backendConfigs.addAll(dstWithCookieSubRule);
             } else {
-                result.addAll(dstSubRule);
+                backendConfigs.addAll(dstSubRule);
             }
-            result.add(stickinessSubRule);
+            backendConfigs.add(stickinessSubRule);
         } else {
-            result.addAll(dstSubRule);
+            backendConfigs.addAll(dstSubRule);
         }
         if (stickinessSubRule != null && !destsAvailable) {
             s_logger.warn("Haproxy stickiness policy for lb rule: " + lbTO.getSrcIp() + ":" + lbTO.getSrcPort() + ": Not Applied, cause:  backends are unavailable");
         }
-        if (publicPort == NetUtils.HTTP_PORT && !keepAliveEnabled || httpbasedStickiness) {
+        boolean http = false;
+        String cfgLbHttp = lbConfigsMap.get(LoadBalancerConfigKey.LbHttp.key());
+        if (publicPort == NetUtils.HTTP_PORT && cfgLbHttp == null) {
+            http = true;
+        } else if (cfgLbHttp != null && cfgLbHttp.equalsIgnoreCase("true")) {
+            http = true;
+        }
+
+        boolean keepAliveEnabled = lbCmd.keepAliveEnabled;
+        String cfgLbHttpKeepalive = lbConfigsMap.get(LoadBalancerConfigKey.LbHttpKeepalive.key());
+        if (cfgLbHttpKeepalive != null && cfgLbHttpKeepalive.equalsIgnoreCase("true")) {
+            keepAliveEnabled = true;
+        } else if (cfgLbHttpKeepalive != null && cfgLbHttpKeepalive.equalsIgnoreCase("false")) {
+            keepAliveEnabled = false;
+        }
+
+        if (http || httpbasedStickiness || sslOffloading) {
             sb = new StringBuilder();
             sb.append("\t").append("mode http");
+            frontendConfigs.add(sb.toString());
+            backendConfigsForHttp.add(sb.toString());
+            if (keepAliveEnabled) {
+                sb = new StringBuilder();
+                sb.append("\t").append("no option forceclose");
+                frontendConfigs.add(sb.toString());
+                backendConfigsForHttp.add(sb.toString());
+            } else {
+                sb = new StringBuilder();
+                sb.append("\t").append("option httpclose");
+                frontendConfigs.add(sb.toString());
+                backendConfigsForHttp.add(sb.toString());
+            }
+        }
+
+        if (isTransparent) {
+            sb = new StringBuilder();
+            sb.append("frontend ").append(poolName);
             result.add(sb.toString());
+            result.addAll(frontendConfigs);
             sb = new StringBuilder();
-            sb.append("\t").append("option httpclose");
+            sb.append("\tacl local_subnet src ").append(lbCmd.getNetworkCidr());
+            sb.append("\n\tuse_backend ").append(poolName).append("-backend-local if local_subnet");
+            sb.append("\n\tdefault_backend ").append(poolName).append("-backend");
+            sb.append("\n\n");
+            sb.append("backend ").append(poolName).append("-backend");
+            result.add(sb.toString());
+            result.addAll(backendConfigsForHttp);
+            result.addAll(backendConfigs);
+            sb = new StringBuilder();
+            sb.append("\t").append("source 0.0.0.0 usesrc clientip");
+            sb.append("\n\n");
+            sb.append("backend ").append(poolName).append("-backend-local");
             result.add(sb.toString());
+            result.addAll(backendConfigsForHttp);
+            result.addAll(backendConfigs);
+        } else {
+            // add line like this: "listen  65_37_141_30-80\n\tbind 65.37.141.30:80"
+            sb = new StringBuilder();
+            sb.append("listen ").append(poolName);
+            result.add(sb.toString());
+            result.addAll(frontendConfigs);
+            result.addAll(backendConfigs);
         }
 
         result.add(blankLine);
         return result;
     }
 
-    private String generateStatsRule(final LoadBalancerConfigCommand lbCmd, final String ruleName, final String statsIp) {
+    private String generateStatsRule(final LoadBalancerConfigCommand lbCmd, final String ruleName, final String statsIp, HashMap<String, String> networkLbConfigsMap) {
+        String lbStatsEnable = networkLbConfigsMap.get(LoadBalancerConfigKey.LbStatsEnable.key());
+        if ( lbStatsEnable != null && !  lbStatsEnable.equalsIgnoreCase("true")) {
+            return "";
+        }

Review comment:
       for `lbStatsEnable` null, rule generated?




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-723972129


   @DaanHoogland a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-700795539


   @rhtyd a Trillian-Jenkins test job (centos7 mgmt + kvm-centos7) has been kicked to run smoke tests


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-689500812


   @rhtyd a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-695810991






----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland removed a comment on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland removed a comment on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-721595255


   @blueorangutan test


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] davidjumani commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
davidjumani commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r589319206



##########
File path: ui/src/views/network/LbConfigTab.vue
##########
@@ -0,0 +1,341 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+<template>
+  <div>
+    <div>
+      <div class="form">
+        <div class="form__item">
+          <div class="form__label">{{ $t('label.lb.config.name') }}</div>
+          <br>
+          <a-select v-model="lbConfig.name" style="width: 100%;" @change="populateValues">
+            <a-select-option
+              v-for="config in globalLbConfigs"
+              :key="config.name">{{ config.name }}
+            </a-select-option>
+          </a-select>
+        </div>
+        <div class="form__item">
+          <div class="form__label">{{ $t('label.description') }}</div>
+          <br>
+          {{ lbConfig.description }}
+        </div>
+        <div class="form__item">
+          <div class="form__label">{{ $t('label.lb.config.default.value') }}</div>
+          <br>
+          {{ lbConfig.defaultvalue }}
+        </div>
+        <div class="form__item" ref="lbconfigValue">
+          <div class="form__label"><span class="form__required">*</span>{{ $t('label.lb.config.value') }}</div>
+          <br>
+          <a-input v-model="lbConfig.value"></a-input>
+          <span class="error-text">Required</span>
+        </div>
+        <div class="form__item">
+          <div class="form__label">{{ $t('label.action') }}</div>
+          <br>
+          <a-button :disabled="!('createLoadBalancerConfig' in $store.getters.apis)" type="primary" icon="plus" @click="addLbConfig">{{ $t('label.add') }}</a-button>
+        </div>
+      </div>
+    </div>
+
+    <a-divider/>
+
+    <a-table
+      size="small"
+      style="overflow-y: auto"
+      :loading="loading"
+      :columns="columns"
+      :dataSource="savedLbConfigs"
+      :pagination="false"
+      :rowKey="record => record.id">
+      <template slot="actions" slot-scope="record">
+        <a-button :disabled="!('deleteLoadBalancerConfig' in $store.getters.apis)" shape="circle" type="danger" icon="delete" @click="deleteLbConfig(record)" />
+      </template>
+    </a-table>
+    <a-pagination
+      class="pagination"
+      size="small"
+      :current="page"
+      :pageSize="pageSize"
+      :total="totalCount"
+      :showTotal="total => `Total ${total} items`"
+      :pageSizeOptions="['10', '20', '40', '80', '100']"
+      @change="handleChangePage"
+      @showSizeChange="handleChangePageSize"
+      showSizeChanger/>
+  </div>
+</template>
+
+<script>
+import { api } from '@/api'
+export default {
+  name: 'LbConfigTab',
+  props: {
+    resource: {
+      type: Object,
+      required: true
+    }
+  },
+  data () {
+    return {
+      loading: true,
+      globalLbConfigs: [],
+      savedLbConfigs: [],
+      lbConfig: {
+        scope: 'Network',
+        name: null,
+        description: null,
+        defaultvalue: null,
+        value: null,
+        forced: 'true',
+        networkid: this.resource.id
+      },
+      totalCount: 0,
+      page: 1,
+      pageSize: 10,
+      columns: [
+        {
+          title: this.$t('label.lb.config.name'),
+          dataIndex: 'name'
+        },
+        {
+          title: this.$t('label.description'),
+          dataIndex: 'description'
+        },
+        {
+          title: this.$t('label.lb.config.default.value'),
+          dataIndex: 'defaultvalue'
+        },
+        {
+          title: this.$t('label.lb.config.value'),
+          dataIndex: 'value'
+        },
+        {
+          title: this.$t('label.action'),
+          scopedSlots: { customRender: 'actions' }
+        }
+      ]
+    }
+  },
+  mounted () {
+    this.fetchData()
+  },
+  watch: {
+    resource: function (newItem, oldItem) {
+      if (!newItem || !newItem.id) {
+        return
+      }
+      this.resource = newItem
+      this.fetchData()
+    }
+  },
+  methods: {
+    fetchData () {
+      this.loading = true
+      // Populate all lb confings
+      api('listLoadBalancerConfigs', {
+        scope: 'Network',
+        listall: 'true',
+        networkid: this.resource.id
+      }).then(response => {
+        this.globalLbConfigs = response.listloadbalancerconfigsresponse.loadbalancerconfig || []
+        this.lbConfig.name = this.globalLbConfigs[0].name
+        this.lbConfig.description = this.globalLbConfigs[0].description
+        this.lbConfig.defaultvalue = this.globalLbConfigs[0].defaultvalue
+      }).finally(() => {
+        this.loading = false
+      })
+      // Fetch saved lb configs
+      api('listLoadBalancerConfigs', {
+        scope: 'Network',
+        networkid: this.resource.id
+      }).then(response => {
+        this.savedLbConfigs = response.listloadbalancerconfigsresponse.loadbalancerconfig || []
+        this.totalCount = response.listloadbalancerconfigsresponse.count || 0
+      }).finally(() => {
+        this.loading = false
+      })
+    },
+    deleteLbConfig (rule) {
+      this.loading = true
+      api('deleteLoadBalancerConfig', { id: rule.id }).then(response => {
+        this.$pollJob({
+          jobId: response.deleteloadbalancerconfigresponse.jobid,
+          successMessage: `Successfully removed Load Balancer config`,
+          successMethod: () => this.fetchData(),
+          errorMessage: 'Removing Load Balancer config failed',
+          errorMethod: () => this.fetchData(),
+          loadingMessage: `Deleting Load Balancer config...`,
+          catchMessage: 'Error encountered while fetching async job result',
+          catchMethod: () => this.fetchData()
+        })
+      }).catch(error => {
+        this.$notifyError(error)
+        this.fetchData()
+      })
+    },
+    addLbConfig () {
+      if (!this.lbConfig.value) {
+        this.$refs.lbconfigValue.classList.add('error')
+        return
+      } else {
+        this.$refs.lbconfigValue.classList.remove('error')
+      }
+      this.loading = true
+      api('createLoadBalancerConfig', { ...this.lbConfig }).then(response => {
+        this.$pollJob({
+          jobId: response.createloadbalancerconfigresponse.jobid,
+          successMessage: `Successfully created new load balancer config`,
+          successMethod: () => {
+            this.resetValues()
+            this.fetchData()
+          },
+          errorMessage: 'Adding new Load Balancer Config failed',
+          errorMethod: () => {
+            this.resetValues()
+            this.fetchData()
+          },
+          loadingMessage: `Adding new Load Balancer config...`,
+          catchMessage: 'Error encountered while fetching async job result',
+          catchMethod: () => {
+            this.resetValues()
+            this.fetchData()
+          }
+        })
+      }).catch(error => {
+        this.$notifyError(error)
+        this.resetValues()
+        this.fetchData()
+      })
+    },
+    resetValues () {
+      this.lbConfig.name = ''
+      this.lbConfig.description = null
+      this.lbConfig.defaultValue = null
+      this.lbConfig.value = null
+      this.lbConfig.networkid = this.resource.id
+    },
+    populateValues () {
+      for (let i = 0; i < this.globalLbConfigs.length; i++) {
+        if (this.lbConfig.name === this.globalLbConfigs[i].name) {
+          this.lbConfig.description = this.globalLbConfigs[i].description
+          this.lbConfig.defaultvalue = this.globalLbConfigs[i].defaultvalue
+        }
+      }
+    },
+    handleChangePage (page, pageSize) {
+      this.page = page
+      this.pageSize = pageSize
+      this.fetchData()
+    },
+    handleChangePageSize (currentPage, pageSize) {
+      this.page = currentPage
+      this.pageSize = pageSize
+      this.fetchData()
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.rule {
+  &-container {
+    display: flex;
+    width: 100%;
+    flex-wrap: wrap;
+    margin-right: -20px;
+    margin-bottom: -10px;
+  }
+  &__item {
+    padding-right: 20px;
+    margin-bottom: 20px;
+    @media (min-width: 760px) {
+      flex: 1;
+    }
+  }
+  &__title {
+    font-weight: bold;
+  }
+}
+.add-btn {
+  width: 100%;
+  padding-top: 15px;
+  padding-bottom: 15px;
+  height: auto;
+}
+.add-actions {
+  display: flex;
+  justify-content: flex-end;
+  margin-right: -20px;
+  margin-bottom: 20px;
+  @media (min-width: 760px) {
+    margin-top: 20px;
+  }
+  button {
+    margin-right: 20px;
+  }
+}
+.form {
+  display: flex;
+  margin-right: -20px;
+  margin-bottom: 20px;
+  flex-direction: column;
+  align-items: flex-start;
+  @media (min-width: 760px) {
+    flex-direction: row;
+  }
+  &__item {
+    display: flex;
+    flex-direction: column;
+    flex: 1;
+    padding-right: 20px;
+    margin-bottom: 20px;
+    @media (min-width: 760px) {
+      margin-bottom: 0;
+      flex: 1;
+    }
+    input,
+    .ant-select {
+      margin-top: auto;
+    }
+  }
+  &__label {
+    font-weight: bold;
+  }
+  &__required {
+    margin-right: 5px;
+    color: red;
+  }
+  .error-text {
+    display: none;
+    color: red;
+    font-size: 0.8rem;
+  }
+  .error {
+    input {
+      border-color: red;
+    }
+    .error-text {
+      display: block;
+    }
+  }
+}
+.pagination {
+  margin-top: 20px;
+}
+</style>

Review comment:
       @weizhouapache Needs a new line at the end of the file
   ```
    ERROR  Failed to compile with 1 errors10:18:48 AM
   
    error  in ./src/views/network/LbConfigTab.vue
   
   Module Error (from ./node_modules/eslint-loader/index.js):
   
   /jenkins/workspace/acs-deb-pkg-builder/ui/src/views/network/LbConfigTab.vue
     341:9  error  Newline required at end of file but not found  eol-last
   
   ��� 1 problem (1 error, 0 warnings)
     1 error and 0 warnings potentially fixable with the `--fix` option.
   ```




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] soreana commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
soreana commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r668810151



##########
File path: core/src/main/java/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java
##########
@@ -72,4 +81,36 @@ public NicTO getNic() {
     public Long getVpcId() {
         return vpcId;
     }
+
+    public LoadBalancerConfigTO[] getNetworkLbConfigs() {
+        return this.networkLbConfigs;
+    }
+
+    public void setNetworkLbConfigs(List<? extends LoadBalancerConfig> networkLbConfigs) {
+        if (networkLbConfigs == null || networkLbConfigs.size() == 0) {

Review comment:
       @GutoVeronezi, As I mentioned before, `org.apache.commons.lang3.ArrayUtils` package don't have isEmpty method which accepts List object. I have to override it like:
   
   ```java
   ...
   ArrayUtils.isEmpty(new List[]{networkLbConfigs})
   ...
   ```
   
   It imposes unnecessary conversion. What do you think?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd edited a comment on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd edited a comment on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-679968897


   @weizhouapache can you fix the conflict and kick packaging? I'll help with testing, thnx


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-689550855


   Packaging result: ✔centos7 ✔centos8 ✔debian. JID-1941


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-698124881


   @rhtyd a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r520622888



##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/ReplaceLoadBalancerConfigsCmd.java
##########
@@ -0,0 +1,182 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig;
+import org.apache.commons.collections.MapUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "replaceLoadBalancerConfigs", description = "Replaces load balancer configs of vpc/network/rule",
+        responseObject = SuccessResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        since = "4.15",
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class ReplaceLoadBalancerConfigsCmd extends BaseAsyncCmd {
+    public static final Logger LOGGER = Logger.getLogger(ReplaceLoadBalancerConfigsCmd.class.getName());
+    private static final String s_name = "replaceloadbalancerconfigsresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.SCOPE,
+               type = CommandType.STRING,
+               required = true,
+               description = "the scope of the config: network, vpc or rule")
+    private String scope;
+
+    @Parameter(name = ApiConstants.NETWORK_ID,
+               type = CommandType.UUID,
+               entityType = NetworkResponse.class,
+               description = "the ID of network to update")
+    private Long networkId;
+
+    @Parameter(name = ApiConstants.VPC_ID,
+               type = CommandType.UUID,
+               entityType = VpcResponse.class,
+               description = "the ID of vpc to update")
+    private Long vpcId;
+
+    @Parameter(name = ApiConstants.LOAD_BALANCER_ID,
+               type = CommandType.UUID,
+               entityType = FirewallRuleResponse.class,
+               description = "the ID of the load balancer rule to update")
+    private Long loadBalancerId;
+
+    @Parameter(name = ApiConstants.CONFIG,
+               type = CommandType.MAP,
+               description = "configs list, Example: config[0].name=timout&config[0].value=60000")

Review comment:
       @sureshanaparti done.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland removed a comment on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland removed a comment on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-719435535


   @blueorangutan package


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-725295311


   all travis jobs fail as well


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-724970706


   @blueorangutan package


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-725434042


   @DaanHoogland a Trillian-Jenkins test job (centos7 mgmt + kvm-centos7) has been kicked to run smoke tests


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd closed pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd closed pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141


   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-685506323


   @blueorangutan package
   
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-671768562


   @blueorangutan package


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r491943641



##########
File path: api/src/main/java/com/cloud/network/lb/LoadBalancerConfigService.java
##########
@@ -0,0 +1,40 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.network.lb;

Review comment:
       > got one quarter into reviewing, so I will not pass judgement. looks good so far. We got a request on list to include this in 4.15, but as it requires a new svm template I'm not sure how realistic that is. I marked it 4.15 for now. (cc @weizhouapache @PaulAngus @rhtyd )
   
   @DaanHoogland it requires haproxy 1.8 to support HTTP2. 
   However, debian 10 already has haproxy 1.8 installed so new systemvm template is not required.
   https://packages.debian.org/buster/haproxy
   




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-713361497


   the password failure is being addressed in another PR, not related.
   I lost track of reviews, i know i got only partly through, @rhtyd @onitake do you approve? (i do, based on part of the code and smoke tests)


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-690349410


   <b>Trillian test result (tid-2712)</b>
   Environment: kvm-centos7 (x2), Advanced Networking with Mgmt server 7
   Total time taken: 55036 seconds
   Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr4141-t2712-kvm-centos7.zip
   Intermittent failure detected: /marvin/tests/smoke/test_kubernetes_clusters.py
   Intermittent failure detected: /marvin/tests/smoke/test_privategw_acl.py
   Intermittent failure detected: /marvin/tests/smoke/test_vpc_redundant.py
   Intermittent failure detected: /marvin/tests/smoke/test_hostha_kvm.py
   Smoke tests completed. 82 look OK, 3 have error(s)
   Only failed tests results shown below:
   
   
   Test | Result | Time (s) | Test File
   --- | --- | --- | ---
   test_02_vpc_privategw_static_routes | `Failure` | 245.75 | test_privategw_acl.py
   test_01_create_redundant_VPC_2tiers_4VMs_4IPs_4PF_ACL | `Failure` | 406.00 | test_vpc_redundant.py
   test_hostha_kvm_host_fencing | `Error` | 101.16 | test_hostha_kvm.py
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] GutoVeronezi commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
GutoVeronezi commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-870871956


   There is a lot of code addition, but none unit testing or javadoc. IMHO we should add they.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r520557627



##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/ReplaceLoadBalancerConfigsCmd.java
##########
@@ -0,0 +1,182 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig;
+import org.apache.commons.collections.MapUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "replaceLoadBalancerConfigs", description = "Replaces load balancer configs of vpc/network/rule",
+        responseObject = SuccessResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        since = "4.15",
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class ReplaceLoadBalancerConfigsCmd extends BaseAsyncCmd {
+    public static final Logger LOGGER = Logger.getLogger(ReplaceLoadBalancerConfigsCmd.class.getName());
+    private static final String s_name = "replaceloadbalancerconfigsresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.SCOPE,
+               type = CommandType.STRING,
+               required = true,
+               description = "the scope of the config: network, vpc or rule")
+    private String scope;
+
+    @Parameter(name = ApiConstants.NETWORK_ID,
+               type = CommandType.UUID,
+               entityType = NetworkResponse.class,
+               description = "the ID of network to update")
+    private Long networkId;
+
+    @Parameter(name = ApiConstants.VPC_ID,
+               type = CommandType.UUID,
+               entityType = VpcResponse.class,
+               description = "the ID of vpc to update")
+    private Long vpcId;
+
+    @Parameter(name = ApiConstants.LOAD_BALANCER_ID,
+               type = CommandType.UUID,
+               entityType = FirewallRuleResponse.class,
+               description = "the ID of the load balancer rule to update")
+    private Long loadBalancerId;
+
+    @Parameter(name = ApiConstants.CONFIG,
+               type = CommandType.MAP,
+               description = "configs list, Example: config[0].name=timout&config[0].value=60000")

Review comment:
       @sureshanaparti good point. I will change it.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-870556066


   @blueorangutan package


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] soreana commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
soreana commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-918884950


   @rhtyd @weizhouapache Sure let's do this.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] sureshanaparti commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
sureshanaparti commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-906185527


   ping @soreana can you please fix the conflicting files.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] soreana commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
soreana commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r668813079



##########
File path: server/src/main/java/com/cloud/api/ApiResponseHelper.java
##########
@@ -1040,6 +1043,78 @@ public LoadBalancerResponse createLoadBalancerResponse(LoadBalancer loadBalancer
         return lbResponse;
     }
 
+    @Override
+    public LoadBalancerConfigResponse createLoadBalancerConfigResponse(LoadBalancerConfig config) {
+        Network network = null;
+        Vpc vpc = null;
+        LoadBalancer lb = null;
+        if (config.getNetworkId() != null) {
+            network = ApiDBUtils.findNetworkById(config.getNetworkId());
+        }
+        if (config.getVpcId() != null) {
+            vpc = ApiDBUtils.findVpcById(config.getVpcId());
+        }
+        if (config.getLoadBalancerId() != null) {
+            lb = ApiDBUtils.findLoadBalancerById(config.getLoadBalancerId());
+        }
+        return setLoadBalancerConfigResponse(network, vpc, lb, config);
+    }
+
+    @Override
+    public List<LoadBalancerConfigResponse> createLoadBalancerConfigResponse(List<? extends LoadBalancerConfig> configs) {
+        List<LoadBalancerConfigResponse> lbConfigResponses = new ArrayList<LoadBalancerConfigResponse>();
+        if (configs == null || configs.size() == 0) {

Review comment:
       @GutoVeronezi As I mentioned before, `org.apache.commons.lang3.ArrayUtils` package don't have isEmpty method which accepts List object. I have to override it like:
   
   ```java
   ...
   ArrayUtils.isEmpty(new List[]{configs})
   ...
   ```
   
   It imposes unnecessary conversion. What do you think?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-792574751


   Packaging result: :heavy_multiplication_x: centos7 :heavy_multiplication_x: centos8 :heavy_multiplication_x: debian. SL-JID 53


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan removed a comment on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan removed a comment on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-721596004


   @DaanHoogland a Trillian-Jenkins test job (centos7 mgmt + kvm-centos7) has been kicked to run smoke tests


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-695978262


   <b>Trillian test result (tid-2801)</b>
   Environment: vmware-67u3 (x2), Advanced Networking with Mgmt server 7
   Total time taken: 50525 seconds
   Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr4141-t2801-vmware-67u3.zip
   Intermittent failure detected: /marvin/tests/smoke/test_kubernetes_supported_versions.py
   Intermittent failure detected: /marvin/tests/smoke/test_vpc_redundant.py
   Smoke tests completed. 84 look OK, 1 have error(s)
   Only failed tests results shown below:
   
   
   Test | Result | Time (s) | Test File
   --- | --- | --- | ---
   test_01_add_delete_kubernetes_supported_version | `Error` | 1808.60 | test_kubernetes_supported_versions.py
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-713717540


   @blueorangutan package 


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] soreana commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
soreana commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r670468405



##########
File path: core/src/main/java/com/cloud/network/HAProxyConfigurator.java
##########
@@ -531,42 +654,111 @@ private String getLbSubRuleForStickiness(final LoadBalancerTO lbTO) {
                 }
             }
             if (httpbasedStickiness) {
-                result.addAll(dstWithCookieSubRule);
+                backendConfigs.addAll(dstWithCookieSubRule);
             } else {
-                result.addAll(dstSubRule);
+                backendConfigs.addAll(dstSubRule);
             }
-            result.add(stickinessSubRule);
+            backendConfigs.add(stickinessSubRule);
         } else {
-            result.addAll(dstSubRule);
+            backendConfigs.addAll(dstSubRule);
         }
         if (stickinessSubRule != null && !destsAvailable) {
             s_logger.warn("Haproxy stickiness policy for lb rule: " + lbTO.getSrcIp() + ":" + lbTO.getSrcPort() + ": Not Applied, cause:  backends are unavailable");
         }
-        if (publicPort == NetUtils.HTTP_PORT && !keepAliveEnabled || httpbasedStickiness) {
+        boolean http = false;
+        String cfgLbHttp = lbConfigsMap.get(LoadBalancerConfigKey.LbHttp.key());
+        if (publicPort == NetUtils.HTTP_PORT && cfgLbHttp == null) {
+            http = true;
+        } else if (cfgLbHttp != null && cfgLbHttp.equalsIgnoreCase("true")) {
+            http = true;
+        }
+
+        boolean keepAliveEnabled = lbCmd.keepAliveEnabled;
+        String cfgLbHttpKeepalive = lbConfigsMap.get(LoadBalancerConfigKey.LbHttpKeepalive.key());
+        if (cfgLbHttpKeepalive != null && cfgLbHttpKeepalive.equalsIgnoreCase("true")) {
+            keepAliveEnabled = true;
+        } else if (cfgLbHttpKeepalive != null && cfgLbHttpKeepalive.equalsIgnoreCase("false")) {
+            keepAliveEnabled = false;
+        }
+
+        if (http || httpbasedStickiness || sslOffloading) {
             sb = new StringBuilder();
             sb.append("\t").append("mode http");
+            frontendConfigs.add(sb.toString());
+            backendConfigsForHttp.add(sb.toString());
+            if (keepAliveEnabled) {
+                sb = new StringBuilder();
+                sb.append("\t").append("no option forceclose");
+                frontendConfigs.add(sb.toString());
+                backendConfigsForHttp.add(sb.toString());
+            } else {
+                sb = new StringBuilder();
+                sb.append("\t").append("option httpclose");
+                frontendConfigs.add(sb.toString());
+                backendConfigsForHttp.add(sb.toString());
+            }
+        }
+
+        if (isTransparent) {
+            sb = new StringBuilder();
+            sb.append("frontend ").append(poolName);
             result.add(sb.toString());
+            result.addAll(frontendConfigs);
             sb = new StringBuilder();
-            sb.append("\t").append("option httpclose");
+            sb.append("\tacl local_subnet src ").append(lbCmd.getNetworkCidr());
+            sb.append("\n\tuse_backend ").append(poolName).append("-backend-local if local_subnet");
+            sb.append("\n\tdefault_backend ").append(poolName).append("-backend");
+            sb.append("\n\n");
+            sb.append("backend ").append(poolName).append("-backend");
+            result.add(sb.toString());
+            result.addAll(backendConfigsForHttp);
+            result.addAll(backendConfigs);
+            sb = new StringBuilder();
+            sb.append("\t").append("source 0.0.0.0 usesrc clientip");
+            sb.append("\n\n");

Review comment:
       @GutoVeronezi For line 707 ... 713, it is better to leave it as it is. It would be a long String.format expression and hard to read. I changed the remaining.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-671804215


   @blueorangutan test


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r520559488



##########
File path: core/src/main/java/com/cloud/network/HAProxyConfigurator.java
##########
@@ -531,42 +654,111 @@ private String getLbSubRuleForStickiness(final LoadBalancerTO lbTO) {
                 }
             }
             if (httpbasedStickiness) {
-                result.addAll(dstWithCookieSubRule);
+                backendConfigs.addAll(dstWithCookieSubRule);
             } else {
-                result.addAll(dstSubRule);
+                backendConfigs.addAll(dstSubRule);
             }
-            result.add(stickinessSubRule);
+            backendConfigs.add(stickinessSubRule);
         } else {
-            result.addAll(dstSubRule);
+            backendConfigs.addAll(dstSubRule);
         }
         if (stickinessSubRule != null && !destsAvailable) {
             s_logger.warn("Haproxy stickiness policy for lb rule: " + lbTO.getSrcIp() + ":" + lbTO.getSrcPort() + ": Not Applied, cause:  backends are unavailable");
         }
-        if (publicPort == NetUtils.HTTP_PORT && !keepAliveEnabled || httpbasedStickiness) {
+        boolean http = false;
+        String cfgLbHttp = lbConfigsMap.get(LoadBalancerConfigKey.LbHttp.key());
+        if (publicPort == NetUtils.HTTP_PORT && cfgLbHttp == null) {
+            http = true;
+        } else if (cfgLbHttp != null && cfgLbHttp.equalsIgnoreCase("true")) {
+            http = true;
+        }
+
+        boolean keepAliveEnabled = lbCmd.keepAliveEnabled;
+        String cfgLbHttpKeepalive = lbConfigsMap.get(LoadBalancerConfigKey.LbHttpKeepalive.key());
+        if (cfgLbHttpKeepalive != null && cfgLbHttpKeepalive.equalsIgnoreCase("true")) {
+            keepAliveEnabled = true;
+        } else if (cfgLbHttpKeepalive != null && cfgLbHttpKeepalive.equalsIgnoreCase("false")) {
+            keepAliveEnabled = false;
+        }
+
+        if (http || httpbasedStickiness || sslOffloading) {
             sb = new StringBuilder();
             sb.append("\t").append("mode http");
+            frontendConfigs.add(sb.toString());
+            backendConfigsForHttp.add(sb.toString());
+            if (keepAliveEnabled) {
+                sb = new StringBuilder();
+                sb.append("\t").append("no option forceclose");
+                frontendConfigs.add(sb.toString());
+                backendConfigsForHttp.add(sb.toString());
+            } else {
+                sb = new StringBuilder();
+                sb.append("\t").append("option httpclose");
+                frontendConfigs.add(sb.toString());
+                backendConfigsForHttp.add(sb.toString());
+            }
+        }
+
+        if (isTransparent) {
+            sb = new StringBuilder();
+            sb.append("frontend ").append(poolName);
             result.add(sb.toString());
+            result.addAll(frontendConfigs);
             sb = new StringBuilder();
-            sb.append("\t").append("option httpclose");
+            sb.append("\tacl local_subnet src ").append(lbCmd.getNetworkCidr());
+            sb.append("\n\tuse_backend ").append(poolName).append("-backend-local if local_subnet");
+            sb.append("\n\tdefault_backend ").append(poolName).append("-backend");
+            sb.append("\n\n");
+            sb.append("backend ").append(poolName).append("-backend");
+            result.add(sb.toString());
+            result.addAll(backendConfigsForHttp);
+            result.addAll(backendConfigs);
+            sb = new StringBuilder();
+            sb.append("\t").append("source 0.0.0.0 usesrc clientip");
+            sb.append("\n\n");
+            sb.append("backend ").append(poolName).append("-backend-local");
             result.add(sb.toString());
+            result.addAll(backendConfigsForHttp);
+            result.addAll(backendConfigs);
+        } else {
+            // add line like this: "listen  65_37_141_30-80\n\tbind 65.37.141.30:80"
+            sb = new StringBuilder();
+            sb.append("listen ").append(poolName);
+            result.add(sb.toString());
+            result.addAll(frontendConfigs);
+            result.addAll(backendConfigs);
         }
 
         result.add(blankLine);
         return result;
     }
 
-    private String generateStatsRule(final LoadBalancerConfigCommand lbCmd, final String ruleName, final String statsIp) {
+    private String generateStatsRule(final LoadBalancerConfigCommand lbCmd, final String ruleName, final String statsIp, HashMap<String, String> networkLbConfigsMap) {
+        String lbStatsEnable = networkLbConfigsMap.get(LoadBalancerConfigKey.LbStatsEnable.key());
+        if ( lbStatsEnable != null && !  lbStatsEnable.equalsIgnoreCase("true")) {
+            return "";
+        }

Review comment:
       @sureshanaparti yes. rules for stats will be generated, which is default behavior in cloudstack 4.14 and previous versions.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-697208850


   @rhtyd merged latest master into this branch.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-695810991


   @rhtyd a Trillian-Jenkins test job (centos7 mgmt + vmware-67u3) has been kicked to run smoke tests


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-664216138


   @blueorangutan package


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] soreana commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
soreana commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r670501607



##########
File path: core/src/main/java/com/cloud/network/HAProxyConfigurator.java
##########
@@ -531,42 +654,111 @@ private String getLbSubRuleForStickiness(final LoadBalancerTO lbTO) {
                 }
             }
             if (httpbasedStickiness) {
-                result.addAll(dstWithCookieSubRule);
+                backendConfigs.addAll(dstWithCookieSubRule);
             } else {
-                result.addAll(dstSubRule);
+                backendConfigs.addAll(dstSubRule);
             }
-            result.add(stickinessSubRule);
+            backendConfigs.add(stickinessSubRule);
         } else {
-            result.addAll(dstSubRule);
+            backendConfigs.addAll(dstSubRule);
         }
         if (stickinessSubRule != null && !destsAvailable) {
             s_logger.warn("Haproxy stickiness policy for lb rule: " + lbTO.getSrcIp() + ":" + lbTO.getSrcPort() + ": Not Applied, cause:  backends are unavailable");
         }
-        if (publicPort == NetUtils.HTTP_PORT && !keepAliveEnabled || httpbasedStickiness) {
+        boolean http = false;
+        String cfgLbHttp = lbConfigsMap.get(LoadBalancerConfigKey.LbHttp.key());
+        if (publicPort == NetUtils.HTTP_PORT && cfgLbHttp == null) {
+            http = true;
+        } else if (cfgLbHttp != null && cfgLbHttp.equalsIgnoreCase("true")) {
+            http = true;
+        }
+
+        boolean keepAliveEnabled = lbCmd.keepAliveEnabled;
+        String cfgLbHttpKeepalive = lbConfigsMap.get(LoadBalancerConfigKey.LbHttpKeepalive.key());
+        if (cfgLbHttpKeepalive != null && cfgLbHttpKeepalive.equalsIgnoreCase("true")) {
+            keepAliveEnabled = true;
+        } else if (cfgLbHttpKeepalive != null && cfgLbHttpKeepalive.equalsIgnoreCase("false")) {
+            keepAliveEnabled = false;
+        }
+
+        if (http || httpbasedStickiness || sslOffloading) {
             sb = new StringBuilder();
             sb.append("\t").append("mode http");
+            frontendConfigs.add(sb.toString());
+            backendConfigsForHttp.add(sb.toString());
+            if (keepAliveEnabled) {
+                sb = new StringBuilder();
+                sb.append("\t").append("no option forceclose");
+                frontendConfigs.add(sb.toString());
+                backendConfigsForHttp.add(sb.toString());
+            } else {
+                sb = new StringBuilder();
+                sb.append("\t").append("option httpclose");
+                frontendConfigs.add(sb.toString());
+                backendConfigsForHttp.add(sb.toString());
+            }

Review comment:
       I replaced it with String.format. In my opinion, writing a method for it would be over engineering 😄 




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-669057374


   @weizhouapache will this require a new systemvmtemplate?


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r493393783



##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerConfigCmd.java
##########
@@ -0,0 +1,215 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.LoadBalancerConfigResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.rules.LoadBalancer;
+import com.cloud.network.rules.LoadBalancerConfig;
+import com.cloud.network.rules.LoadBalancerConfig.Scope;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "createLoadBalancerConfig", description = "Creates a load balancer config",

Review comment:
       done

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerConfigCmd.java
##########
@@ -0,0 +1,215 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.LoadBalancerConfigResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.rules.LoadBalancer;
+import com.cloud.network.rules.LoadBalancerConfig;
+import com.cloud.network.rules.LoadBalancerConfig.Scope;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "createLoadBalancerConfig", description = "Creates a load balancer config",
+        responseObject = LoadBalancerConfigResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class CreateLoadBalancerConfigCmd extends BaseAsyncCreateCmd {
+    public static final Logger s_logger = Logger.getLogger(CreateLoadBalancerConfigCmd.class.getName());

Review comment:
       done




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-700696975


   Packaging result: ✔centos7 ✔centos8 ✔debian. JID-2105


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] sureshanaparti commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
sureshanaparti commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r520571068



##########
File path: core/src/main/java/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java
##########
@@ -72,4 +82,35 @@ public NicTO getNic() {
     public Long getVpcId() {
         return vpcId;
     }
+
+    public LoadBalancerConfigTO[] getNetworkLbConfigs() {
+        return this.networkLbConfigs;
+    }
+
+    public void setNetworkLbConfigs(List<? extends LoadBalancerConfig> networkLbConfigs) {
+        if (networkLbConfigs == null) {
+            networkLbConfigs = new ArrayList<LoadBalancerConfig>();
+        }
+        this.networkLbConfigs = new LoadBalancerConfigTO[networkLbConfigs.size()];

Review comment:
       @weizhouapache if your intention is to create an empty array, create `new LoadBalancerConfigTO[0]` and return when `networkLbConfigs` is null; else just return.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-725281348


   @blueorangutan test


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-721596004


   @DaanHoogland a Trillian-Jenkins test job (centos7 mgmt + kvm-centos7) has been kicked to run smoke tests


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-781959815


   Packaging result: ✖centos7 ✖centos8 ✖debian. JID-2747


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-689869313


   @blueorangutan test


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-695810935


   @blueorangutan test centos7 vmware-67u3
   
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] sureshanaparti commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
sureshanaparti commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r520549104



##########
File path: core/src/main/java/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java
##########
@@ -72,4 +82,35 @@ public NicTO getNic() {
     public Long getVpcId() {
         return vpcId;
     }
+
+    public LoadBalancerConfigTO[] getNetworkLbConfigs() {
+        return this.networkLbConfigs;
+    }
+
+    public void setNetworkLbConfigs(List<? extends LoadBalancerConfig> networkLbConfigs) {
+        if (networkLbConfigs == null) {
+            networkLbConfigs = new ArrayList<LoadBalancerConfig>();
+        }
+        this.networkLbConfigs = new LoadBalancerConfigTO[networkLbConfigs.size()];

Review comment:
       when `networkLbConfigs` is null, empty array is being created here. Is that the intention here? further, GC has to cleanup the reference for `networkLbConfigs`. same would be applicable for the similar code in this PR.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-671218525


   @blueorangutan package


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r589405897



##########
File path: ui/src/views/network/LbConfigTab.vue
##########
@@ -0,0 +1,341 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+<template>
+  <div>
+    <div>
+      <div class="form">
+        <div class="form__item">
+          <div class="form__label">{{ $t('label.lb.config.name') }}</div>
+          <br>
+          <a-select v-model="lbConfig.name" style="width: 100%;" @change="populateValues">
+            <a-select-option
+              v-for="config in globalLbConfigs"
+              :key="config.name">{{ config.name }}
+            </a-select-option>
+          </a-select>
+        </div>
+        <div class="form__item">
+          <div class="form__label">{{ $t('label.description') }}</div>
+          <br>
+          {{ lbConfig.description }}
+        </div>
+        <div class="form__item">
+          <div class="form__label">{{ $t('label.lb.config.default.value') }}</div>
+          <br>
+          {{ lbConfig.defaultvalue }}
+        </div>
+        <div class="form__item" ref="lbconfigValue">
+          <div class="form__label"><span class="form__required">*</span>{{ $t('label.lb.config.value') }}</div>
+          <br>
+          <a-input v-model="lbConfig.value"></a-input>
+          <span class="error-text">Required</span>
+        </div>
+        <div class="form__item">
+          <div class="form__label">{{ $t('label.action') }}</div>
+          <br>
+          <a-button :disabled="!('createLoadBalancerConfig' in $store.getters.apis)" type="primary" icon="plus" @click="addLbConfig">{{ $t('label.add') }}</a-button>
+        </div>
+      </div>
+    </div>
+
+    <a-divider/>
+
+    <a-table
+      size="small"
+      style="overflow-y: auto"
+      :loading="loading"
+      :columns="columns"
+      :dataSource="savedLbConfigs"
+      :pagination="false"
+      :rowKey="record => record.id">
+      <template slot="actions" slot-scope="record">
+        <a-button :disabled="!('deleteLoadBalancerConfig' in $store.getters.apis)" shape="circle" type="danger" icon="delete" @click="deleteLbConfig(record)" />
+      </template>
+    </a-table>
+    <a-pagination
+      class="pagination"
+      size="small"
+      :current="page"
+      :pageSize="pageSize"
+      :total="totalCount"
+      :showTotal="total => `Total ${total} items`"
+      :pageSizeOptions="['10', '20', '40', '80', '100']"
+      @change="handleChangePage"
+      @showSizeChange="handleChangePageSize"
+      showSizeChanger/>
+  </div>
+</template>
+
+<script>
+import { api } from '@/api'
+export default {
+  name: 'LbConfigTab',
+  props: {
+    resource: {
+      type: Object,
+      required: true
+    }
+  },
+  data () {
+    return {
+      loading: true,
+      globalLbConfigs: [],
+      savedLbConfigs: [],
+      lbConfig: {
+        scope: 'Network',
+        name: null,
+        description: null,
+        defaultvalue: null,
+        value: null,
+        forced: 'true',
+        networkid: this.resource.id
+      },
+      totalCount: 0,
+      page: 1,
+      pageSize: 10,
+      columns: [
+        {
+          title: this.$t('label.lb.config.name'),
+          dataIndex: 'name'
+        },
+        {
+          title: this.$t('label.description'),
+          dataIndex: 'description'
+        },
+        {
+          title: this.$t('label.lb.config.default.value'),
+          dataIndex: 'defaultvalue'
+        },
+        {
+          title: this.$t('label.lb.config.value'),
+          dataIndex: 'value'
+        },
+        {
+          title: this.$t('label.action'),
+          scopedSlots: { customRender: 'actions' }
+        }
+      ]
+    }
+  },
+  mounted () {
+    this.fetchData()
+  },
+  watch: {
+    resource: function (newItem, oldItem) {
+      if (!newItem || !newItem.id) {
+        return
+      }
+      this.resource = newItem
+      this.fetchData()
+    }
+  },
+  methods: {
+    fetchData () {
+      this.loading = true
+      // Populate all lb confings
+      api('listLoadBalancerConfigs', {
+        scope: 'Network',
+        listall: 'true',
+        networkid: this.resource.id
+      }).then(response => {
+        this.globalLbConfigs = response.listloadbalancerconfigsresponse.loadbalancerconfig || []
+        this.lbConfig.name = this.globalLbConfigs[0].name
+        this.lbConfig.description = this.globalLbConfigs[0].description
+        this.lbConfig.defaultvalue = this.globalLbConfigs[0].defaultvalue
+      }).finally(() => {
+        this.loading = false
+      })
+      // Fetch saved lb configs
+      api('listLoadBalancerConfigs', {
+        scope: 'Network',
+        networkid: this.resource.id
+      }).then(response => {
+        this.savedLbConfigs = response.listloadbalancerconfigsresponse.loadbalancerconfig || []
+        this.totalCount = response.listloadbalancerconfigsresponse.count || 0
+      }).finally(() => {
+        this.loading = false
+      })
+    },
+    deleteLbConfig (rule) {
+      this.loading = true
+      api('deleteLoadBalancerConfig', { id: rule.id }).then(response => {
+        this.$pollJob({
+          jobId: response.deleteloadbalancerconfigresponse.jobid,
+          successMessage: `Successfully removed Load Balancer config`,
+          successMethod: () => this.fetchData(),
+          errorMessage: 'Removing Load Balancer config failed',
+          errorMethod: () => this.fetchData(),
+          loadingMessage: `Deleting Load Balancer config...`,
+          catchMessage: 'Error encountered while fetching async job result',
+          catchMethod: () => this.fetchData()
+        })
+      }).catch(error => {
+        this.$notifyError(error)
+        this.fetchData()
+      })
+    },
+    addLbConfig () {
+      if (!this.lbConfig.value) {
+        this.$refs.lbconfigValue.classList.add('error')
+        return
+      } else {
+        this.$refs.lbconfigValue.classList.remove('error')
+      }
+      this.loading = true
+      api('createLoadBalancerConfig', { ...this.lbConfig }).then(response => {
+        this.$pollJob({
+          jobId: response.createloadbalancerconfigresponse.jobid,
+          successMessage: `Successfully created new load balancer config`,
+          successMethod: () => {
+            this.resetValues()
+            this.fetchData()
+          },
+          errorMessage: 'Adding new Load Balancer Config failed',
+          errorMethod: () => {
+            this.resetValues()
+            this.fetchData()
+          },
+          loadingMessage: `Adding new Load Balancer config...`,
+          catchMessage: 'Error encountered while fetching async job result',
+          catchMethod: () => {
+            this.resetValues()
+            this.fetchData()
+          }
+        })
+      }).catch(error => {
+        this.$notifyError(error)
+        this.resetValues()
+        this.fetchData()
+      })
+    },
+    resetValues () {
+      this.lbConfig.name = ''
+      this.lbConfig.description = null
+      this.lbConfig.defaultValue = null
+      this.lbConfig.value = null
+      this.lbConfig.networkid = this.resource.id
+    },
+    populateValues () {
+      for (let i = 0; i < this.globalLbConfigs.length; i++) {
+        if (this.lbConfig.name === this.globalLbConfigs[i].name) {
+          this.lbConfig.description = this.globalLbConfigs[i].description
+          this.lbConfig.defaultvalue = this.globalLbConfigs[i].defaultvalue
+        }
+      }
+    },
+    handleChangePage (page, pageSize) {
+      this.page = page
+      this.pageSize = pageSize
+      this.fetchData()
+    },
+    handleChangePageSize (currentPage, pageSize) {
+      this.page = currentPage
+      this.pageSize = pageSize
+      this.fetchData()
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.rule {
+  &-container {
+    display: flex;
+    width: 100%;
+    flex-wrap: wrap;
+    margin-right: -20px;
+    margin-bottom: -10px;
+  }
+  &__item {
+    padding-right: 20px;
+    margin-bottom: 20px;
+    @media (min-width: 760px) {
+      flex: 1;
+    }
+  }
+  &__title {
+    font-weight: bold;
+  }
+}
+.add-btn {
+  width: 100%;
+  padding-top: 15px;
+  padding-bottom: 15px;
+  height: auto;
+}
+.add-actions {
+  display: flex;
+  justify-content: flex-end;
+  margin-right: -20px;
+  margin-bottom: 20px;
+  @media (min-width: 760px) {
+    margin-top: 20px;
+  }
+  button {
+    margin-right: 20px;
+  }
+}
+.form {
+  display: flex;
+  margin-right: -20px;
+  margin-bottom: 20px;
+  flex-direction: column;
+  align-items: flex-start;
+  @media (min-width: 760px) {
+    flex-direction: row;
+  }
+  &__item {
+    display: flex;
+    flex-direction: column;
+    flex: 1;
+    padding-right: 20px;
+    margin-bottom: 20px;
+    @media (min-width: 760px) {
+      margin-bottom: 0;
+      flex: 1;
+    }
+    input,
+    .ant-select {
+      margin-top: auto;
+    }
+  }
+  &__label {
+    font-weight: bold;
+  }
+  &__required {
+    margin-right: 5px;
+    color: red;
+  }
+  .error-text {
+    display: none;
+    color: red;
+    font-size: 0.8rem;
+  }
+  .error {
+    input {
+      border-color: red;
+    }
+    .error-text {
+      display: block;
+    }
+  }
+}
+.pagination {
+  margin-top: 20px;
+}
+</style>

Review comment:
       @davidjumani thanks, it should be fixed now.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-720330101






----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] sureshanaparti commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
sureshanaparti commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r521856578



##########
File path: core/src/main/java/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java
##########
@@ -72,4 +82,35 @@ public NicTO getNic() {
     public Long getVpcId() {
         return vpcId;
     }
+
+    public LoadBalancerConfigTO[] getNetworkLbConfigs() {
+        return this.networkLbConfigs;
+    }
+
+    public void setNetworkLbConfigs(List<? extends LoadBalancerConfig> networkLbConfigs) {
+        if (networkLbConfigs == null) {
+            networkLbConfigs = new ArrayList<LoadBalancerConfig>();
+        }
+        this.networkLbConfigs = new LoadBalancerConfigTO[networkLbConfigs.size()];

Review comment:
       @weizhouapache any update here?




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-661720098


   > @weizhouapache Can you provide test packages or should we build the PR ourselves?
   > I haven't done a custom CloudStack build in a while, I'm not sure if I even have the necessary build/packaging environment any more...
   
   @onitake yes, sure. could you please tell me what os version you use ?


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-713166256


   <b>Trillian test result (tid-3014)</b>
   Environment: kvm-centos7 (x2), Advanced Networking with Mgmt server 7
   Total time taken: 40829 seconds
   Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr4141-t3014-kvm-centos7.zip
   Intermittent failure detected: /marvin/tests/smoke/test_kubernetes_clusters.py
   Intermittent failure detected: /marvin/tests/smoke/test_vpc_redundant.py
   Intermittent failure detected: /marvin/tests/smoke/test_hostha_kvm.py
   Smoke tests completed. 84 look OK, 1 have error(s)
   Only failed tests results shown below:
   
   
   Test | Result | Time (s) | Test File
   --- | --- | --- | ---
   test_hostha_kvm_host_fencing | `Error` | 175.69 | test_hostha_kvm.py
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland removed a comment on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland removed a comment on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-671768562


   @blueorangutan package


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] soreana commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
soreana commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-871194029


   @weizhouapache Sure! I asked Neven to make a room for it.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] ravening commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
ravening commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-918881853


   > > Ping @weizhouapache I think some more work may be needed on this as now Debian 11 has moved to haproxy 2.x, should this be targeted for next milestone. I worry it may not be stable within two weeks, ie current tentative RC date.
   > 
   > @rhtyd it is ok to me.
   > @ravening @soreana what do you think ?
   
   @rhtyd @weizhouapache yes lets move it out of this milestone as this will not make it in time


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland removed a comment on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland removed a comment on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-724921732


   @blueorangutan package


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-782065776


   Packaging result: ✖centos7 ✖centos8 ✖debian. JID-2762


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] ravening commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
ravening commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-998883819


   @weizhouapache @rhtyd I have created a new pr for this in https://github.com/apache/cloudstack/pull/5799


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-673966948


   Packaging result: ✔centos7 ✔debian. JID-1752


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-694637897


   @rhtyd a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-700677564


   @blueorangutan package 


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-724956311


   Packaging result: ✖centos7 ✖centos8 ✖debian. JID-2353


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r467488786



##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerConfigCmd.java
##########
@@ -0,0 +1,215 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.LoadBalancerConfigResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.rules.LoadBalancer;
+import com.cloud.network.rules.LoadBalancerConfig;
+import com.cloud.network.rules.LoadBalancerConfig.Scope;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "createLoadBalancerConfig", description = "Creates a load balancer config",

Review comment:
       should we add a `since` attribute

##########
File path: api/src/main/java/com/cloud/agent/api/to/LoadBalancerConfigTO.java
##########
@@ -0,0 +1,42 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.agent.api.to;
+
+import com.cloud.network.rules.LoadBalancerConfig;

Review comment:
       should we use org.apache.cloudstack as base packages for new classes?

##########
File path: api/src/main/java/com/cloud/network/rules/LoadBalancerConfig.java
##########
@@ -0,0 +1,83 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.network.rules;

Review comment:
       package

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerConfigCmd.java
##########
@@ -0,0 +1,215 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.LoadBalancerConfigResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.rules.LoadBalancer;
+import com.cloud.network.rules.LoadBalancerConfig;
+import com.cloud.network.rules.LoadBalancerConfig.Scope;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "createLoadBalancerConfig", description = "Creates a load balancer config",
+        responseObject = LoadBalancerConfigResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class CreateLoadBalancerConfigCmd extends BaseAsyncCreateCmd {
+    public static final Logger s_logger = Logger.getLogger(CreateLoadBalancerConfigCmd.class.getName());

Review comment:
       name convention for `public static final` is all capital. I'd suggest `LOGGER` as name.

##########
File path: api/src/main/java/com/cloud/network/lb/LoadBalancerConfigService.java
##########
@@ -0,0 +1,40 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.network.lb;

Review comment:
       base package for new classes




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-694636583


   Packaging result: ✔centos7 ✖centos8 ✖debian. JID-2030


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-725331953


   > all travis jobs fail as well
   
   @DaanHoogland  travis should be ok now.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan removed a comment on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan removed a comment on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-725272274


   @DaanHoogland a Trillian-Jenkins test job (centos7 mgmt + kvm-centos7) has been kicked to run smoke tests


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-671768886


   @DaanHoogland a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-712745542


   @DaanHoogland a Trillian-Jenkins test job (centos7 mgmt + kvm-centos7) has been kicked to run smoke tests


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-678880837


   Packaging result: ✖centos7 ✖centos8 ✖debian. JID-1810


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-673406508


   @blueorangutan package


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-721612271


   @blueorangutan test


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-791515883


   Packaging result: ✖centos7 ✖centos8 ✖debian. JID-2873


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-724991313


   Packaging result: ✔centos7 ✔centos8 ✔debian. JID-2361


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache edited a comment on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache edited a comment on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-661720098


   > @weizhouapache Can you provide test packages or should we build the PR ourselves?
   > I haven't done a custom CloudStack build in a while, I'm not sure if I even have the necessary build/packaging environment any more...
   
   @onitake we can provide the packages. could you please tell me what os version you use ?


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-673937017


   @rhtyd a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache closed pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache closed pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141


   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] soreana commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
soreana commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r667896446



##########
File path: api/src/main/java/com/cloud/agent/api/to/LoadBalancerTO.java
##########
@@ -179,6 +182,22 @@ public boolean isInline() {
         return inline;
     }
 
+    public LoadBalancerConfigTO[] getLbConfigs() {
+        return this.lbConfigs;
+    }
+
+    public void setLbConfigs(List<? extends LoadBalancerConfig> lbConfigs) {
+        if (lbConfigs == null || lbConfigs.size() == 0) {

Review comment:
       @GutoVeronezi `org.apache.commons.lang3.ArrayUtils` package don't have isEmpty method which accepts List object. I have to override it like:
   ```
   ...
   ArrayUtils.isEmpty(new List[]{lbConfigs})
   ...
   ```
   It imposes unnecessary conversion. What do you think?

##########
File path: api/src/main/java/com/cloud/agent/api/to/LoadBalancerTO.java
##########
@@ -179,6 +182,22 @@ public boolean isInline() {
         return inline;
     }
 
+    public LoadBalancerConfigTO[] getLbConfigs() {
+        return this.lbConfigs;
+    }
+
+    public void setLbConfigs(List<? extends LoadBalancerConfig> lbConfigs) {
+        if (lbConfigs == null || lbConfigs.size() == 0) {

Review comment:
       @GutoVeronezi `org.apache.commons.lang3.ArrayUtils` package don't have isEmpty method which accepts List object. I have to override it like:
   
   ```java
   ...
   ArrayUtils.isEmpty(new List[]{lbConfigs})
   ...
   ```
   
   It imposes unnecessary conversion. What do you think?

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerConfigCmd.java
##########
@@ -0,0 +1,216 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.LoadBalancerConfigResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig.Scope;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.rules.LoadBalancer;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "createLoadBalancerConfig", description = "Creates a load balancer config",
+        responseObject = LoadBalancerConfigResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        since = "4.15",
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class CreateLoadBalancerConfigCmd extends BaseAsyncCreateCmd {
+    public static final Logger LOGGER = Logger.getLogger(CreateLoadBalancerConfigCmd.class.getName());
+
+    private static final String s_name = "createloadbalancerconfigresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.SCOPE,
+               type = CommandType.STRING,
+               required = true,
+               description = "the scope of the config: network, vpc or rule")
+    private String scope;
+
+    @Parameter(name = ApiConstants.NETWORK_ID,
+               type = CommandType.UUID,
+               entityType = NetworkResponse.class,
+               description = "the ID of network to update")
+    private Long networkId;
+
+    @Parameter(name = ApiConstants.VPC_ID,
+               type = CommandType.UUID,
+               entityType = VpcResponse.class,
+               description = "the ID of vpc to update")
+    private Long vpcId;
+
+    @Parameter(name = ApiConstants.LOAD_BALANCER_ID,
+               type = CommandType.UUID,
+               entityType = FirewallRuleResponse.class,
+               description = "the ID of the load balancer rule to update")
+    private Long loadBalancerId;
+
+    @Parameter(name = ApiConstants.NAME,
+               type = CommandType.STRING,
+               required = true,
+               description = "name of the load balancer config")
+    private String name;
+
+    @Parameter(name = ApiConstants.VALUE,
+               type = CommandType.STRING,
+               required = true,
+               description = "value of the load balancer config")
+    private String value;
+
+    @Parameter(name = ApiConstants.FORCED,
+               type = CommandType.BOOLEAN,
+               required = false,
+               description = "Force add a load balancer config. Existing config will be removed")
+    private Boolean forced;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getScope() {
+        return scope;
+    }
+
+    public Long getVpcId() {
+        return vpcId;
+    }
+
+    public Long getNetworkId() {
+        return networkId;
+    }
+
+    public Long getLoadBalancerId() {
+        return loadBalancerId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public boolean isForced() {
+        return (forced != null) ? forced : false;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public void execute() {
+
+        LoadBalancerConfig config = null;
+        try {
+            config = _entityMgr.findById(LoadBalancerConfig.class, getEntityId());
+            LoadBalancerConfigResponse lbConfigResponse = new LoadBalancerConfigResponse();
+            if (config != null) {
+                lbConfigResponse = _responseGenerator.createLoadBalancerConfigResponse(config);
+                setResponseObject(lbConfigResponse);
+            }
+            lbConfigResponse.setResponseName(getCommandName());
+        } catch (Exception ex) {
+            LOGGER.warn("Failed to create LB config due to exception ", ex);
+        }
+    }
+
+    @Override
+    public void create() {
+        try {
+            LoadBalancerConfig result = _lbConfigService.createLoadBalancerConfig(this);
+            this.setEntityId(result.getId());
+            this.setEntityUuid(result.getUuid());
+        } catch (InvalidParameterValueException e) {
+            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage());
+        }
+    }
+
+    @Override
+    public String getSyncObjType() {
+        if (networkId != null) {
+            return BaseAsyncCmd.networkSyncObject;
+        } else if (vpcId != null) {

Review comment:
       @GutoVeronezi I didn't get your comment. Could you please tell me why it doesn't make any difference?

##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerConfigCmd.java
##########
@@ -0,0 +1,216 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.LoadBalancerConfigResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig.Scope;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.rules.LoadBalancer;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "createLoadBalancerConfig", description = "Creates a load balancer config",
+        responseObject = LoadBalancerConfigResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        since = "4.15",
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class CreateLoadBalancerConfigCmd extends BaseAsyncCreateCmd {
+    public static final Logger LOGGER = Logger.getLogger(CreateLoadBalancerConfigCmd.class.getName());
+
+    private static final String s_name = "createloadbalancerconfigresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.SCOPE,
+               type = CommandType.STRING,
+               required = true,
+               description = "the scope of the config: network, vpc or rule")
+    private String scope;
+
+    @Parameter(name = ApiConstants.NETWORK_ID,
+               type = CommandType.UUID,
+               entityType = NetworkResponse.class,
+               description = "the ID of network to update")
+    private Long networkId;
+
+    @Parameter(name = ApiConstants.VPC_ID,
+               type = CommandType.UUID,
+               entityType = VpcResponse.class,
+               description = "the ID of vpc to update")
+    private Long vpcId;
+
+    @Parameter(name = ApiConstants.LOAD_BALANCER_ID,
+               type = CommandType.UUID,
+               entityType = FirewallRuleResponse.class,
+               description = "the ID of the load balancer rule to update")
+    private Long loadBalancerId;
+
+    @Parameter(name = ApiConstants.NAME,
+               type = CommandType.STRING,
+               required = true,
+               description = "name of the load balancer config")
+    private String name;
+
+    @Parameter(name = ApiConstants.VALUE,
+               type = CommandType.STRING,
+               required = true,
+               description = "value of the load balancer config")
+    private String value;
+
+    @Parameter(name = ApiConstants.FORCED,
+               type = CommandType.BOOLEAN,
+               required = false,
+               description = "Force add a load balancer config. Existing config will be removed")
+    private Boolean forced;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getScope() {
+        return scope;
+    }
+
+    public Long getVpcId() {
+        return vpcId;
+    }
+
+    public Long getNetworkId() {
+        return networkId;
+    }
+
+    public Long getLoadBalancerId() {
+        return loadBalancerId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public boolean isForced() {
+        return (forced != null) ? forced : false;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public void execute() {
+
+        LoadBalancerConfig config = null;
+        try {
+            config = _entityMgr.findById(LoadBalancerConfig.class, getEntityId());
+            LoadBalancerConfigResponse lbConfigResponse = new LoadBalancerConfigResponse();
+            if (config != null) {
+                lbConfigResponse = _responseGenerator.createLoadBalancerConfigResponse(config);
+                setResponseObject(lbConfigResponse);
+            }
+            lbConfigResponse.setResponseName(getCommandName());
+        } catch (Exception ex) {
+            LOGGER.warn("Failed to create LB config due to exception ", ex);
+        }
+    }
+
+    @Override
+    public void create() {
+        try {
+            LoadBalancerConfig result = _lbConfigService.createLoadBalancerConfig(this);
+            this.setEntityId(result.getId());
+            this.setEntityUuid(result.getUuid());
+        } catch (InvalidParameterValueException e) {
+            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage());
+        }
+    }
+
+    @Override
+    public String getSyncObjType() {
+        if (networkId != null) {
+            return BaseAsyncCmd.networkSyncObject;
+        } else if (vpcId != null) {
+            return BaseAsyncCmd.vpcSyncObject;
+        }
+        return null;
+    }
+
+    @Override
+    public Long getSyncObjId() {
+        if (networkId != null) {
+            return getNetworkId();
+        } else if (vpcId != null) {

Review comment:
       @GutoVeronezi Also here. Could you please tell me why it doesn't make any difference?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache closed pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache closed pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141


   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-870556066


   @blueorangutan package


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-700794559


   @blueorangutan test


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-673173251


   <b>Trillian test result (tid-2382)</b>
   Environment: kvm-centos7 (x2), Advanced Networking with Mgmt server 7
   Total time taken: 50655 seconds
   Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr4141-t2382-kvm-centos7.zip
   Intermittent failure detected: /marvin/tests/smoke/test_loadbalance.py
   Intermittent failure detected: /marvin/tests/smoke/test_network.py
   Intermittent failure detected: /marvin/tests/smoke/test_usage.py
   Intermittent failure detected: /marvin/tests/smoke/test_vpc_redundant.py
   Smoke tests completed. 80 look OK, 3 have error(s)
   Only failed tests results shown below:
   
   
   Test | Result | Time (s) | Test File
   --- | --- | --- | ---
   test_01_create_lb_rule_src_nat | `Error` | 0.10 | test_loadbalance.py
   test_02_create_lb_rule_non_nat | `Error` | 0.04 | test_loadbalance.py
   test_assign_and_removal_lb | `Error` | 0.06 | test_loadbalance.py
   test_delete_account | `Error` | 79.75 | test_network.py
   test_reboot_router | `Error` | 179.46 | test_network.py
   test_releaseIP | `Error` | 60.47 | test_network.py
   test_network_rules_acquired_public_ip_3_Load_Balancer_Rule | `Error` | 3.23 | test_network.py
   test_01_lb_usage | `Error` | 0.05 | test_usage.py
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-673936824


   @blueorangutan package


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-694637747


   @blueorangutan package 


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] soreana commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
soreana commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r670501607



##########
File path: core/src/main/java/com/cloud/network/HAProxyConfigurator.java
##########
@@ -531,42 +654,111 @@ private String getLbSubRuleForStickiness(final LoadBalancerTO lbTO) {
                 }
             }
             if (httpbasedStickiness) {
-                result.addAll(dstWithCookieSubRule);
+                backendConfigs.addAll(dstWithCookieSubRule);
             } else {
-                result.addAll(dstSubRule);
+                backendConfigs.addAll(dstSubRule);
             }
-            result.add(stickinessSubRule);
+            backendConfigs.add(stickinessSubRule);
         } else {
-            result.addAll(dstSubRule);
+            backendConfigs.addAll(dstSubRule);
         }
         if (stickinessSubRule != null && !destsAvailable) {
             s_logger.warn("Haproxy stickiness policy for lb rule: " + lbTO.getSrcIp() + ":" + lbTO.getSrcPort() + ": Not Applied, cause:  backends are unavailable");
         }
-        if (publicPort == NetUtils.HTTP_PORT && !keepAliveEnabled || httpbasedStickiness) {
+        boolean http = false;
+        String cfgLbHttp = lbConfigsMap.get(LoadBalancerConfigKey.LbHttp.key());
+        if (publicPort == NetUtils.HTTP_PORT && cfgLbHttp == null) {
+            http = true;
+        } else if (cfgLbHttp != null && cfgLbHttp.equalsIgnoreCase("true")) {
+            http = true;
+        }
+
+        boolean keepAliveEnabled = lbCmd.keepAliveEnabled;
+        String cfgLbHttpKeepalive = lbConfigsMap.get(LoadBalancerConfigKey.LbHttpKeepalive.key());
+        if (cfgLbHttpKeepalive != null && cfgLbHttpKeepalive.equalsIgnoreCase("true")) {
+            keepAliveEnabled = true;
+        } else if (cfgLbHttpKeepalive != null && cfgLbHttpKeepalive.equalsIgnoreCase("false")) {
+            keepAliveEnabled = false;
+        }
+
+        if (http || httpbasedStickiness || sslOffloading) {
             sb = new StringBuilder();
             sb.append("\t").append("mode http");
+            frontendConfigs.add(sb.toString());
+            backendConfigsForHttp.add(sb.toString());
+            if (keepAliveEnabled) {
+                sb = new StringBuilder();
+                sb.append("\t").append("no option forceclose");
+                frontendConfigs.add(sb.toString());
+                backendConfigsForHttp.add(sb.toString());
+            } else {
+                sb = new StringBuilder();
+                sb.append("\t").append("option httpclose");
+                frontendConfigs.add(sb.toString());
+                backendConfigsForHttp.add(sb.toString());
+            }

Review comment:
       I replaced it with String.format. In my opinion, writing a method for it would be over engineering :D




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-768187529


   > @rhtyd @weizhouapache I think it would make sense to remove the legacy UI modification from this PR. Correct?
   > 
   > And FYI, [apache/cloudstack-primate#778](https://github.com/apache/cloudstack-primate/pull/778) was ported back to the main ACS repo: #4619
   
   @onitake yes, legacy ui has been removed from master.
   since this pr is for master, so ui changes in this pr should be removed.
   I will update this pr.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-694618531


   @blueorangutan package 


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-684790756


   Packaging result: ✔centos7 ✖centos8 ✔debian. JID-1871


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-725271886


   @blueorangutan test


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-782082038


   Packaging result: ✖centos7 ✖centos8 ✖debian. JID-2767


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-673406901


   @rhtyd a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan removed a comment on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan removed a comment on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-720349355


   @rhtyd a Trillian-Jenkins test job (centos7 mgmt + kvm-centos7) has been kicked to run smoke tests


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-700497267


   @blueorangutan package


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland removed a comment on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland removed a comment on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-725271886


   @blueorangutan test


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] soreana commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
soreana commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r668813079



##########
File path: server/src/main/java/com/cloud/api/ApiResponseHelper.java
##########
@@ -1040,6 +1043,78 @@ public LoadBalancerResponse createLoadBalancerResponse(LoadBalancer loadBalancer
         return lbResponse;
     }
 
+    @Override
+    public LoadBalancerConfigResponse createLoadBalancerConfigResponse(LoadBalancerConfig config) {
+        Network network = null;
+        Vpc vpc = null;
+        LoadBalancer lb = null;
+        if (config.getNetworkId() != null) {
+            network = ApiDBUtils.findNetworkById(config.getNetworkId());
+        }
+        if (config.getVpcId() != null) {
+            vpc = ApiDBUtils.findVpcById(config.getVpcId());
+        }
+        if (config.getLoadBalancerId() != null) {
+            lb = ApiDBUtils.findLoadBalancerById(config.getLoadBalancerId());
+        }
+        return setLoadBalancerConfigResponse(network, vpc, lb, config);
+    }
+
+    @Override
+    public List<LoadBalancerConfigResponse> createLoadBalancerConfigResponse(List<? extends LoadBalancerConfig> configs) {
+        List<LoadBalancerConfigResponse> lbConfigResponses = new ArrayList<LoadBalancerConfigResponse>();
+        if (configs == null || configs.size() == 0) {

Review comment:
       @GutoVeronezi As I mentioned before, `org.apache.commons.lang3.ArrayUtils` package don't have isEmpty method which accepts List object. I have to override it like:
   
   ```java
   ...
   ArrayUtils.isEmpty(new List[]{Configs})
   ...
   ```
   
   It imposes unnecessary conversion. What do you think?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd removed a comment on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd removed a comment on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-720349041


   @blueorangutan test 


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-870556324






-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-671804819


   @DaanHoogland a Trillian-Jenkins test job (centos7 mgmt + kvm-centos7) has been kicked to run smoke tests


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache closed pull request #4141: [WIP] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache closed pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141


   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-684548779


   @rhtyd a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-673589333


   > @weizhouapache can you look at failures? Thanks
   
   @rhtyd pushed a commit to fix it. can you re-kick off the tests ?


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-725272274


   @DaanHoogland a Trillian-Jenkins test job (centos7 mgmt + kvm-centos7) has been kicked to run smoke tests


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] soreana commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
soreana commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r670522084



##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerConfigCmd.java
##########
@@ -0,0 +1,216 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.LoadBalancerConfigResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig.Scope;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.rules.LoadBalancer;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "createLoadBalancerConfig", description = "Creates a load balancer config",
+        responseObject = LoadBalancerConfigResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        since = "4.15",
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class CreateLoadBalancerConfigCmd extends BaseAsyncCreateCmd {
+    public static final Logger LOGGER = Logger.getLogger(CreateLoadBalancerConfigCmd.class.getName());
+
+    private static final String s_name = "createloadbalancerconfigresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.SCOPE,
+               type = CommandType.STRING,
+               required = true,
+               description = "the scope of the config: network, vpc or rule")
+    private String scope;
+
+    @Parameter(name = ApiConstants.NETWORK_ID,
+               type = CommandType.UUID,
+               entityType = NetworkResponse.class,
+               description = "the ID of network to update")
+    private Long networkId;
+
+    @Parameter(name = ApiConstants.VPC_ID,
+               type = CommandType.UUID,
+               entityType = VpcResponse.class,
+               description = "the ID of vpc to update")
+    private Long vpcId;
+
+    @Parameter(name = ApiConstants.LOAD_BALANCER_ID,
+               type = CommandType.UUID,
+               entityType = FirewallRuleResponse.class,
+               description = "the ID of the load balancer rule to update")
+    private Long loadBalancerId;
+
+    @Parameter(name = ApiConstants.NAME,
+               type = CommandType.STRING,
+               required = true,
+               description = "name of the load balancer config")
+    private String name;
+
+    @Parameter(name = ApiConstants.VALUE,
+               type = CommandType.STRING,
+               required = true,
+               description = "value of the load balancer config")
+    private String value;
+
+    @Parameter(name = ApiConstants.FORCED,
+               type = CommandType.BOOLEAN,
+               required = false,
+               description = "Force add a load balancer config. Existing config will be removed")
+    private Boolean forced;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getScope() {
+        return scope;
+    }
+
+    public Long getVpcId() {
+        return vpcId;
+    }
+
+    public Long getNetworkId() {
+        return networkId;
+    }
+
+    public Long getLoadBalancerId() {
+        return loadBalancerId;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public boolean isForced() {
+        return (forced != null) ? forced : false;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public void execute() {
+
+        LoadBalancerConfig config = null;
+        try {
+            config = _entityMgr.findById(LoadBalancerConfig.class, getEntityId());
+            LoadBalancerConfigResponse lbConfigResponse = new LoadBalancerConfigResponse();
+            if (config != null) {
+                lbConfigResponse = _responseGenerator.createLoadBalancerConfigResponse(config);
+                setResponseObject(lbConfigResponse);
+            }
+            lbConfigResponse.setResponseName(getCommandName());
+        } catch (Exception ex) {
+            LOGGER.warn("Failed to create LB config due to exception ", ex);
+        }
+    }
+
+    @Override
+    public void create() {
+        try {
+            LoadBalancerConfig result = _lbConfigService.createLoadBalancerConfig(this);
+            this.setEntityId(result.getId());
+            this.setEntityUuid(result.getUuid());
+        } catch (InvalidParameterValueException e) {
+            throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage());
+        }
+    }
+
+    @Override
+    public String getSyncObjType() {
+        if (networkId != null) {
+            return BaseAsyncCmd.networkSyncObject;
+        } else if (vpcId != null) {
+            return BaseAsyncCmd.vpcSyncObject;
+        }
+        return null;
+    }
+
+    @Override
+    public Long getSyncObjId() {
+        if (networkId != null) {
+            return getNetworkId();
+        } else if (vpcId != null) {

Review comment:
       @GutoVeronezi addAnd deprecated. I is better not to add `addAndNotNull` to `SearchCriteria`. Could you please help me to find an appropriate method to rewrite this section?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-724921732


   @blueorangutan package


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-870572497


   Packaging result: :heavy_check_mark: centos7 :heavy_check_mark: centos8 :heavy_check_mark: debian. SL-JID 419


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-881276913


   @soreana can you resolve that confict, please?


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] sureshanaparti commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
sureshanaparti commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r521857388



##########
File path: api/src/main/java/com/cloud/agent/api/to/LoadBalancerTO.java
##########
@@ -179,6 +182,21 @@ public boolean isInline() {
         return inline;
     }
 
+    public LoadBalancerConfigTO[] getLbConfigs() {
+        return this.lbConfigs;
+    }
+
+    public void setLbConfigs(List<? extends LoadBalancerConfig> lbConfigs) {
+        if (lbConfigs == null) {
+            lbConfigs = new ArrayList<LoadBalancerConfig>();
+        }
+        this.lbConfigs = new LoadBalancerConfigTO[lbConfigs.size()];

Review comment:
       @weizhouapache advised changes to improve similar code, consider this as well. thanks.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-795050810


   Packaging result: :heavy_check_mark: centos7 :heavy_check_mark: centos8 :heavy_check_mark: debian. SL-JID 68


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-671218822


   @DaanHoogland a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-700497899


   @rhtyd a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] sureshanaparti commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
sureshanaparti commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-870546848


   @weizhouapache can you please fix the conflicts here. thanks.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-669956049


   > @weizhouapache will this require a new systemvmtemplate?
   
   @rhtyd it requires haproxy 1.8+ for http2 support. As I remember haproxy 1.8 is installed in debian10 systemvm template. No other changes is needed in systemvm template 


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-725281765


   @DaanHoogland a Trillian-Jenkins test job (centos7 mgmt + kvm-centos7) has been kicked to run smoke tests


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan removed a comment on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan removed a comment on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-671218822






----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-671803098


   Packaging result: ✔centos7 ✔debian. JID-1706


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r668882005



##########
File path: server/src/main/java/com/cloud/api/ApiResponseHelper.java
##########
@@ -1040,6 +1043,78 @@ public LoadBalancerResponse createLoadBalancerResponse(LoadBalancer loadBalancer
         return lbResponse;
     }
 
+    @Override
+    public LoadBalancerConfigResponse createLoadBalancerConfigResponse(LoadBalancerConfig config) {
+        Network network = null;
+        Vpc vpc = null;
+        LoadBalancer lb = null;
+        if (config.getNetworkId() != null) {
+            network = ApiDBUtils.findNetworkById(config.getNetworkId());
+        }
+        if (config.getVpcId() != null) {
+            vpc = ApiDBUtils.findVpcById(config.getVpcId());
+        }
+        if (config.getLoadBalancerId() != null) {
+            lb = ApiDBUtils.findLoadBalancerById(config.getLoadBalancerId());
+        }
+        return setLoadBalancerConfigResponse(network, vpc, lb, config);
+    }
+
+    @Override
+    public List<LoadBalancerConfigResponse> createLoadBalancerConfigResponse(List<? extends LoadBalancerConfig> configs) {
+        List<LoadBalancerConfigResponse> lbConfigResponses = new ArrayList<LoadBalancerConfigResponse>();
+        if (configs == null || configs.size() == 0) {

Review comment:
       @soreana use CollectionUtils, not ArrayUtils




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache closed pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache closed pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141


   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan removed a comment on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan removed a comment on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-721612964


   @DaanHoogland a Trillian-Jenkins test job (centos7 mgmt + kvm-centos7) has been kicked to run smoke tests


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-695810935


   @blueorangutan test centos7 vmware-67u3
   
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-689532285


   @rhtyd a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-679968897


   @weizhouapache can you fix the conflict and kick pking? I'll help with testing, thnx


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan removed a comment on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan removed a comment on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-782082038






----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r491943641



##########
File path: api/src/main/java/com/cloud/network/lb/LoadBalancerConfigService.java
##########
@@ -0,0 +1,40 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.network.lb;

Review comment:
       > got one quarter into reviewing, so I will not pass judgement. looks good so far. We got a request on list to include this in 4.15, but as it requires a new svm template I'm not sure how realistic that is. I marked it 4.15 for now. (cc @weizhouapache @PaulAngus @rhtyd )
   
   @DaanHoogland it requires haproxy 1.8 to support HTTP2. 
   However, debian 10 already has haproxy 1.8 installed so new systemvm template is not required.
   https://packages.debian.org/buster/haproxy
   




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-701141691


   <b>Trillian test result (tid-2874)</b>
   Environment: kvm-centos7 (x2), Advanced Networking with Mgmt server 7
   Total time taken: 41755 seconds
   Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr4141-t2874-kvm-centos7.zip
   Intermittent failure detected: /marvin/tests/smoke/test_internal_lb.py
   Intermittent failure detected: /marvin/tests/smoke/test_kubernetes_clusters.py
   Intermittent failure detected: /marvin/tests/smoke/test_outofbandmanagement_nestedplugin.py
   Intermittent failure detected: /marvin/tests/smoke/test_ssvm.py
   Intermittent failure detected: /marvin/tests/smoke/test_vpc_redundant.py
   Intermittent failure detected: /marvin/tests/smoke/test_vpc_vpn.py
   Intermittent failure detected: /marvin/tests/smoke/test_hostha_kvm.py
   Smoke tests completed. 81 look OK, 4 have error(s)
   Only failed tests results shown below:
   
   
   Test | Result | Time (s) | Test File
   --- | --- | --- | ---
   test_03_deploy_and_upgrade_kubernetes_cluster | `Failure` | 203.32 | test_kubernetes_clusters.py
   test_03_ssvm_internals | `Failure` | 3.08 | test_ssvm.py
   test_03_create_redundant_VPC_1tier_2VMs_2IPs_2PF_ACL_reboot_routers | `Failure` | 292.74 | test_vpc_redundant.py
   test_hostha_kvm_host_fencing | `Error` | 171.74 | test_hostha_kvm.py
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] soreana commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
soreana commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r668803267



##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/ReplaceLoadBalancerConfigsCmd.java
##########
@@ -0,0 +1,173 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "replaceLoadBalancerConfigs", description = "Replaces load balancer configs of vpc/network/rule",
+        responseObject = SuccessResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        since = "4.15",
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class ReplaceLoadBalancerConfigsCmd extends BaseAsyncCmd {
+    public static final Logger LOGGER = Logger.getLogger(ReplaceLoadBalancerConfigsCmd.class.getName());
+    private static final String s_name = "replaceloadbalancerconfigsresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.SCOPE,
+               type = CommandType.STRING,
+               required = true,
+               description = "the scope of the config: network, vpc or rule")
+    private String scope;
+
+    @Parameter(name = ApiConstants.NETWORK_ID,
+               type = CommandType.UUID,
+               entityType = NetworkResponse.class,
+               description = "the ID of network to update")
+    private Long networkId;
+
+    @Parameter(name = ApiConstants.VPC_ID,
+               type = CommandType.UUID,
+               entityType = VpcResponse.class,
+               description = "the ID of vpc to update")
+    private Long vpcId;
+
+    @Parameter(name = ApiConstants.LOAD_BALANCER_ID,
+               type = CommandType.UUID,
+               entityType = FirewallRuleResponse.class,
+               description = "the ID of the load balancer rule to update")
+    private Long loadBalancerId;
+
+    @Parameter(name = ApiConstants.CONFIG,
+               type = CommandType.MAP,
+               description = "configs list, Example: config[0].global.maxconn=40960")
+    private Map<String, String> configList;
+
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public String getScope() {
+        return scope;
+    }
+
+    public Long getVpcId() {
+        return vpcId;
+    }
+
+    public Long getNetworkId() {
+        return networkId;
+    }
+
+    public Long getLoadBalancerId() {
+        return loadBalancerId;
+    }
+
+    public Map<String, String> getConfigList() {
+        if (configList == null || configList.isEmpty()) {
+            return null;
+        }
+
+        Collection<String> paramsCollection = configList.values();
+        return (Map<String, String>) (paramsCollection.toArray())[0];

Review comment:
       @GutoVeronezi  I'm agree with you, It might cause a class cast exception. Maybe @ravening or @weizhouapache can provide more clarification.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] sureshanaparti commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
sureshanaparti commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r520549104



##########
File path: core/src/main/java/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java
##########
@@ -72,4 +82,35 @@ public NicTO getNic() {
     public Long getVpcId() {
         return vpcId;
     }
+
+    public LoadBalancerConfigTO[] getNetworkLbConfigs() {
+        return this.networkLbConfigs;
+    }
+
+    public void setNetworkLbConfigs(List<? extends LoadBalancerConfig> networkLbConfigs) {
+        if (networkLbConfigs == null) {
+            networkLbConfigs = new ArrayList<LoadBalancerConfig>();
+        }
+        this.networkLbConfigs = new LoadBalancerConfigTO[networkLbConfigs.size()];

Review comment:
       when `networkLbConfigs` is null, empty array is being created here. Is that the intention here? further, GC has to cleanup the reference for `networkLbConfigs`.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-714280529


   @rhtyd smke tests have passed already


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-781988296


   @blueorangutan package


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-723971542


   @blueorangutan package


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] sureshanaparti commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
sureshanaparti commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r520539831



##########
File path: api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/ReplaceLoadBalancerConfigsCmd.java
##########
@@ -0,0 +1,182 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.loadbalancer;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.FirewallRuleResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.api.response.VpcResponse;
+import org.apache.cloudstack.network.lb.LoadBalancerConfig;
+import org.apache.commons.collections.MapUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.network.Network;
+import com.cloud.network.vpc.Vpc;
+
+@APICommand(name = "replaceLoadBalancerConfigs", description = "Replaces load balancer configs of vpc/network/rule",
+        responseObject = SuccessResponse.class,
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false,
+        since = "4.15",
+        authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
+public class ReplaceLoadBalancerConfigsCmd extends BaseAsyncCmd {
+    public static final Logger LOGGER = Logger.getLogger(ReplaceLoadBalancerConfigsCmd.class.getName());
+    private static final String s_name = "replaceloadbalancerconfigsresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.SCOPE,
+               type = CommandType.STRING,
+               required = true,
+               description = "the scope of the config: network, vpc or rule")
+    private String scope;
+
+    @Parameter(name = ApiConstants.NETWORK_ID,
+               type = CommandType.UUID,
+               entityType = NetworkResponse.class,
+               description = "the ID of network to update")
+    private Long networkId;
+
+    @Parameter(name = ApiConstants.VPC_ID,
+               type = CommandType.UUID,
+               entityType = VpcResponse.class,
+               description = "the ID of vpc to update")
+    private Long vpcId;
+
+    @Parameter(name = ApiConstants.LOAD_BALANCER_ID,
+               type = CommandType.UUID,
+               entityType = FirewallRuleResponse.class,
+               description = "the ID of the load balancer rule to update")
+    private Long loadBalancerId;
+
+    @Parameter(name = ApiConstants.CONFIG,
+               type = CommandType.MAP,
+               description = "configs list, Example: config[0].name=timout&config[0].value=60000")

Review comment:
       Map here can take key and value inputs, for example config[0].timeout=60000. no need to explicitly mark name/key & value.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-697146522


   @weizhouapache can you address the conflict? Thanks


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-700530768


   Packaging result: ✔centos7 ✖centos8 ✔debian. JID-2099


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-698165034


   @blueorangutan test


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-694646072


   Packaging result: ✔centos7 ✔centos8 ✔debian. JID-2033


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland removed a comment on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland removed a comment on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-671218525


   @blueorangutan package


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache closed pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache closed pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141


   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-719435535


   @blueorangutan package


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-684742322


   @blueorangutan package
   
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] onitake commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
onitake commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-661706140


   @weizhouapache Can you provide test packages or should we build the PR ourselves?
   I haven't done a custom CloudStack build in a while, I'm not sure if I even have the necessary build/packaging environment any more...


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-682423004


   ping @weizhouapache @ustcweizhou 


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-717816084


   @weizhouapache looks like there is a merge conflict, can you address that?
   
   Sorry for the delay in replying; given we're in code freeze now, should we consider this an enhancement (a major one btw) and merge, or push for 4.16 - @DaanHoogland @PaulAngus ?


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-694646541


   @rhtyd a Trillian-Jenkins test job (centos7 mgmt + vmware-67u3) has been kicked to run smoke tests


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-689531149


   Packaging result: ✔centos7 ✖centos8 ✖debian. JID-1933


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-724971321


   @DaanHoogland a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-781989317


   @rhtyd a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache closed pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache closed pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141


   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] onitake commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
onitake commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-768156475


   @rhtyd @weizhouapache I think it would make sense to remove the legacy UI modification from this PR. Correct?
   
   And FYI, https://github.com/apache/cloudstack-primate/pull/778 was ported back to the main ACS repo: https://github.com/apache/cloudstack/pull/4619


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r520552327



##########
File path: core/src/main/java/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java
##########
@@ -72,4 +82,35 @@ public NicTO getNic() {
     public Long getVpcId() {
         return vpcId;
     }
+
+    public LoadBalancerConfigTO[] getNetworkLbConfigs() {
+        return this.networkLbConfigs;
+    }
+
+    public void setNetworkLbConfigs(List<? extends LoadBalancerConfig> networkLbConfigs) {
+        if (networkLbConfigs == null) {
+            networkLbConfigs = new ArrayList<LoadBalancerConfig>();
+        }
+        this.networkLbConfigs = new LoadBalancerConfigTO[networkLbConfigs.size()];

Review comment:
       > when `networkLbConfigs` is null, empty array is being created here. Is that the intention here? further, GC has to cleanup the reference for `networkLbConfigs`. same would be applicable for the similar code in this PR.
   
   @sureshanaparti so your suggestion is ?




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-871131162


   @ravening @soreana 
   could you have a look at @GutoVeronezi 's remarks ?
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland removed a comment on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland removed a comment on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-721612271


   @blueorangutan test


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r493297124



##########
File path: api/src/main/java/com/cloud/agent/api/to/LoadBalancerConfigTO.java
##########
@@ -0,0 +1,42 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.agent.api.to;
+
+import com.cloud.network.rules.LoadBalancerConfig;

Review comment:
       > should we use org.apache.cloudstack as base packages for new classes?
   
   @DaanHoogland all TO files are put into api/src/main/java/com/cloud/agent/api/to/, maybe we can move them together
   ```
   # ls -l api/src/main/java/com/cloud/agent/api/to/
   total 160
   -rw-r--r-- 1 root root  2951 Sep  3 09:35 DatadiskTO.java
   -rw-r--r-- 1 root root   912 Sep 22 14:35 DataObjectType.java
   -rw-r--r-- 1 root root  1021 Sep  3 09:35 DataStoreTO.java
   -rw-r--r-- 1 root root  1125 Sep  3 09:35 DataTO.java
   -rw-r--r-- 1 root root  1826 Sep  3 09:35 DhcpTO.java
   -rw-r--r-- 1 root root  3063 Sep  3 09:35 DiskTO.java
   -rw-r--r-- 1 root root  1280 Sep  3 09:35 DpdkTO.java
   -rw-r--r-- 1 root root  9205 Sep  3 09:35 FirewallRuleTO.java
   -rw-r--r-- 1 root root  1930 Sep  3 09:35 GPUDeviceTO.java
   -rw-r--r-- 1 root root  2749 Sep  3 09:35 HostTO.java
   -rw-r--r-- 1 root root  3576 Sep  3 09:35 IpAddressTO.java
   -rw-r--r-- 1 root root  1361 Sep 22 14:41 LoadBalancerConfigTO.java
   -rw-r--r-- 1 root root 22026 Sep 22 14:41 LoadBalancerTO.java
   -rw-r--r-- 1 root root  1983 Sep  3 09:35 MonitorServiceTO.java
   -rw-r--r-- 1 root root  4209 Sep  3 09:35 NetworkACLTO.java
   -rw-r--r-- 1 root root  5352 Sep  3 09:35 NetworkTO.java
   -rw-r--r-- 1 root root  1966 Sep 23 08:12 NfsTO.java
   -rw-r--r-- 1 root root  3105 Sep  3 09:35 NicTO.java
   -rw-r--r-- 1 root root  2199 Sep  3 09:35 PortForwardingRuleTO.java
   -rw-r--r-- 1 root root  9934 Sep  3 09:35 S3TO.java
   -rw-r--r-- 1 root root  2930 Sep  3 09:35 StaticNatRuleTO.java
   -rw-r--r-- 1 root root  2058 Sep  3 09:35 StorageFilerTO.java
   -rw-r--r-- 1 root root  2256 Sep  3 09:35 SwiftTO.java
   -rw-r--r-- 1 root root  1718 Sep  3 09:35 TemplateTO.java
   -rw-r--r-- 1 root root 10206 Sep 23 08:10 VirtualMachineTO.java
   -rw-r--r-- 1 root root  5387 Sep  3 09:35 VolumeTO.java
   
   ```




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-661698180


   @andrijapanicsb @svenvogel @rhtyd @DaanHoogland @onitake 
   This PR is ready for review and testing !
   
   Any suggestions and comments are welcome !
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] soreana commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
soreana commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r668889927



##########
File path: server/src/main/java/com/cloud/api/ApiResponseHelper.java
##########
@@ -1040,6 +1043,78 @@ public LoadBalancerResponse createLoadBalancerResponse(LoadBalancer loadBalancer
         return lbResponse;
     }
 
+    @Override
+    public LoadBalancerConfigResponse createLoadBalancerConfigResponse(LoadBalancerConfig config) {
+        Network network = null;
+        Vpc vpc = null;
+        LoadBalancer lb = null;
+        if (config.getNetworkId() != null) {
+            network = ApiDBUtils.findNetworkById(config.getNetworkId());
+        }
+        if (config.getVpcId() != null) {
+            vpc = ApiDBUtils.findVpcById(config.getVpcId());
+        }
+        if (config.getLoadBalancerId() != null) {
+            lb = ApiDBUtils.findLoadBalancerById(config.getLoadBalancerId());
+        }
+        return setLoadBalancerConfigResponse(network, vpc, lb, config);
+    }
+
+    @Override
+    public List<LoadBalancerConfigResponse> createLoadBalancerConfigResponse(List<? extends LoadBalancerConfig> configs) {
+        List<LoadBalancerConfigResponse> lbConfigResponses = new ArrayList<LoadBalancerConfigResponse>();
+        if (configs == null || configs.size() == 0) {

Review comment:
       @weizhouapache Thanks, will do that!




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-684547683


   @blueorangutan package


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-673390755


   @weizhouapache can you look at failures? Thanks


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] sureshanaparti commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
sureshanaparti commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r521931122



##########
File path: core/src/main/java/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java
##########
@@ -72,4 +82,35 @@ public NicTO getNic() {
     public Long getVpcId() {
         return vpcId;
     }
+
+    public LoadBalancerConfigTO[] getNetworkLbConfigs() {
+        return this.networkLbConfigs;
+    }
+
+    public void setNetworkLbConfigs(List<? extends LoadBalancerConfig> networkLbConfigs) {
+        if (networkLbConfigs == null) {
+            networkLbConfigs = new ArrayList<LoadBalancerConfig>();
+        }
+        this.networkLbConfigs = new LoadBalancerConfigTO[networkLbConfigs.size()];

Review comment:
       > @sureshanaparti this has been changed in commit
   > [1ccff82](https://github.com/apache/cloudstack/commit/1ccff8298166d66479d303b5be9196c23c8d0814)
   
   thanks @weizhouapache verified.
   




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan removed a comment on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan removed a comment on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-720330671






----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-689531720


   @blueorangutan package 


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-678879595


   @blueorangutan package 


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-686907703






----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-712745073


   @blueorangutan test


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r521925476



##########
File path: core/src/main/java/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java
##########
@@ -72,4 +82,35 @@ public NicTO getNic() {
     public Long getVpcId() {
         return vpcId;
     }
+
+    public LoadBalancerConfigTO[] getNetworkLbConfigs() {
+        return this.networkLbConfigs;
+    }
+
+    public void setNetworkLbConfigs(List<? extends LoadBalancerConfig> networkLbConfigs) {
+        if (networkLbConfigs == null) {
+            networkLbConfigs = new ArrayList<LoadBalancerConfig>();
+        }
+        this.networkLbConfigs = new LoadBalancerConfigTO[networkLbConfigs.size()];

Review comment:
       @sureshanaparti this has been changed in commit
   https://github.com/apache/cloudstack/pull/4141/commits/1ccff8298166d66479d303b5be9196c23c8d0814

##########
File path: api/src/main/java/com/cloud/agent/api/to/LoadBalancerTO.java
##########
@@ -179,6 +182,21 @@ public boolean isInline() {
         return inline;
     }
 
+    public LoadBalancerConfigTO[] getLbConfigs() {
+        return this.lbConfigs;
+    }
+
+    public void setLbConfigs(List<? extends LoadBalancerConfig> lbConfigs) {
+        if (lbConfigs == null) {
+            lbConfigs = new ArrayList<LoadBalancerConfig>();
+        }
+        this.lbConfigs = new LoadBalancerConfigTO[lbConfigs.size()];

Review comment:
       @sureshanaparti this has been changed in commit  as well 
   https://github.com/apache/cloudstack/pull/4141/commits/1ccff8298166d66479d303b5be9196c23c8d0814




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r493393599



##########
File path: api/src/main/java/com/cloud/network/lb/LoadBalancerConfigService.java
##########
@@ -0,0 +1,40 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.network.lb;

Review comment:
       > base package for new classes
   
   done




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] rhtyd commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
rhtyd commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-698124537


   @blueorangutan package 


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-781930873


   @rhtyd a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-781989815


   @rhtyd a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] soreana commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
soreana commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r670501607



##########
File path: core/src/main/java/com/cloud/network/HAProxyConfigurator.java
##########
@@ -531,42 +654,111 @@ private String getLbSubRuleForStickiness(final LoadBalancerTO lbTO) {
                 }
             }
             if (httpbasedStickiness) {
-                result.addAll(dstWithCookieSubRule);
+                backendConfigs.addAll(dstWithCookieSubRule);
             } else {
-                result.addAll(dstSubRule);
+                backendConfigs.addAll(dstSubRule);
             }
-            result.add(stickinessSubRule);
+            backendConfigs.add(stickinessSubRule);
         } else {
-            result.addAll(dstSubRule);
+            backendConfigs.addAll(dstSubRule);
         }
         if (stickinessSubRule != null && !destsAvailable) {
             s_logger.warn("Haproxy stickiness policy for lb rule: " + lbTO.getSrcIp() + ":" + lbTO.getSrcPort() + ": Not Applied, cause:  backends are unavailable");
         }
-        if (publicPort == NetUtils.HTTP_PORT && !keepAliveEnabled || httpbasedStickiness) {
+        boolean http = false;
+        String cfgLbHttp = lbConfigsMap.get(LoadBalancerConfigKey.LbHttp.key());
+        if (publicPort == NetUtils.HTTP_PORT && cfgLbHttp == null) {
+            http = true;
+        } else if (cfgLbHttp != null && cfgLbHttp.equalsIgnoreCase("true")) {
+            http = true;
+        }
+
+        boolean keepAliveEnabled = lbCmd.keepAliveEnabled;
+        String cfgLbHttpKeepalive = lbConfigsMap.get(LoadBalancerConfigKey.LbHttpKeepalive.key());
+        if (cfgLbHttpKeepalive != null && cfgLbHttpKeepalive.equalsIgnoreCase("true")) {
+            keepAliveEnabled = true;
+        } else if (cfgLbHttpKeepalive != null && cfgLbHttpKeepalive.equalsIgnoreCase("false")) {
+            keepAliveEnabled = false;
+        }
+
+        if (http || httpbasedStickiness || sslOffloading) {
             sb = new StringBuilder();
             sb.append("\t").append("mode http");
+            frontendConfigs.add(sb.toString());
+            backendConfigsForHttp.add(sb.toString());
+            if (keepAliveEnabled) {
+                sb = new StringBuilder();
+                sb.append("\t").append("no option forceclose");
+                frontendConfigs.add(sb.toString());
+                backendConfigsForHttp.add(sb.toString());
+            } else {
+                sb = new StringBuilder();
+                sb.append("\t").append("option httpclose");
+                frontendConfigs.add(sb.toString());
+                backendConfigsForHttp.add(sb.toString());
+            }

Review comment:
       I replaced it with String.format. In my opinion, writing a method for it would be over engineering :lay




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-664217085


   @rhtyd a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] soreana commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
soreana commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r668810151



##########
File path: core/src/main/java/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java
##########
@@ -72,4 +81,36 @@ public NicTO getNic() {
     public Long getVpcId() {
         return vpcId;
     }
+
+    public LoadBalancerConfigTO[] getNetworkLbConfigs() {
+        return this.networkLbConfigs;
+    }
+
+    public void setNetworkLbConfigs(List<? extends LoadBalancerConfig> networkLbConfigs) {
+        if (networkLbConfigs == null || networkLbConfigs.size() == 0) {

Review comment:
       @GutoVeronezi, As I mentioned before, `org.apache.commons.lang3.ArrayUtils` package don't have isEmpty method which accepts List object. I have to override it like:
   
   ```java
   ...
   ArrayUtils.isEmpty(new List[]{lbConfigs})
   ...
   ```
   
   It imposes unnecessary conversion. What do you think?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] luhaijiao commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
luhaijiao commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-678879368


   It's a nice feature, is it possible to have it in 4.15 ?  


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-721595255


   @blueorangutan test


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-698124881






----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] blueorangutan commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
blueorangutan commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-724922419


   @DaanHoogland a Jenkins job has been kicked to build packages. I'll keep you posted as I make progress.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] sureshanaparti commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
sureshanaparti commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-870546848


   @weizhouapache can you please fix the conflicts here. thanks.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] DaanHoogland commented on a change in pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
DaanHoogland commented on a change in pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#discussion_r514958102



##########
File path: api/src/main/java/com/cloud/agent/api/to/LoadBalancerConfigTO.java
##########
@@ -0,0 +1,42 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package com.cloud.agent.api.to;
+
+import com.cloud.network.rules.LoadBalancerConfig;

Review comment:
       Do they need to be together? I think we should put all new ones in org.apache.cloudstack and worry about a cleanup on idle time. (no biggy)




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] weizhouapache closed pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
weizhouapache closed pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [cloudstack] kodesmon commented on pull request #4141: [New feature] Load balancer customization (haproxy-based)

Posted by GitBox <gi...@apache.org>.
kodesmon commented on pull request #4141:
URL: https://github.com/apache/cloudstack/pull/4141#issuecomment-758071019


   Hi guys, is anybody looking at this issue at this moment? I think it's very useful to upload ssl certificates to load balancers, it's a very use case.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org