mirror of https://github.com/apache/cloudstack.git
Add `pre-commit` workflow with 3 Git hooks (#6273)
Co-authored-by: dahn <daan@onecht.net>
This commit is contained in:
parent
a85973a0ca
commit
00426ede46
|
|
@ -15,7 +15,7 @@
|
|||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
name: Lint Code Base
|
||||
name: Lint
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
|
|
@ -31,7 +31,7 @@ jobs:
|
|||
permissions:
|
||||
contents: read # for actions/checkout to fetch code
|
||||
statuses: write # for github/super-linter to mark status of each linter run
|
||||
name: SuperLinter Check
|
||||
name: Super-Linter Check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
|
|
@ -39,10 +39,28 @@ jobs:
|
|||
with:
|
||||
# Full git history is needed to get a proper list of changed files within `super-linter`
|
||||
fetch-depth: 0
|
||||
- name: SuperLinter
|
||||
- name: Super-Linter
|
||||
uses: github/super-linter@v4
|
||||
env:
|
||||
DEFAULT_BRANCH: main
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
VALIDATE_ALL_CODEBASE: false
|
||||
VALIDATE_PYTHON_FLAKE8: true
|
||||
pre-commit:
|
||||
name: Run pre-commit
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check Out
|
||||
uses: actions/checkout@v3
|
||||
- name: Install
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install pre-commit
|
||||
- name: Set PY
|
||||
run: echo "PY=$(python -VV | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: ~/.cache/pre-commit
|
||||
key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }}
|
||||
- name: Run pre-commit
|
||||
run: pre-commit run --all-files
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
---
|
||||
default_stages: [commit, push]
|
||||
default_language_version:
|
||||
# force all unspecified Python hooks to run python3
|
||||
python: python3
|
||||
minimum_pre_commit_version: "2.18.0"
|
||||
repos:
|
||||
- repo: meta
|
||||
hooks:
|
||||
- id: identity
|
||||
- id: check-hooks-apply
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.1.0
|
||||
hooks:
|
||||
#- id: check-added-large-files
|
||||
#- id: check-case-conflict
|
||||
#- id: check-executables-have-shebangs
|
||||
#- id: check-merge-conflict
|
||||
#- id: check-vcs-permalinks
|
||||
#- id: check-yaml
|
||||
#- id: detect-private-key
|
||||
#- id: end-of-file-fixer
|
||||
#- id: fix-byte-order-marker
|
||||
- id: mixed-line-ending
|
||||
files: \.(java|py)$
|
||||
# - id: trailing-whitespace
|
||||
0
api/src/main/java/org/apache/cloudstack/api/command/admin/direct/download/UploadTemplateDirectDownloadCertificateCmd.java
Executable file → Normal file
0
api/src/main/java/org/apache/cloudstack/api/command/admin/direct/download/UploadTemplateDirectDownloadCertificateCmd.java
Executable file → Normal file
|
|
@ -1,61 +1,61 @@
|
|||
// 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.host;
|
||||
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import java.util.Arrays;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Test;
|
||||
import org.junit.Before;
|
||||
|
||||
public class HostVOTest {
|
||||
HostVO host;
|
||||
ServiceOfferingVO offering;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
host = new HostVO();
|
||||
offering = new ServiceOfferingVO("TestSO", 0, 0, 0, 0, 0,
|
||||
false, "TestSO", false,VirtualMachine.Type.User,false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoSO() {
|
||||
assertFalse(host.checkHostServiceOfferingTags(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoTag() {
|
||||
assertTrue(host.checkHostServiceOfferingTags(offering));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRightTag() {
|
||||
host.setHostTags(Arrays.asList("tag1","tag2"));
|
||||
offering.setHostTag("tag2,tag1");
|
||||
assertTrue(host.checkHostServiceOfferingTags(offering));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrongTag() {
|
||||
host.setHostTags(Arrays.asList("tag1","tag2"));
|
||||
offering.setHostTag("tag2,tag4");
|
||||
assertFalse(host.checkHostServiceOfferingTags(offering));
|
||||
}
|
||||
}
|
||||
// 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.host;
|
||||
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import java.util.Arrays;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Test;
|
||||
import org.junit.Before;
|
||||
|
||||
public class HostVOTest {
|
||||
HostVO host;
|
||||
ServiceOfferingVO offering;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
host = new HostVO();
|
||||
offering = new ServiceOfferingVO("TestSO", 0, 0, 0, 0, 0,
|
||||
false, "TestSO", false,VirtualMachine.Type.User,false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoSO() {
|
||||
assertFalse(host.checkHostServiceOfferingTags(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoTag() {
|
||||
assertTrue(host.checkHostServiceOfferingTags(offering));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRightTag() {
|
||||
host.setHostTags(Arrays.asList("tag1","tag2"));
|
||||
offering.setHostTag("tag2,tag1");
|
||||
assertTrue(host.checkHostServiceOfferingTags(offering));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrongTag() {
|
||||
host.setHostTags(Arrays.asList("tag1","tag2"));
|
||||
offering.setHostTag("tag2,tag4");
|
||||
assertFalse(host.checkHostServiceOfferingTags(offering));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,26 @@
|
|||
// 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.baremetal.database;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
/**
|
||||
* Created by frank on 5/8/14.
|
||||
*/
|
||||
public interface BaremetalRctDao extends GenericDao<BaremetalRctVO, Long> {
|
||||
}
|
||||
// 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.baremetal.database;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
/**
|
||||
* Created by frank on 5/8/14.
|
||||
*/
|
||||
public interface BaremetalRctDao extends GenericDao<BaremetalRctVO, Long> {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,26 @@
|
|||
// 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.baremetal.database;
|
||||
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
|
||||
/**
|
||||
* Created by frank on 5/8/14.
|
||||
*/
|
||||
public class BaremetalRctDaoImpl extends GenericDaoBase<BaremetalRctVO, Long> implements BaremetalRctDao {
|
||||
}
|
||||
// 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.baremetal.database;
|
||||
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
|
||||
/**
|
||||
* Created by frank on 5/8/14.
|
||||
*/
|
||||
public class BaremetalRctDaoImpl extends GenericDaoBase<BaremetalRctVO, Long> implements BaremetalRctDao {
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,82 +1,82 @@
|
|||
// 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.baremetal.database;
|
||||
|
||||
import org.apache.cloudstack.api.Identity;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Created by frank on 5/8/14.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "baremetal_rct")
|
||||
public class BaremetalRctVO implements InternalIdentity, Identity {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private long id;
|
||||
|
||||
@Column(name = "uuid")
|
||||
private String uuid = UUID.randomUUID().toString();
|
||||
|
||||
@Column(name = "url")
|
||||
private String url;
|
||||
|
||||
@Column(name = "rct")
|
||||
private String rct;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public void setUuid(String uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getRct() {
|
||||
return rct;
|
||||
}
|
||||
|
||||
public void setRct(String rct) {
|
||||
this.rct = rct;
|
||||
}
|
||||
}
|
||||
// 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.baremetal.database;
|
||||
|
||||
import org.apache.cloudstack.api.Identity;
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Created by frank on 5/8/14.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "baremetal_rct")
|
||||
public class BaremetalRctVO implements InternalIdentity, Identity {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private long id;
|
||||
|
||||
@Column(name = "uuid")
|
||||
private String uuid = UUID.randomUUID().toString();
|
||||
|
||||
@Column(name = "url")
|
||||
private String url;
|
||||
|
||||
@Column(name = "rct")
|
||||
private String rct;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public void setUuid(String uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getRct() {
|
||||
return rct;
|
||||
}
|
||||
|
||||
public void setRct(String rct) {
|
||||
this.rct = rct;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,125 +1,125 @@
|
|||
// 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.baremetal.manager;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by frank on 5/8/14.
|
||||
*/
|
||||
public class BaremetalRct {
|
||||
public static class SwitchEntry {
|
||||
private String ip;
|
||||
private String username;
|
||||
private String password;
|
||||
private String type;
|
||||
|
||||
public String getIp() {
|
||||
return ip;
|
||||
}
|
||||
|
||||
public void setIp(String ip) {
|
||||
this.ip = ip;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
|
||||
public static class HostEntry {
|
||||
private String uuid;
|
||||
private String mac;
|
||||
private String port;
|
||||
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public void setUuid(String uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
public String getMac() {
|
||||
return mac;
|
||||
}
|
||||
|
||||
public void setMac(String mac) {
|
||||
this.mac = mac;
|
||||
}
|
||||
|
||||
public String getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(String port) {
|
||||
this.port = port;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Rack {
|
||||
private SwitchEntry l2Switch;
|
||||
private List<HostEntry> hosts;
|
||||
|
||||
public SwitchEntry getL2Switch() {
|
||||
return l2Switch;
|
||||
}
|
||||
|
||||
public void setL2Switch(SwitchEntry l2Switch) {
|
||||
this.l2Switch = l2Switch;
|
||||
}
|
||||
|
||||
public List<HostEntry> getHosts() {
|
||||
return hosts;
|
||||
}
|
||||
|
||||
public void setHosts(List<HostEntry> hosts) {
|
||||
this.hosts = hosts;
|
||||
}
|
||||
}
|
||||
|
||||
private List<Rack> racks;
|
||||
|
||||
public List<Rack> getRacks() {
|
||||
return racks;
|
||||
}
|
||||
|
||||
public void setRacks(List<Rack> racks) {
|
||||
this.racks = racks;
|
||||
}
|
||||
}
|
||||
// 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.baremetal.manager;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by frank on 5/8/14.
|
||||
*/
|
||||
public class BaremetalRct {
|
||||
public static class SwitchEntry {
|
||||
private String ip;
|
||||
private String username;
|
||||
private String password;
|
||||
private String type;
|
||||
|
||||
public String getIp() {
|
||||
return ip;
|
||||
}
|
||||
|
||||
public void setIp(String ip) {
|
||||
this.ip = ip;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
|
||||
public static class HostEntry {
|
||||
private String uuid;
|
||||
private String mac;
|
||||
private String port;
|
||||
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public void setUuid(String uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
public String getMac() {
|
||||
return mac;
|
||||
}
|
||||
|
||||
public void setMac(String mac) {
|
||||
this.mac = mac;
|
||||
}
|
||||
|
||||
public String getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(String port) {
|
||||
this.port = port;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Rack {
|
||||
private SwitchEntry l2Switch;
|
||||
private List<HostEntry> hosts;
|
||||
|
||||
public SwitchEntry getL2Switch() {
|
||||
return l2Switch;
|
||||
}
|
||||
|
||||
public void setL2Switch(SwitchEntry l2Switch) {
|
||||
this.l2Switch = l2Switch;
|
||||
}
|
||||
|
||||
public List<HostEntry> getHosts() {
|
||||
return hosts;
|
||||
}
|
||||
|
||||
public void setHosts(List<HostEntry> hosts) {
|
||||
this.hosts = hosts;
|
||||
}
|
||||
}
|
||||
|
||||
private List<Rack> racks;
|
||||
|
||||
public List<Rack> getRacks() {
|
||||
return racks;
|
||||
}
|
||||
|
||||
public void setRacks(List<Rack> racks) {
|
||||
this.racks = racks;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,43 +1,43 @@
|
|||
// 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.baremetal.manager;
|
||||
|
||||
import com.cloud.baremetal.networkservice.BaremetalRctResponse;
|
||||
import com.cloud.baremetal.networkservice.BaremetalSwitchBackend;
|
||||
import com.cloud.deploy.DeployDestination;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.utils.component.Manager;
|
||||
import com.cloud.utils.component.PluggableService;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import org.apache.cloudstack.api.AddBaremetalRctCmd;
|
||||
import org.apache.cloudstack.api.DeleteBaremetalRctCmd;
|
||||
|
||||
public interface BaremetalVlanManager extends Manager, PluggableService {
|
||||
|
||||
BaremetalRctResponse addRct(AddBaremetalRctCmd cmd);
|
||||
|
||||
void prepareVlan(Network nw, DeployDestination destHost);
|
||||
|
||||
void releaseVlan(Network nw, VirtualMachineProfile vm);
|
||||
|
||||
void registerSwitchBackend(BaremetalSwitchBackend backend);
|
||||
|
||||
void deleteRct(DeleteBaremetalRctCmd cmd);
|
||||
|
||||
BaremetalRctResponse listRct();
|
||||
}
|
||||
// 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.baremetal.manager;
|
||||
|
||||
import com.cloud.baremetal.networkservice.BaremetalRctResponse;
|
||||
import com.cloud.baremetal.networkservice.BaremetalSwitchBackend;
|
||||
import com.cloud.deploy.DeployDestination;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.utils.component.Manager;
|
||||
import com.cloud.utils.component.PluggableService;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import org.apache.cloudstack.api.AddBaremetalRctCmd;
|
||||
import org.apache.cloudstack.api.DeleteBaremetalRctCmd;
|
||||
|
||||
public interface BaremetalVlanManager extends Manager, PluggableService {
|
||||
|
||||
BaremetalRctResponse addRct(AddBaremetalRctCmd cmd);
|
||||
|
||||
void prepareVlan(Network nw, DeployDestination destHost);
|
||||
|
||||
void releaseVlan(Network nw, VirtualMachineProfile vm);
|
||||
|
||||
void registerSwitchBackend(BaremetalSwitchBackend backend);
|
||||
|
||||
void deleteRct(DeleteBaremetalRctCmd cmd);
|
||||
|
||||
BaremetalRctResponse listRct();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,272 +1,272 @@
|
|||
// 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.baremetal.manager;
|
||||
|
||||
import com.cloud.baremetal.database.BaremetalRctDao;
|
||||
import com.cloud.baremetal.database.BaremetalRctVO;
|
||||
import com.cloud.baremetal.networkservice.BaremetalRctResponse;
|
||||
import com.cloud.baremetal.networkservice.BaremetalSwitchBackend;
|
||||
import com.cloud.baremetal.networkservice.BaremetalVlanStruct;
|
||||
import com.cloud.deploy.DeployDestination;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.Networks;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.UserVO;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.user.dao.UserDao;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.db.QueryBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.google.gson.Gson;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.AddBaremetalRctCmd;
|
||||
import org.apache.cloudstack.api.DeleteBaremetalRctCmd;
|
||||
import org.apache.cloudstack.api.ListBaremetalRctCmd;
|
||||
import org.apache.cloudstack.utils.baremetal.BaremetalUtils;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Created by frank on 5/8/14.
|
||||
*/
|
||||
public class BaremetalVlanManagerImpl extends ManagerBase implements BaremetalVlanManager {
|
||||
private Gson gson = new Gson();
|
||||
|
||||
@Inject
|
||||
private BaremetalRctDao rctDao;
|
||||
@Inject
|
||||
private HostDao hostDao;
|
||||
@Inject
|
||||
private AccountDao acntDao;
|
||||
@Inject
|
||||
private UserDao userDao;
|
||||
@Inject
|
||||
private AccountManager acntMgr;
|
||||
|
||||
private Map<String, BaremetalSwitchBackend> backends;
|
||||
|
||||
private class RackPair {
|
||||
BaremetalRct.Rack rack;
|
||||
BaremetalRct.HostEntry host;
|
||||
}
|
||||
|
||||
public void setBackends(Map<String, BaremetalSwitchBackend> backends) {
|
||||
this.backends = backends;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaremetalRctResponse addRct(AddBaremetalRctCmd cmd) {
|
||||
try {
|
||||
List<BaremetalRctVO> existings = rctDao.listAll();
|
||||
if (!existings.isEmpty()) {
|
||||
throw new CloudRuntimeException(String.format("there is some RCT existing. A CloudStack deployment accepts only one RCT"));
|
||||
}
|
||||
URL url = new URL(cmd.getRctUrl());
|
||||
RestTemplate rest = new RestTemplate();
|
||||
String rctStr = rest.getForObject(url.toString(), String.class);
|
||||
|
||||
// validate it's right format
|
||||
BaremetalRct rct = gson.fromJson(rctStr, BaremetalRct.class);
|
||||
QueryBuilder<BaremetalRctVO> sc = QueryBuilder.create(BaremetalRctVO.class);
|
||||
sc.and(sc.entity().getUrl(), SearchCriteria.Op.EQ, cmd.getRctUrl());
|
||||
BaremetalRctVO vo = sc.find();
|
||||
if (vo == null) {
|
||||
vo = new BaremetalRctVO();
|
||||
vo.setRct(gson.toJson(rct));
|
||||
vo.setUrl(cmd.getRctUrl());
|
||||
vo = rctDao.persist(vo);
|
||||
} else {
|
||||
vo.setRct(gson.toJson(rct));
|
||||
rctDao.update(vo.getId(), vo);
|
||||
}
|
||||
|
||||
BaremetalRctResponse rsp = new BaremetalRctResponse();
|
||||
rsp.setUrl(vo.getUrl());
|
||||
rsp.setId(vo.getUuid());
|
||||
rsp.setObjectName("baremetalrct");
|
||||
return rsp;
|
||||
} catch (MalformedURLException e) {
|
||||
throw new IllegalArgumentException(String.format("%s is not a legal http url", cmd.getRctUrl()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareVlan(Network nw, DeployDestination destHost) {
|
||||
List<BaremetalRctVO> vos = rctDao.listAll();
|
||||
if (vos.isEmpty()) {
|
||||
throw new CloudRuntimeException("no rack configuration found, please call addBaremetalRct to add one");
|
||||
}
|
||||
|
||||
BaremetalRctVO vo = vos.get(0);
|
||||
BaremetalRct rct = gson.fromJson(vo.getRct(), BaremetalRct.class);
|
||||
|
||||
RackPair rp = findRack(rct, destHost.getHost().getPrivateMacAddress());
|
||||
if (rp == null) {
|
||||
throw new CloudRuntimeException(String.format("cannot find any rack contains host[mac:%s], please double check your rack configuration file, update it and call addBaremetalRct again", destHost.getHost().getPrivateMacAddress()));
|
||||
}
|
||||
|
||||
int vlan = Integer.parseInt(Networks.BroadcastDomainType.getValue(nw.getBroadcastUri()));
|
||||
BaremetalSwitchBackend backend = getSwitchBackend(rp.rack.getL2Switch().getType());
|
||||
BaremetalVlanStruct struct = new BaremetalVlanStruct();
|
||||
struct.setHostMac(rp.host.getMac());
|
||||
struct.setPort(rp.host.getPort());
|
||||
struct.setSwitchIp(rp.rack.getL2Switch().getIp());
|
||||
struct.setSwitchPassword(rp.rack.getL2Switch().getPassword());
|
||||
struct.setSwitchType(rp.rack.getL2Switch().getType());
|
||||
struct.setSwitchUsername(rp.rack.getL2Switch().getUsername());
|
||||
struct.setVlan(vlan);
|
||||
backend.prepareVlan(struct);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseVlan(Network nw, VirtualMachineProfile vm) {
|
||||
List<BaremetalRctVO> vos = rctDao.listAll();
|
||||
if (vos.isEmpty()) {
|
||||
throw new CloudRuntimeException("no rack configuration found, please call addBaremetalRct to add one");
|
||||
}
|
||||
|
||||
BaremetalRctVO vo = vos.get(0);
|
||||
BaremetalRct rct = gson.fromJson(vo.getRct(), BaremetalRct.class);
|
||||
HostVO host = hostDao.findById(vm.getVirtualMachine().getHostId());
|
||||
RackPair rp = findRack(rct, host.getPrivateMacAddress());
|
||||
assert rp != null : String.format("where is my rack???");
|
||||
|
||||
int vlan = Integer.parseInt(Networks.BroadcastDomainType.getValue(nw.getBroadcastUri()));
|
||||
BaremetalVlanStruct struct = new BaremetalVlanStruct();
|
||||
struct.setHostMac(rp.host.getMac());
|
||||
struct.setPort(rp.host.getPort());
|
||||
struct.setSwitchIp(rp.rack.getL2Switch().getIp());
|
||||
struct.setSwitchPassword(rp.rack.getL2Switch().getPassword());
|
||||
struct.setSwitchType(rp.rack.getL2Switch().getType());
|
||||
struct.setSwitchUsername(rp.rack.getL2Switch().getUsername());
|
||||
struct.setVlan(vlan);
|
||||
BaremetalSwitchBackend backend = getSwitchBackend(rp.rack.getL2Switch().getType());
|
||||
backend.removePortFromVlan(struct);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerSwitchBackend(BaremetalSwitchBackend backend) {
|
||||
backends.put(backend.getSwitchBackendType(), backend);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteRct(DeleteBaremetalRctCmd cmd) {
|
||||
rctDao.remove(cmd.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaremetalRctResponse listRct() {
|
||||
List<BaremetalRctVO> vos = rctDao.listAll();
|
||||
if (!vos.isEmpty()) {
|
||||
BaremetalRctVO vo = vos.get(0);
|
||||
BaremetalRctResponse rsp = new BaremetalRctResponse();
|
||||
rsp.setId(vo.getUuid());
|
||||
rsp.setUrl(vo.getUrl());
|
||||
rsp.setObjectName("baremetalrct");
|
||||
return rsp;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private BaremetalSwitchBackend getSwitchBackend(String type) {
|
||||
BaremetalSwitchBackend backend = backends.get(type);
|
||||
if (backend == null) {
|
||||
throw new CloudRuntimeException(String.format("cannot find switch backend[type:%s]", type));
|
||||
}
|
||||
return backend;
|
||||
}
|
||||
|
||||
private RackPair findRack(BaremetalRct rct, String mac) {
|
||||
for (BaremetalRct.Rack rack : rct.getRacks()) {
|
||||
for (BaremetalRct.HostEntry host : rack.getHosts()) {
|
||||
if (mac.equals(host.getMac())) {
|
||||
RackPair p = new RackPair();
|
||||
p.host = host;
|
||||
p.rack = rack;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Baremetal Vlan Manager";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<Class<?>> getCommands() {
|
||||
List<Class<?>> cmds = new ArrayList<Class<?>>();
|
||||
cmds.add(AddBaremetalRctCmd.class);
|
||||
cmds.add(ListBaremetalRctCmd.class);
|
||||
cmds.add(DeleteBaremetalRctCmd.class);
|
||||
return cmds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
QueryBuilder<AccountVO> acntq = QueryBuilder.create(AccountVO.class);
|
||||
acntq.and(acntq.entity().getAccountName(), SearchCriteria.Op.EQ, BaremetalUtils.BAREMETAL_SYSTEM_ACCOUNT_NAME);
|
||||
AccountVO acnt = acntq.find();
|
||||
if (acnt != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
acnt = new AccountVO();
|
||||
acnt.setAccountName(BaremetalUtils.BAREMETAL_SYSTEM_ACCOUNT_NAME);
|
||||
acnt.setUuid(UUID.randomUUID().toString());
|
||||
acnt.setState(Account.State.ENABLED);
|
||||
acnt.setDomainId(1);
|
||||
acnt.setType(RoleType.User.getAccountType());
|
||||
acnt.setRoleId(RoleType.User.getId());
|
||||
acnt = acntDao.persist(acnt);
|
||||
|
||||
UserVO user = new UserVO();
|
||||
user.setState(Account.State.ENABLED);
|
||||
user.setUuid(UUID.randomUUID().toString());
|
||||
user.setAccountId(acnt.getAccountId());
|
||||
user.setUsername(BaremetalUtils.BAREMETAL_SYSTEM_ACCOUNT_NAME);
|
||||
user.setFirstname(BaremetalUtils.BAREMETAL_SYSTEM_ACCOUNT_NAME);
|
||||
user.setLastname(BaremetalUtils.BAREMETAL_SYSTEM_ACCOUNT_NAME);
|
||||
user.setPassword(UUID.randomUUID().toString());
|
||||
user.setSource(User.Source.UNKNOWN);
|
||||
user = userDao.persist(user);
|
||||
|
||||
String[] keys = acntMgr.createApiKeyAndSecretKey(user.getId());
|
||||
user.setApiKey(keys[0]);
|
||||
user.setSecretKey(keys[1]);
|
||||
userDao.update(user.getId(), user);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// 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.baremetal.manager;
|
||||
|
||||
import com.cloud.baremetal.database.BaremetalRctDao;
|
||||
import com.cloud.baremetal.database.BaremetalRctVO;
|
||||
import com.cloud.baremetal.networkservice.BaremetalRctResponse;
|
||||
import com.cloud.baremetal.networkservice.BaremetalSwitchBackend;
|
||||
import com.cloud.baremetal.networkservice.BaremetalVlanStruct;
|
||||
import com.cloud.deploy.DeployDestination;
|
||||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.Networks;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.UserVO;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.user.dao.UserDao;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.db.QueryBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.google.gson.Gson;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.AddBaremetalRctCmd;
|
||||
import org.apache.cloudstack.api.DeleteBaremetalRctCmd;
|
||||
import org.apache.cloudstack.api.ListBaremetalRctCmd;
|
||||
import org.apache.cloudstack.utils.baremetal.BaremetalUtils;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Created by frank on 5/8/14.
|
||||
*/
|
||||
public class BaremetalVlanManagerImpl extends ManagerBase implements BaremetalVlanManager {
|
||||
private Gson gson = new Gson();
|
||||
|
||||
@Inject
|
||||
private BaremetalRctDao rctDao;
|
||||
@Inject
|
||||
private HostDao hostDao;
|
||||
@Inject
|
||||
private AccountDao acntDao;
|
||||
@Inject
|
||||
private UserDao userDao;
|
||||
@Inject
|
||||
private AccountManager acntMgr;
|
||||
|
||||
private Map<String, BaremetalSwitchBackend> backends;
|
||||
|
||||
private class RackPair {
|
||||
BaremetalRct.Rack rack;
|
||||
BaremetalRct.HostEntry host;
|
||||
}
|
||||
|
||||
public void setBackends(Map<String, BaremetalSwitchBackend> backends) {
|
||||
this.backends = backends;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaremetalRctResponse addRct(AddBaremetalRctCmd cmd) {
|
||||
try {
|
||||
List<BaremetalRctVO> existings = rctDao.listAll();
|
||||
if (!existings.isEmpty()) {
|
||||
throw new CloudRuntimeException(String.format("there is some RCT existing. A CloudStack deployment accepts only one RCT"));
|
||||
}
|
||||
URL url = new URL(cmd.getRctUrl());
|
||||
RestTemplate rest = new RestTemplate();
|
||||
String rctStr = rest.getForObject(url.toString(), String.class);
|
||||
|
||||
// validate it's right format
|
||||
BaremetalRct rct = gson.fromJson(rctStr, BaremetalRct.class);
|
||||
QueryBuilder<BaremetalRctVO> sc = QueryBuilder.create(BaremetalRctVO.class);
|
||||
sc.and(sc.entity().getUrl(), SearchCriteria.Op.EQ, cmd.getRctUrl());
|
||||
BaremetalRctVO vo = sc.find();
|
||||
if (vo == null) {
|
||||
vo = new BaremetalRctVO();
|
||||
vo.setRct(gson.toJson(rct));
|
||||
vo.setUrl(cmd.getRctUrl());
|
||||
vo = rctDao.persist(vo);
|
||||
} else {
|
||||
vo.setRct(gson.toJson(rct));
|
||||
rctDao.update(vo.getId(), vo);
|
||||
}
|
||||
|
||||
BaremetalRctResponse rsp = new BaremetalRctResponse();
|
||||
rsp.setUrl(vo.getUrl());
|
||||
rsp.setId(vo.getUuid());
|
||||
rsp.setObjectName("baremetalrct");
|
||||
return rsp;
|
||||
} catch (MalformedURLException e) {
|
||||
throw new IllegalArgumentException(String.format("%s is not a legal http url", cmd.getRctUrl()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareVlan(Network nw, DeployDestination destHost) {
|
||||
List<BaremetalRctVO> vos = rctDao.listAll();
|
||||
if (vos.isEmpty()) {
|
||||
throw new CloudRuntimeException("no rack configuration found, please call addBaremetalRct to add one");
|
||||
}
|
||||
|
||||
BaremetalRctVO vo = vos.get(0);
|
||||
BaremetalRct rct = gson.fromJson(vo.getRct(), BaremetalRct.class);
|
||||
|
||||
RackPair rp = findRack(rct, destHost.getHost().getPrivateMacAddress());
|
||||
if (rp == null) {
|
||||
throw new CloudRuntimeException(String.format("cannot find any rack contains host[mac:%s], please double check your rack configuration file, update it and call addBaremetalRct again", destHost.getHost().getPrivateMacAddress()));
|
||||
}
|
||||
|
||||
int vlan = Integer.parseInt(Networks.BroadcastDomainType.getValue(nw.getBroadcastUri()));
|
||||
BaremetalSwitchBackend backend = getSwitchBackend(rp.rack.getL2Switch().getType());
|
||||
BaremetalVlanStruct struct = new BaremetalVlanStruct();
|
||||
struct.setHostMac(rp.host.getMac());
|
||||
struct.setPort(rp.host.getPort());
|
||||
struct.setSwitchIp(rp.rack.getL2Switch().getIp());
|
||||
struct.setSwitchPassword(rp.rack.getL2Switch().getPassword());
|
||||
struct.setSwitchType(rp.rack.getL2Switch().getType());
|
||||
struct.setSwitchUsername(rp.rack.getL2Switch().getUsername());
|
||||
struct.setVlan(vlan);
|
||||
backend.prepareVlan(struct);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseVlan(Network nw, VirtualMachineProfile vm) {
|
||||
List<BaremetalRctVO> vos = rctDao.listAll();
|
||||
if (vos.isEmpty()) {
|
||||
throw new CloudRuntimeException("no rack configuration found, please call addBaremetalRct to add one");
|
||||
}
|
||||
|
||||
BaremetalRctVO vo = vos.get(0);
|
||||
BaremetalRct rct = gson.fromJson(vo.getRct(), BaremetalRct.class);
|
||||
HostVO host = hostDao.findById(vm.getVirtualMachine().getHostId());
|
||||
RackPair rp = findRack(rct, host.getPrivateMacAddress());
|
||||
assert rp != null : String.format("where is my rack???");
|
||||
|
||||
int vlan = Integer.parseInt(Networks.BroadcastDomainType.getValue(nw.getBroadcastUri()));
|
||||
BaremetalVlanStruct struct = new BaremetalVlanStruct();
|
||||
struct.setHostMac(rp.host.getMac());
|
||||
struct.setPort(rp.host.getPort());
|
||||
struct.setSwitchIp(rp.rack.getL2Switch().getIp());
|
||||
struct.setSwitchPassword(rp.rack.getL2Switch().getPassword());
|
||||
struct.setSwitchType(rp.rack.getL2Switch().getType());
|
||||
struct.setSwitchUsername(rp.rack.getL2Switch().getUsername());
|
||||
struct.setVlan(vlan);
|
||||
BaremetalSwitchBackend backend = getSwitchBackend(rp.rack.getL2Switch().getType());
|
||||
backend.removePortFromVlan(struct);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerSwitchBackend(BaremetalSwitchBackend backend) {
|
||||
backends.put(backend.getSwitchBackendType(), backend);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteRct(DeleteBaremetalRctCmd cmd) {
|
||||
rctDao.remove(cmd.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaremetalRctResponse listRct() {
|
||||
List<BaremetalRctVO> vos = rctDao.listAll();
|
||||
if (!vos.isEmpty()) {
|
||||
BaremetalRctVO vo = vos.get(0);
|
||||
BaremetalRctResponse rsp = new BaremetalRctResponse();
|
||||
rsp.setId(vo.getUuid());
|
||||
rsp.setUrl(vo.getUrl());
|
||||
rsp.setObjectName("baremetalrct");
|
||||
return rsp;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private BaremetalSwitchBackend getSwitchBackend(String type) {
|
||||
BaremetalSwitchBackend backend = backends.get(type);
|
||||
if (backend == null) {
|
||||
throw new CloudRuntimeException(String.format("cannot find switch backend[type:%s]", type));
|
||||
}
|
||||
return backend;
|
||||
}
|
||||
|
||||
private RackPair findRack(BaremetalRct rct, String mac) {
|
||||
for (BaremetalRct.Rack rack : rct.getRacks()) {
|
||||
for (BaremetalRct.HostEntry host : rack.getHosts()) {
|
||||
if (mac.equals(host.getMac())) {
|
||||
RackPair p = new RackPair();
|
||||
p.host = host;
|
||||
p.rack = rack;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Baremetal Vlan Manager";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<Class<?>> getCommands() {
|
||||
List<Class<?>> cmds = new ArrayList<Class<?>>();
|
||||
cmds.add(AddBaremetalRctCmd.class);
|
||||
cmds.add(ListBaremetalRctCmd.class);
|
||||
cmds.add(DeleteBaremetalRctCmd.class);
|
||||
return cmds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
QueryBuilder<AccountVO> acntq = QueryBuilder.create(AccountVO.class);
|
||||
acntq.and(acntq.entity().getAccountName(), SearchCriteria.Op.EQ, BaremetalUtils.BAREMETAL_SYSTEM_ACCOUNT_NAME);
|
||||
AccountVO acnt = acntq.find();
|
||||
if (acnt != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
acnt = new AccountVO();
|
||||
acnt.setAccountName(BaremetalUtils.BAREMETAL_SYSTEM_ACCOUNT_NAME);
|
||||
acnt.setUuid(UUID.randomUUID().toString());
|
||||
acnt.setState(Account.State.ENABLED);
|
||||
acnt.setDomainId(1);
|
||||
acnt.setType(RoleType.User.getAccountType());
|
||||
acnt.setRoleId(RoleType.User.getId());
|
||||
acnt = acntDao.persist(acnt);
|
||||
|
||||
UserVO user = new UserVO();
|
||||
user.setState(Account.State.ENABLED);
|
||||
user.setUuid(UUID.randomUUID().toString());
|
||||
user.setAccountId(acnt.getAccountId());
|
||||
user.setUsername(BaremetalUtils.BAREMETAL_SYSTEM_ACCOUNT_NAME);
|
||||
user.setFirstname(BaremetalUtils.BAREMETAL_SYSTEM_ACCOUNT_NAME);
|
||||
user.setLastname(BaremetalUtils.BAREMETAL_SYSTEM_ACCOUNT_NAME);
|
||||
user.setPassword(UUID.randomUUID().toString());
|
||||
user.setSource(User.Source.UNKNOWN);
|
||||
user = userDao.persist(user);
|
||||
|
||||
String[] keys = acntMgr.createApiKeyAndSecretKey(user.getId());
|
||||
user.setApiKey(keys[0]);
|
||||
user.setSecretKey(keys[1]);
|
||||
userDao.update(user.getId(), user);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,55 +1,55 @@
|
|||
// 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.baremetal.networkservice;
|
||||
|
||||
import com.cloud.baremetal.database.BaremetalRctVO;
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
|
||||
/**
|
||||
* Created by frank on 5/8/14.
|
||||
*/
|
||||
@EntityReference(value = BaremetalRctVO.class)
|
||||
public class BaremetalRctResponse extends BaseResponse {
|
||||
@SerializedName(ApiConstants.ID)
|
||||
@Param(description = "id of rct")
|
||||
private String id;
|
||||
|
||||
@SerializedName(ApiConstants.URL)
|
||||
@Param(description = "url")
|
||||
private String url;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
}
|
||||
// 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.baremetal.networkservice;
|
||||
|
||||
import com.cloud.baremetal.database.BaremetalRctVO;
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
|
||||
/**
|
||||
* Created by frank on 5/8/14.
|
||||
*/
|
||||
@EntityReference(value = BaremetalRctVO.class)
|
||||
public class BaremetalRctResponse extends BaseResponse {
|
||||
@SerializedName(ApiConstants.ID)
|
||||
@Param(description = "id of rct")
|
||||
private String id;
|
||||
|
||||
@SerializedName(ApiConstants.URL)
|
||||
@Param(description = "url")
|
||||
private String url;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,34 +1,34 @@
|
|||
// 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.
|
||||
//
|
||||
// Automatically generated by addcopyright.py at 01/29/2013
|
||||
// Apache License, Version 2.0 (the "License"); you may not use this
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// Automatically generated by addcopyright.py at 04/03/2012
|
||||
package com.cloud.baremetal.networkservice;
|
||||
|
||||
/**
|
||||
* Created by frank on 9/2/14.
|
||||
*/
|
||||
public interface BaremetalSwitchBackend {
|
||||
String getSwitchBackendType();
|
||||
|
||||
void prepareVlan(BaremetalVlanStruct struct);
|
||||
|
||||
void removePortFromVlan(BaremetalVlanStruct struct);
|
||||
}
|
||||
// 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.
|
||||
//
|
||||
// Automatically generated by addcopyright.py at 01/29/2013
|
||||
// Apache License, Version 2.0 (the "License"); you may not use this
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// Automatically generated by addcopyright.py at 04/03/2012
|
||||
package com.cloud.baremetal.networkservice;
|
||||
|
||||
/**
|
||||
* Created by frank on 9/2/14.
|
||||
*/
|
||||
public interface BaremetalSwitchBackend {
|
||||
String getSwitchBackendType();
|
||||
|
||||
void prepareVlan(BaremetalVlanStruct struct);
|
||||
|
||||
void removePortFromVlan(BaremetalVlanStruct struct);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,122 +1,122 @@
|
|||
// 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.baremetal.networkservice;
|
||||
|
||||
/**
|
||||
* Created by frank on 7/23/14.
|
||||
*/
|
||||
public class BaremetalVirtualRouterCommands {
|
||||
|
||||
public abstract static class AgentCommand {
|
||||
}
|
||||
|
||||
public abstract static class AgentResponse {
|
||||
private boolean success;
|
||||
private String error;
|
||||
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public void setSuccess(boolean success) {
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
public String getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public void setError(String error) {
|
||||
this.error = error;
|
||||
}
|
||||
}
|
||||
|
||||
public static class PreparePxeCmd extends AgentCommand {
|
||||
private String guestMac;
|
||||
private String templateUuid;
|
||||
private String kickStartUrl;
|
||||
private String initrdUrl;
|
||||
private String kernelUrl;
|
||||
|
||||
public String getTemplateUuid() {
|
||||
return templateUuid;
|
||||
}
|
||||
|
||||
public void setTemplateUuid(String templateUuid) {
|
||||
this.templateUuid = templateUuid;
|
||||
}
|
||||
|
||||
public String getGuestMac() {
|
||||
return guestMac;
|
||||
}
|
||||
|
||||
public void setGuestMac(String guestMac) {
|
||||
this.guestMac = guestMac;
|
||||
}
|
||||
|
||||
public String getKickStartUrl() {
|
||||
return kickStartUrl;
|
||||
}
|
||||
|
||||
public void setKickStartUrl(String kickStartUrl) {
|
||||
this.kickStartUrl = kickStartUrl;
|
||||
}
|
||||
|
||||
public String getInitrdUrl() {
|
||||
return initrdUrl;
|
||||
}
|
||||
|
||||
public void setInitrdUrl(String initrdUrl) {
|
||||
this.initrdUrl = initrdUrl;
|
||||
}
|
||||
|
||||
public String getKernelUrl() {
|
||||
return kernelUrl;
|
||||
}
|
||||
|
||||
public void setKernelUrl(String kernelUrl) {
|
||||
this.kernelUrl = kernelUrl;
|
||||
}
|
||||
}
|
||||
|
||||
public static class PreparePxeRsp extends AgentResponse {
|
||||
}
|
||||
|
||||
public static class PrepareSourceNatCmd extends AgentCommand {
|
||||
private String internalStorageServerIp;
|
||||
private String managementNicIp;
|
||||
|
||||
public String getInternalStorageServerIp() {
|
||||
return internalStorageServerIp;
|
||||
}
|
||||
|
||||
public void setInternalStorageServerIp(String internalStorageServerIp) {
|
||||
this.internalStorageServerIp = internalStorageServerIp;
|
||||
}
|
||||
|
||||
public String getManagementNicIp() {
|
||||
return managementNicIp;
|
||||
}
|
||||
|
||||
public void setManagementNicIp(String managementNicIp) {
|
||||
this.managementNicIp = managementNicIp;
|
||||
}
|
||||
}
|
||||
|
||||
public static class PrepareSourceNatRsp extends AgentResponse {
|
||||
}
|
||||
}
|
||||
// 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.baremetal.networkservice;
|
||||
|
||||
/**
|
||||
* Created by frank on 7/23/14.
|
||||
*/
|
||||
public class BaremetalVirtualRouterCommands {
|
||||
|
||||
public abstract static class AgentCommand {
|
||||
}
|
||||
|
||||
public abstract static class AgentResponse {
|
||||
private boolean success;
|
||||
private String error;
|
||||
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public void setSuccess(boolean success) {
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
public String getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public void setError(String error) {
|
||||
this.error = error;
|
||||
}
|
||||
}
|
||||
|
||||
public static class PreparePxeCmd extends AgentCommand {
|
||||
private String guestMac;
|
||||
private String templateUuid;
|
||||
private String kickStartUrl;
|
||||
private String initrdUrl;
|
||||
private String kernelUrl;
|
||||
|
||||
public String getTemplateUuid() {
|
||||
return templateUuid;
|
||||
}
|
||||
|
||||
public void setTemplateUuid(String templateUuid) {
|
||||
this.templateUuid = templateUuid;
|
||||
}
|
||||
|
||||
public String getGuestMac() {
|
||||
return guestMac;
|
||||
}
|
||||
|
||||
public void setGuestMac(String guestMac) {
|
||||
this.guestMac = guestMac;
|
||||
}
|
||||
|
||||
public String getKickStartUrl() {
|
||||
return kickStartUrl;
|
||||
}
|
||||
|
||||
public void setKickStartUrl(String kickStartUrl) {
|
||||
this.kickStartUrl = kickStartUrl;
|
||||
}
|
||||
|
||||
public String getInitrdUrl() {
|
||||
return initrdUrl;
|
||||
}
|
||||
|
||||
public void setInitrdUrl(String initrdUrl) {
|
||||
this.initrdUrl = initrdUrl;
|
||||
}
|
||||
|
||||
public String getKernelUrl() {
|
||||
return kernelUrl;
|
||||
}
|
||||
|
||||
public void setKernelUrl(String kernelUrl) {
|
||||
this.kernelUrl = kernelUrl;
|
||||
}
|
||||
}
|
||||
|
||||
public static class PreparePxeRsp extends AgentResponse {
|
||||
}
|
||||
|
||||
public static class PrepareSourceNatCmd extends AgentCommand {
|
||||
private String internalStorageServerIp;
|
||||
private String managementNicIp;
|
||||
|
||||
public String getInternalStorageServerIp() {
|
||||
return internalStorageServerIp;
|
||||
}
|
||||
|
||||
public void setInternalStorageServerIp(String internalStorageServerIp) {
|
||||
this.internalStorageServerIp = internalStorageServerIp;
|
||||
}
|
||||
|
||||
public String getManagementNicIp() {
|
||||
return managementNicIp;
|
||||
}
|
||||
|
||||
public void setManagementNicIp(String managementNicIp) {
|
||||
this.managementNicIp = managementNicIp;
|
||||
}
|
||||
}
|
||||
|
||||
public static class PrepareSourceNatRsp extends AgentResponse {
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,92 +1,92 @@
|
|||
// 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.
|
||||
//
|
||||
// Automatically generated by addcopyright.py at 01/29/2013
|
||||
// Apache License, Version 2.0 (the "License"); you may not use this
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// Automatically generated by addcopyright.py at 04/03/2012
|
||||
package com.cloud.baremetal.networkservice;
|
||||
|
||||
/**
|
||||
* Created by frank on 9/2/14.
|
||||
*/
|
||||
public class BaremetalVlanStruct {
|
||||
private String switchType;
|
||||
private String switchIp;
|
||||
private String switchUsername;
|
||||
private String switchPassword;
|
||||
private String hostMac;
|
||||
private String port;
|
||||
private int vlan;
|
||||
|
||||
public String getSwitchType() {
|
||||
return switchType;
|
||||
}
|
||||
|
||||
public void setSwitchType(String switchType) {
|
||||
this.switchType = switchType;
|
||||
}
|
||||
|
||||
public String getSwitchIp() {
|
||||
return switchIp;
|
||||
}
|
||||
|
||||
public void setSwitchIp(String switchIp) {
|
||||
this.switchIp = switchIp;
|
||||
}
|
||||
|
||||
public String getSwitchUsername() {
|
||||
return switchUsername;
|
||||
}
|
||||
|
||||
public void setSwitchUsername(String switchUsername) {
|
||||
this.switchUsername = switchUsername;
|
||||
}
|
||||
|
||||
public String getSwitchPassword() {
|
||||
return switchPassword;
|
||||
}
|
||||
|
||||
public void setSwitchPassword(String switchPassword) {
|
||||
this.switchPassword = switchPassword;
|
||||
}
|
||||
|
||||
public String getHostMac() {
|
||||
return hostMac;
|
||||
}
|
||||
|
||||
public void setHostMac(String hostMac) {
|
||||
this.hostMac = hostMac;
|
||||
}
|
||||
|
||||
public String getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(String port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public int getVlan() {
|
||||
return vlan;
|
||||
}
|
||||
|
||||
public void setVlan(int vlan) {
|
||||
this.vlan = vlan;
|
||||
}
|
||||
}
|
||||
// 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.
|
||||
//
|
||||
// Automatically generated by addcopyright.py at 01/29/2013
|
||||
// Apache License, Version 2.0 (the "License"); you may not use this
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// Automatically generated by addcopyright.py at 04/03/2012
|
||||
package com.cloud.baremetal.networkservice;
|
||||
|
||||
/**
|
||||
* Created by frank on 9/2/14.
|
||||
*/
|
||||
public class BaremetalVlanStruct {
|
||||
private String switchType;
|
||||
private String switchIp;
|
||||
private String switchUsername;
|
||||
private String switchPassword;
|
||||
private String hostMac;
|
||||
private String port;
|
||||
private int vlan;
|
||||
|
||||
public String getSwitchType() {
|
||||
return switchType;
|
||||
}
|
||||
|
||||
public void setSwitchType(String switchType) {
|
||||
this.switchType = switchType;
|
||||
}
|
||||
|
||||
public String getSwitchIp() {
|
||||
return switchIp;
|
||||
}
|
||||
|
||||
public void setSwitchIp(String switchIp) {
|
||||
this.switchIp = switchIp;
|
||||
}
|
||||
|
||||
public String getSwitchUsername() {
|
||||
return switchUsername;
|
||||
}
|
||||
|
||||
public void setSwitchUsername(String switchUsername) {
|
||||
this.switchUsername = switchUsername;
|
||||
}
|
||||
|
||||
public String getSwitchPassword() {
|
||||
return switchPassword;
|
||||
}
|
||||
|
||||
public void setSwitchPassword(String switchPassword) {
|
||||
this.switchPassword = switchPassword;
|
||||
}
|
||||
|
||||
public String getHostMac() {
|
||||
return hostMac;
|
||||
}
|
||||
|
||||
public void setHostMac(String hostMac) {
|
||||
this.hostMac = hostMac;
|
||||
}
|
||||
|
||||
public String getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public void setPort(String port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public int getVlan() {
|
||||
return vlan;
|
||||
}
|
||||
|
||||
public void setVlan(int vlan) {
|
||||
this.vlan = vlan;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,56 +1,56 @@
|
|||
// 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.
|
||||
//
|
||||
// Automatically generated by addcopyright.py at 01/29/2013
|
||||
// Apache License, Version 2.0 (the "License"); you may not use this
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// Automatically generated by addcopyright.py at 04/03/2012
|
||||
package com.cloud.baremetal.networkservice;
|
||||
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.xmlobject.XmlObject;
|
||||
import com.cloud.utils.xmlobject.XmlObjectParser;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
// 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.
|
||||
//
|
||||
// Automatically generated by addcopyright.py at 01/29/2013
|
||||
// Apache License, Version 2.0 (the "License"); you may not use this
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// Automatically generated by addcopyright.py at 04/03/2012
|
||||
package com.cloud.baremetal.networkservice;
|
||||
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.xmlobject.XmlObject;
|
||||
import com.cloud.utils.xmlobject.XmlObjectParser;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.web.client.ResponseErrorHandler;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by frank on 9/2/14.
|
||||
*/
|
||||
public class Force10BaremetalSwitchBackend implements BaremetalSwitchBackend {
|
||||
private Logger logger = Logger.getLogger(Force10BaremetalSwitchBackend.class);
|
||||
public static final String TYPE = "Force10";
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by frank on 9/2/14.
|
||||
*/
|
||||
public class Force10BaremetalSwitchBackend implements BaremetalSwitchBackend {
|
||||
private Logger logger = Logger.getLogger(Force10BaremetalSwitchBackend.class);
|
||||
public static final String TYPE = "Force10";
|
||||
|
||||
private static List<HttpStatus> successHttpStatusCode = new ArrayList<>();
|
||||
{
|
||||
successHttpStatusCode.add(HttpStatus.OK);
|
||||
|
|
@ -62,7 +62,7 @@ public class Force10BaremetalSwitchBackend implements BaremetalSwitchBackend {
|
|||
successHttpStatusCode.add(HttpStatus.ALREADY_REPORTED);
|
||||
}
|
||||
|
||||
RestTemplate rest = new RestTemplate();
|
||||
RestTemplate rest = new RestTemplate();
|
||||
{
|
||||
// fake error handler, we handle error in business logic code
|
||||
rest.setErrorHandler(new ResponseErrorHandler() {
|
||||
|
|
@ -70,7 +70,7 @@ public class Force10BaremetalSwitchBackend implements BaremetalSwitchBackend {
|
|||
public boolean hasError(ClientHttpResponse clientHttpResponse) throws IOException {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void handleError(ClientHttpResponse clientHttpResponse) throws IOException {
|
||||
}
|
||||
|
|
@ -78,29 +78,29 @@ public class Force10BaremetalSwitchBackend implements BaremetalSwitchBackend {
|
|||
}
|
||||
|
||||
private String buildLink(String switchIp, String path) {
|
||||
UriComponentsBuilder builder = UriComponentsBuilder.newInstance();
|
||||
builder.scheme("http");
|
||||
builder.host(switchIp);
|
||||
builder.port(8008);
|
||||
UriComponentsBuilder builder = UriComponentsBuilder.newInstance();
|
||||
builder.scheme("http");
|
||||
builder.host(switchIp);
|
||||
builder.port(8008);
|
||||
builder.path(path);
|
||||
return builder.build().toUriString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSwitchBackendType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareVlan(BaremetalVlanStruct struct) {
|
||||
return builder.build().toUriString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSwitchBackendType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareVlan(BaremetalVlanStruct struct) {
|
||||
String link = buildLink(struct.getSwitchIp(), String.format("/api/running/ftos/interface/vlan/%s", struct.getVlan()));
|
||||
HttpHeaders headers = createBasicAuthenticationHeader(struct);
|
||||
HttpEntity<String> request = new HttpEntity<>(headers);
|
||||
ResponseEntity rsp = rest.exchange(link, HttpMethod.GET, request, String.class);
|
||||
HttpHeaders headers = createBasicAuthenticationHeader(struct);
|
||||
HttpEntity<String> request = new HttpEntity<>(headers);
|
||||
ResponseEntity rsp = rest.exchange(link, HttpMethod.GET, request, String.class);
|
||||
logger.debug(String.format("http get: %s", link));
|
||||
|
||||
if (rsp.getStatusCode() == HttpStatus.NOT_FOUND) {
|
||||
PortInfo port = new PortInfo(struct);
|
||||
|
||||
if (rsp.getStatusCode() == HttpStatus.NOT_FOUND) {
|
||||
PortInfo port = new PortInfo(struct);
|
||||
XmlObject xml = new XmlObject("vlan").putElement("vlan-id",
|
||||
new XmlObject("vlan-id").setText(String.valueOf(struct.getVlan()))).putElement("untagged",
|
||||
new XmlObject("untagged").putElement(port.interfaceType, new XmlObject(port.interfaceType)
|
||||
|
|
@ -111,26 +111,26 @@ public class Force10BaremetalSwitchBackend implements BaremetalSwitchBackend {
|
|||
logger.debug(String.format("http get: %s, body: %s", link, request));
|
||||
rsp = rest.exchange(link, HttpMethod.POST, request, String.class);
|
||||
if (!successHttpStatusCode.contains(rsp.getStatusCode())) {
|
||||
throw new CloudRuntimeException(String.format("unable to create vlan[%s] on force10 switch[ip:%s]. HTTP status code:%s, body dump:%s",
|
||||
throw new CloudRuntimeException(String.format("unable to create vlan[%s] on force10 switch[ip:%s]. HTTP status code:%s, body dump:%s",
|
||||
struct.getVlan(), struct.getSwitchIp(),rsp.getStatusCode(), rsp.getBody()));
|
||||
} else {
|
||||
logger.debug(String.format("successfully programmed vlan[%s] on Force10[ip:%s, port:%s]. http response[status code:%s, body:%s]",
|
||||
struct.getVlan(), struct.getSwitchIp(), struct.getPort(), rsp.getStatusCode(), rsp.getBody()));
|
||||
}
|
||||
}
|
||||
} else if (successHttpStatusCode.contains(rsp.getStatusCode())) {
|
||||
PortInfo port = new PortInfo(struct);
|
||||
XmlObject xml = XmlObjectParser.parseFromString((String)rsp.getBody());
|
||||
PortInfo port = new PortInfo(struct);
|
||||
XmlObject xml = XmlObjectParser.parseFromString((String)rsp.getBody());
|
||||
List<XmlObject> ports = xml.getAsList("untagged.tengigabitethernet");
|
||||
ports.addAll(xml.<XmlObject>getAsList("untagged.gigabitethernet"));
|
||||
ports.addAll(xml.<XmlObject>getAsList("untagged.fortyGigE"));
|
||||
for (XmlObject pxml : ports) {
|
||||
XmlObject name = pxml.get("name");
|
||||
if (port.port.equals(name.getText())) {
|
||||
logger.debug(String.format("port[%s] has joined in vlan[%s], no need to program again", struct.getPort(), struct.getVlan()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (XmlObject pxml : ports) {
|
||||
XmlObject name = pxml.get("name");
|
||||
if (port.port.equals(name.getText())) {
|
||||
logger.debug(String.format("port[%s] has joined in vlan[%s], no need to program again", struct.getPort(), struct.getVlan()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
xml.removeElement("mtu");
|
||||
xml.setText(null);
|
||||
XmlObject tag = xml.get("untagged");
|
||||
|
|
@ -144,51 +144,51 @@ public class Force10BaremetalSwitchBackend implements BaremetalSwitchBackend {
|
|||
request = new HttpEntity<>(xml.dump(), headers);
|
||||
link = buildLink(struct.getSwitchIp(), String.format("/api/running/ftos/interface/vlan/%s", struct.getVlan()));
|
||||
logger.debug(String.format("http get: %s, body: %s", link, request));
|
||||
rsp = rest.exchange(link, HttpMethod.PUT, request, String.class);
|
||||
rsp = rest.exchange(link, HttpMethod.PUT, request, String.class);
|
||||
if (!successHttpStatusCode.contains(rsp.getStatusCode())) {
|
||||
throw new CloudRuntimeException(String.format("failed to program vlan[%s] for port[%s] on force10[ip:%s]. http status:%s, body dump:%s",
|
||||
struct.getVlan(), struct.getPort(), struct.getSwitchIp(), rsp.getStatusCode(), rsp.getBody()));
|
||||
throw new CloudRuntimeException(String.format("failed to program vlan[%s] for port[%s] on force10[ip:%s]. http status:%s, body dump:%s",
|
||||
struct.getVlan(), struct.getPort(), struct.getSwitchIp(), rsp.getStatusCode(), rsp.getBody()));
|
||||
} else {
|
||||
logger.debug(String.format("successfully join port[%s] into vlan[%s] on Force10[ip:%s]. http response[status code:%s, body:%s]",
|
||||
struct.getPort(), struct.getVlan(), struct.getSwitchIp(), rsp.getStatusCode(), rsp.getBody()));
|
||||
}
|
||||
} else {
|
||||
throw new CloudRuntimeException(String.format("force10[ip:%s] returns unexpected error[%s] when http getting %s, body dump:%s",
|
||||
struct.getSwitchIp(), rsp.getStatusCode(), link, rsp.getBody()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePortFromVlan(BaremetalVlanStruct struct) {
|
||||
}
|
||||
} else {
|
||||
throw new CloudRuntimeException(String.format("force10[ip:%s] returns unexpected error[%s] when http getting %s, body dump:%s",
|
||||
struct.getSwitchIp(), rsp.getStatusCode(), link, rsp.getBody()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePortFromVlan(BaremetalVlanStruct struct) {
|
||||
String link = buildLink(struct.getSwitchIp(), String.format("/api/running/ftos/interface/vlan/%s", struct.getVlan()));
|
||||
HttpHeaders headers = createBasicAuthenticationHeader(struct);
|
||||
HttpEntity<String> request = new HttpEntity<>(headers);
|
||||
HttpHeaders headers = createBasicAuthenticationHeader(struct);
|
||||
HttpEntity<String> request = new HttpEntity<>(headers);
|
||||
logger.debug(String.format("http get: %s, body: %s", link, request));
|
||||
ResponseEntity rsp = rest.exchange(link, HttpMethod.GET, request, String.class);
|
||||
if (rsp.getStatusCode() == HttpStatus.NOT_FOUND) {
|
||||
logger.debug(String.format("vlan[%s] has been deleted on force10[ip:%s], no need to remove the port[%s] anymore", struct.getVlan(), struct.getSwitchIp(), struct.getPort()));
|
||||
} else if (rsp.getStatusCode() == HttpStatus.OK) {
|
||||
PortInfo port = new PortInfo(struct);
|
||||
XmlObject xml = XmlObjectParser.parseFromString((String)rsp.getBody());
|
||||
ResponseEntity rsp = rest.exchange(link, HttpMethod.GET, request, String.class);
|
||||
if (rsp.getStatusCode() == HttpStatus.NOT_FOUND) {
|
||||
logger.debug(String.format("vlan[%s] has been deleted on force10[ip:%s], no need to remove the port[%s] anymore", struct.getVlan(), struct.getSwitchIp(), struct.getPort()));
|
||||
} else if (rsp.getStatusCode() == HttpStatus.OK) {
|
||||
PortInfo port = new PortInfo(struct);
|
||||
XmlObject xml = XmlObjectParser.parseFromString((String)rsp.getBody());
|
||||
List<XmlObject> ports = xml.getAsList("untagged.tengigabitethernet");
|
||||
ports.addAll(xml.<XmlObject>getAsList("untagged.gigabitethernet"));
|
||||
ports.addAll(xml.<XmlObject>getAsList("untagged.fortyGigE"));
|
||||
List<XmlObject> newPorts = new ArrayList<>();
|
||||
boolean needRemove = false;
|
||||
for (XmlObject pxml : ports) {
|
||||
XmlObject name = pxml.get("name");
|
||||
if (port.port.equals(name.getText())) {
|
||||
needRemove = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
newPorts.add(pxml);
|
||||
}
|
||||
|
||||
if (!needRemove) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<XmlObject> newPorts = new ArrayList<>();
|
||||
boolean needRemove = false;
|
||||
for (XmlObject pxml : ports) {
|
||||
XmlObject name = pxml.get("name");
|
||||
if (port.port.equals(name.getText())) {
|
||||
needRemove = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
newPorts.add(pxml);
|
||||
}
|
||||
|
||||
if (!needRemove) {
|
||||
return;
|
||||
}
|
||||
|
||||
xml.setText(null);
|
||||
xml.removeElement("mtu");
|
||||
XmlObject tagged = xml.get("untagged");
|
||||
|
|
@ -197,56 +197,56 @@ public class Force10BaremetalSwitchBackend implements BaremetalSwitchBackend {
|
|||
tagged.putElement(p.getTag(), p);
|
||||
}
|
||||
|
||||
|
||||
|
||||
request = new HttpEntity<>(xml.dump(), headers);
|
||||
logger.debug(String.format("http get: %s, body: %s", link, request));
|
||||
rsp = rest.exchange(link, HttpMethod.PUT, request, String.class);
|
||||
rsp = rest.exchange(link, HttpMethod.PUT, request, String.class);
|
||||
if (!successHttpStatusCode.contains(rsp.getStatusCode())) {
|
||||
throw new CloudRuntimeException(String.format("failed to program vlan[%s] for port[%s] on force10[ip:%s]. http status:%s, body dump:%s",
|
||||
struct.getVlan(), struct.getPort(), struct.getSwitchIp(), rsp.getStatusCode(), rsp.getBody()));
|
||||
} else {
|
||||
logger.debug(String.format("removed port[%s] from vlan[%s] on force10[ip:%s]", struct.getPort(), struct.getVlan(), struct.getSwitchIp()));
|
||||
}
|
||||
} else {
|
||||
throw new CloudRuntimeException(String.format("force10[ip:%s] returns unexpected error[%s] when http getting %s, body dump:%s",
|
||||
struct.getSwitchIp(), rsp.getStatusCode(), link, rsp.getBody()));
|
||||
}
|
||||
}
|
||||
|
||||
private HttpHeaders createBasicAuthenticationHeader(BaremetalVlanStruct struct) {
|
||||
String plainCreds = String.format("%s:%s", struct.getSwitchUsername(), struct.getSwitchPassword());
|
||||
byte[] plainCredsBytes = plainCreds.getBytes();
|
||||
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
|
||||
String base64Creds = new String(base64CredsBytes);
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add("Authorization", "Basic " + base64Creds);
|
||||
throw new CloudRuntimeException(String.format("failed to program vlan[%s] for port[%s] on force10[ip:%s]. http status:%s, body dump:%s",
|
||||
struct.getVlan(), struct.getPort(), struct.getSwitchIp(), rsp.getStatusCode(), rsp.getBody()));
|
||||
} else {
|
||||
logger.debug(String.format("removed port[%s] from vlan[%s] on force10[ip:%s]", struct.getPort(), struct.getVlan(), struct.getSwitchIp()));
|
||||
}
|
||||
} else {
|
||||
throw new CloudRuntimeException(String.format("force10[ip:%s] returns unexpected error[%s] when http getting %s, body dump:%s",
|
||||
struct.getSwitchIp(), rsp.getStatusCode(), link, rsp.getBody()));
|
||||
}
|
||||
}
|
||||
|
||||
private HttpHeaders createBasicAuthenticationHeader(BaremetalVlanStruct struct) {
|
||||
String plainCreds = String.format("%s:%s", struct.getSwitchUsername(), struct.getSwitchPassword());
|
||||
byte[] plainCredsBytes = plainCreds.getBytes();
|
||||
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
|
||||
String base64Creds = new String(base64CredsBytes);
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add("Authorization", "Basic " + base64Creds);
|
||||
headers.setAccept(Arrays.asList(MediaType.ALL));
|
||||
headers.setContentType(MediaType.valueOf("application/vnd.yang.data+xml"));
|
||||
return headers;
|
||||
}
|
||||
|
||||
private class PortInfo {
|
||||
static final String G_IFACE = "gigabitethernet";
|
||||
static final String TEN_G_IFACE = "tengigabitethernet";
|
||||
static final String FOURTY_G_IFACE = "fortyGigE";
|
||||
|
||||
private String interfaceType;
|
||||
private String port;
|
||||
|
||||
PortInfo(BaremetalVlanStruct struct) {
|
||||
String[] ps = StringUtils.split(struct.getPort(), ":");
|
||||
if (ps.length == 1) {
|
||||
interfaceType = TEN_G_IFACE;
|
||||
port = ps[0];
|
||||
} else if (ps.length == 2) {
|
||||
interfaceType = ps[0];
|
||||
if (!interfaceType.equals(G_IFACE) && !interfaceType.equals(TEN_G_IFACE) && !interfaceType.equals(FOURTY_G_IFACE)) {
|
||||
throw new CloudRuntimeException(String.format("wrong port definition[%s]. The prefix must be one of [%s,%s,%s]", struct.getPort(), G_IFACE, TEN_G_IFACE, FOURTY_G_IFACE));
|
||||
}
|
||||
port = ps[1];
|
||||
} else {
|
||||
throw new CloudRuntimeException(String.format("wrong port definition[%s]. Force10 port should be in format of interface_type:port_identity, for example: tengigabitethernet:1/3", struct.getPort()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
private class PortInfo {
|
||||
static final String G_IFACE = "gigabitethernet";
|
||||
static final String TEN_G_IFACE = "tengigabitethernet";
|
||||
static final String FOURTY_G_IFACE = "fortyGigE";
|
||||
|
||||
private String interfaceType;
|
||||
private String port;
|
||||
|
||||
PortInfo(BaremetalVlanStruct struct) {
|
||||
String[] ps = StringUtils.split(struct.getPort(), ":");
|
||||
if (ps.length == 1) {
|
||||
interfaceType = TEN_G_IFACE;
|
||||
port = ps[0];
|
||||
} else if (ps.length == 2) {
|
||||
interfaceType = ps[0];
|
||||
if (!interfaceType.equals(G_IFACE) && !interfaceType.equals(TEN_G_IFACE) && !interfaceType.equals(FOURTY_G_IFACE)) {
|
||||
throw new CloudRuntimeException(String.format("wrong port definition[%s]. The prefix must be one of [%s,%s,%s]", struct.getPort(), G_IFACE, TEN_G_IFACE, FOURTY_G_IFACE));
|
||||
}
|
||||
port = ps[1];
|
||||
} else {
|
||||
throw new CloudRuntimeException(String.format("wrong port definition[%s]. Force10 port should be in format of interface_type:port_identity, for example: tengigabitethernet:1/3", struct.getPort()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,236 +1,236 @@
|
|||
# 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.
|
||||
#
|
||||
# Automatically generated by addcopyright.py at 01/29/2013
|
||||
'''
|
||||
Created on Jan 2, 2013
|
||||
|
||||
@author: frank
|
||||
'''
|
||||
import cherrypy
|
||||
import sglib
|
||||
import xmlobject
|
||||
import types
|
||||
import uuid
|
||||
import os.path
|
||||
import sys
|
||||
import os
|
||||
|
||||
class SGRule(object):
|
||||
def __init__(self):
|
||||
self.protocol = None
|
||||
self.start_port = None
|
||||
self.end_port = None
|
||||
self.allowed_ips = []
|
||||
|
||||
class IPSet(object):
|
||||
IPSET_TYPE = 'hash:ip'
|
||||
def __init__(self, setname, ips):
|
||||
self.ips = ips
|
||||
self.name = setname
|
||||
|
||||
def create(self):
|
||||
tmpname = str(uuid.uuid4()).replace('-', '')[0:30]
|
||||
sglib.ShellCmd('ipset -N %s %s' % (tmpname, self.IPSET_TYPE))()
|
||||
try:
|
||||
for ip in self.ips:
|
||||
sglib.ShellCmd('ipset -A %s %s' % (tmpname, ip))()
|
||||
|
||||
try:
|
||||
sglib.ShellCmd('ipset -N %s %s' % (self.name, self.IPSET_TYPE))()
|
||||
cherrypy.log('created new ipset: %s' % self.name)
|
||||
except Exception:
|
||||
cherrypy.log('%s already exists, no need to create new' % self.name)
|
||||
finally:
|
||||
sglib.ShellCmd('ipset -W %s %s' % (tmpname, self.name))()
|
||||
sglib.ShellCmd('ipset -F %s' % tmpname)()
|
||||
sglib.ShellCmd('ipset -X %s' % tmpname)()
|
||||
|
||||
@staticmethod
|
||||
def destroy_sets(sets_to_keep):
|
||||
sets = sglib.ShellCmd('ipset list')()
|
||||
for s in sets.split('\n'):
|
||||
if 'Name:' in s:
|
||||
set_name = s.split(':', 1)[1].strip()
|
||||
if not set_name in sets_to_keep:
|
||||
sglib.ShellCmd('ipset destroy %s' % set_name)()
|
||||
cherrypy.log('destroyed unused ipset: %s' % set_name)
|
||||
|
||||
class SGAgent(object):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def _self_list(self, obj):
|
||||
if isinstance(obj, types.ListType):
|
||||
return obj
|
||||
else:
|
||||
return [obj]
|
||||
|
||||
def set_rules(self, req):
|
||||
body = req.body
|
||||
doc = xmlobject.loads(body)
|
||||
vm_name = doc.vmName.text_
|
||||
vm_id = doc.vmId.text_
|
||||
vm_ip = doc.vmIp.text_
|
||||
vm_mac = doc.vmMac.text_
|
||||
sig = doc.signature.text_
|
||||
seq = doc.sequenceNumber.text_
|
||||
|
||||
def parse_rules(rules, lst):
|
||||
for i in self._self_list(rules):
|
||||
r = SGRule()
|
||||
r.protocol = i.protocol.text_
|
||||
r.start_port = i.startPort.text_
|
||||
r.end_port = i.endPort.text_
|
||||
if hasattr(i, 'ip'):
|
||||
for ip in self._self_list(i.ip):
|
||||
r.allowed_ips.append(ip.text_)
|
||||
lst.append(r)
|
||||
|
||||
i_rules = []
|
||||
if hasattr(doc, 'ingressRules'):
|
||||
parse_rules(doc.ingressRules, i_rules)
|
||||
|
||||
e_rules = []
|
||||
if hasattr(doc, 'egressRules'):
|
||||
parse_rules(doc.egressRules, e_rules)
|
||||
|
||||
def create_chain(name):
|
||||
try:
|
||||
sglib.ShellCmd('iptables -F %s' % name)()
|
||||
except Exception:
|
||||
sglib.ShellCmd('iptables -N %s' % name)()
|
||||
|
||||
def apply_rules(rules, chainname, direction, action, current_set_names):
|
||||
create_chain(chainname)
|
||||
for r in i_rules:
|
||||
allow_any = False
|
||||
if '0.0.0.0/0' in r.allowed_ips:
|
||||
allow_any = True
|
||||
r.allowed_ips.remove('0.0.0.0/0')
|
||||
|
||||
if r.allowed_ips:
|
||||
setname = '_'.join([chainname, r.protocol, r.start_port, r.end_port])
|
||||
ipset = IPSet(setname, r.allowed_ips)
|
||||
ipset.create()
|
||||
current_set_names.append(setname)
|
||||
|
||||
if r.protocol == 'all':
|
||||
cmd = ['iptables -I', chainname, '-m state --state NEW -m set --set', setname, direction, '-j', action]
|
||||
sglib.ShellCmd(' '.join(cmd))()
|
||||
elif r.protocol != 'icmp':
|
||||
port_range = ":".join([r.start_port, r.end_port])
|
||||
cmd = ['iptables', '-I', chainname, '-p', r.protocol, '-m', r.protocol, '--dport', port_range, '-m state --state NEW -m set --set', setname, direction, '-j', action]
|
||||
sglib.ShellCmd(' '.join(cmd))()
|
||||
else:
|
||||
port_range = "/".join([r.start_port, r.end_port])
|
||||
if r.start_port == "-1":
|
||||
port_range = "any"
|
||||
cmd = ['iptables', '-I', i_chain_name, '-p', 'icmp', '--icmp-type', port_range, '-m set --set', setname, direction, '-j', action]
|
||||
sglib.ShellCmd(' '.join(cmd))()
|
||||
|
||||
|
||||
if allow_any and r.protocol != 'all':
|
||||
if r.protocol != 'icmp':
|
||||
port_range = ":".join([r.start_port, r.end_port])
|
||||
cmd = ['iptables', '-I', chainname, '-p', r.protocol, '-m', r.protocol, '--dport', port_range, '-m', 'state', '--state', 'NEW', '-j', action]
|
||||
sglib.ShellCmd(' '.join(cmd))()
|
||||
else:
|
||||
port_range = "/".join([r.start_port, r.end_port])
|
||||
if r.start_port == "-1":
|
||||
port_range = "any"
|
||||
cmd = ['iptables', '-I', i_chain_name, '-p', 'icmp', '--icmp-type', port_range, '-j', action]
|
||||
sglib.ShellCmd(' '.join(cmd))()
|
||||
|
||||
current_sets = []
|
||||
i_chain_name = vm_name + '-in'
|
||||
apply_rules(i_rules, i_chain_name, 'src', 'ACCEPT', current_sets)
|
||||
e_chain_name = vm_name + '-eg'
|
||||
apply_rules(e_rules, e_chain_name, 'dst', 'RETURN', current_sets)
|
||||
|
||||
if e_rules:
|
||||
sglib.ShellCmd('iptables -A %s -j RETURN' % e_chain_name)
|
||||
else:
|
||||
sglib.ShellCmd('iptables -A %s -j DROP' % e_chain_name)
|
||||
|
||||
sglib.ShellCmd('iptables -A %s -j DROP' % i_chain_name)
|
||||
IPSet.destroy_sets(current_sets)
|
||||
|
||||
|
||||
def echo(self, req):
|
||||
cherrypy.log("echo: I am alive")
|
||||
|
||||
def index(self):
|
||||
req = sglib.Request.from_cherrypy_request(cherrypy.request)
|
||||
cmd_name = req.headers['command']
|
||||
|
||||
if not hasattr(self, cmd_name):
|
||||
raise ValueError("SecurityGroupAgent doesn't have a method called '%s'" % cmd_name)
|
||||
method = getattr(self, cmd_name)
|
||||
|
||||
return method(req)
|
||||
index.exposed = True
|
||||
|
||||
@staticmethod
|
||||
def start():
|
||||
cherrypy.log.access_file = '/var/log/cs-securitygroup.log'
|
||||
cherrypy.log.error_file = '/var/log/cs-securitygroup.log'
|
||||
cherrypy.server.socket_host = '0.0.0.0'
|
||||
cherrypy.server.socket_port = 9988
|
||||
cherrypy.quickstart(SGAgent())
|
||||
|
||||
@staticmethod
|
||||
def stop():
|
||||
cherrypy.engine.exit()
|
||||
|
||||
PID_FILE = '/var/run/cssgagent.pid'
|
||||
class SGAgentDaemon(sglib.Daemon):
|
||||
def __init__(self):
|
||||
super(SGAgentDaemon, self).__init__(PID_FILE)
|
||||
self.is_stopped = False
|
||||
self.agent = SGAgent()
|
||||
sglib.Daemon.register_atexit_hook(self._do_stop)
|
||||
|
||||
def _do_stop(self):
|
||||
if self.is_stopped:
|
||||
return
|
||||
self.is_stopped = True
|
||||
self.agent.stop()
|
||||
|
||||
def run(self):
|
||||
self.agent.start()
|
||||
|
||||
def stop(self):
|
||||
self.agent.stop()
|
||||
super(SGAgentDaemon, self).stop()
|
||||
|
||||
def main():
|
||||
usage = 'usage: python -c "from security_group_agent import cs_sg_agent; cs_sg_agent.main()" start|stop|restart'
|
||||
if len(sys.argv) != 2 or not sys.argv[1] in ['start', 'stop', 'restart']:
|
||||
print usage
|
||||
sys.exit(1)
|
||||
|
||||
cmd = sys.argv[1]
|
||||
agentdaemon = SGAgentDaemon()
|
||||
if cmd == 'start':
|
||||
agentdaemon.start()
|
||||
elif cmd == 'stop':
|
||||
agentdaemon.stop()
|
||||
else:
|
||||
agentdaemon.restart()
|
||||
|
||||
sys.exit(0)
|
||||
# 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.
|
||||
#
|
||||
# Automatically generated by addcopyright.py at 01/29/2013
|
||||
'''
|
||||
Created on Jan 2, 2013
|
||||
|
||||
@author: frank
|
||||
'''
|
||||
import cherrypy
|
||||
import sglib
|
||||
import xmlobject
|
||||
import types
|
||||
import uuid
|
||||
import os.path
|
||||
import sys
|
||||
import os
|
||||
|
||||
class SGRule(object):
|
||||
def __init__(self):
|
||||
self.protocol = None
|
||||
self.start_port = None
|
||||
self.end_port = None
|
||||
self.allowed_ips = []
|
||||
|
||||
class IPSet(object):
|
||||
IPSET_TYPE = 'hash:ip'
|
||||
def __init__(self, setname, ips):
|
||||
self.ips = ips
|
||||
self.name = setname
|
||||
|
||||
def create(self):
|
||||
tmpname = str(uuid.uuid4()).replace('-', '')[0:30]
|
||||
sglib.ShellCmd('ipset -N %s %s' % (tmpname, self.IPSET_TYPE))()
|
||||
try:
|
||||
for ip in self.ips:
|
||||
sglib.ShellCmd('ipset -A %s %s' % (tmpname, ip))()
|
||||
|
||||
try:
|
||||
sglib.ShellCmd('ipset -N %s %s' % (self.name, self.IPSET_TYPE))()
|
||||
cherrypy.log('created new ipset: %s' % self.name)
|
||||
except Exception:
|
||||
cherrypy.log('%s already exists, no need to create new' % self.name)
|
||||
finally:
|
||||
sglib.ShellCmd('ipset -W %s %s' % (tmpname, self.name))()
|
||||
sglib.ShellCmd('ipset -F %s' % tmpname)()
|
||||
sglib.ShellCmd('ipset -X %s' % tmpname)()
|
||||
|
||||
@staticmethod
|
||||
def destroy_sets(sets_to_keep):
|
||||
sets = sglib.ShellCmd('ipset list')()
|
||||
for s in sets.split('\n'):
|
||||
if 'Name:' in s:
|
||||
set_name = s.split(':', 1)[1].strip()
|
||||
if not set_name in sets_to_keep:
|
||||
sglib.ShellCmd('ipset destroy %s' % set_name)()
|
||||
cherrypy.log('destroyed unused ipset: %s' % set_name)
|
||||
|
||||
class SGAgent(object):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def _self_list(self, obj):
|
||||
if isinstance(obj, types.ListType):
|
||||
return obj
|
||||
else:
|
||||
return [obj]
|
||||
|
||||
def set_rules(self, req):
|
||||
body = req.body
|
||||
doc = xmlobject.loads(body)
|
||||
vm_name = doc.vmName.text_
|
||||
vm_id = doc.vmId.text_
|
||||
vm_ip = doc.vmIp.text_
|
||||
vm_mac = doc.vmMac.text_
|
||||
sig = doc.signature.text_
|
||||
seq = doc.sequenceNumber.text_
|
||||
|
||||
def parse_rules(rules, lst):
|
||||
for i in self._self_list(rules):
|
||||
r = SGRule()
|
||||
r.protocol = i.protocol.text_
|
||||
r.start_port = i.startPort.text_
|
||||
r.end_port = i.endPort.text_
|
||||
if hasattr(i, 'ip'):
|
||||
for ip in self._self_list(i.ip):
|
||||
r.allowed_ips.append(ip.text_)
|
||||
lst.append(r)
|
||||
|
||||
i_rules = []
|
||||
if hasattr(doc, 'ingressRules'):
|
||||
parse_rules(doc.ingressRules, i_rules)
|
||||
|
||||
e_rules = []
|
||||
if hasattr(doc, 'egressRules'):
|
||||
parse_rules(doc.egressRules, e_rules)
|
||||
|
||||
def create_chain(name):
|
||||
try:
|
||||
sglib.ShellCmd('iptables -F %s' % name)()
|
||||
except Exception:
|
||||
sglib.ShellCmd('iptables -N %s' % name)()
|
||||
|
||||
def apply_rules(rules, chainname, direction, action, current_set_names):
|
||||
create_chain(chainname)
|
||||
for r in i_rules:
|
||||
allow_any = False
|
||||
if '0.0.0.0/0' in r.allowed_ips:
|
||||
allow_any = True
|
||||
r.allowed_ips.remove('0.0.0.0/0')
|
||||
|
||||
if r.allowed_ips:
|
||||
setname = '_'.join([chainname, r.protocol, r.start_port, r.end_port])
|
||||
ipset = IPSet(setname, r.allowed_ips)
|
||||
ipset.create()
|
||||
current_set_names.append(setname)
|
||||
|
||||
if r.protocol == 'all':
|
||||
cmd = ['iptables -I', chainname, '-m state --state NEW -m set --set', setname, direction, '-j', action]
|
||||
sglib.ShellCmd(' '.join(cmd))()
|
||||
elif r.protocol != 'icmp':
|
||||
port_range = ":".join([r.start_port, r.end_port])
|
||||
cmd = ['iptables', '-I', chainname, '-p', r.protocol, '-m', r.protocol, '--dport', port_range, '-m state --state NEW -m set --set', setname, direction, '-j', action]
|
||||
sglib.ShellCmd(' '.join(cmd))()
|
||||
else:
|
||||
port_range = "/".join([r.start_port, r.end_port])
|
||||
if r.start_port == "-1":
|
||||
port_range = "any"
|
||||
cmd = ['iptables', '-I', i_chain_name, '-p', 'icmp', '--icmp-type', port_range, '-m set --set', setname, direction, '-j', action]
|
||||
sglib.ShellCmd(' '.join(cmd))()
|
||||
|
||||
|
||||
if allow_any and r.protocol != 'all':
|
||||
if r.protocol != 'icmp':
|
||||
port_range = ":".join([r.start_port, r.end_port])
|
||||
cmd = ['iptables', '-I', chainname, '-p', r.protocol, '-m', r.protocol, '--dport', port_range, '-m', 'state', '--state', 'NEW', '-j', action]
|
||||
sglib.ShellCmd(' '.join(cmd))()
|
||||
else:
|
||||
port_range = "/".join([r.start_port, r.end_port])
|
||||
if r.start_port == "-1":
|
||||
port_range = "any"
|
||||
cmd = ['iptables', '-I', i_chain_name, '-p', 'icmp', '--icmp-type', port_range, '-j', action]
|
||||
sglib.ShellCmd(' '.join(cmd))()
|
||||
|
||||
current_sets = []
|
||||
i_chain_name = vm_name + '-in'
|
||||
apply_rules(i_rules, i_chain_name, 'src', 'ACCEPT', current_sets)
|
||||
e_chain_name = vm_name + '-eg'
|
||||
apply_rules(e_rules, e_chain_name, 'dst', 'RETURN', current_sets)
|
||||
|
||||
if e_rules:
|
||||
sglib.ShellCmd('iptables -A %s -j RETURN' % e_chain_name)
|
||||
else:
|
||||
sglib.ShellCmd('iptables -A %s -j DROP' % e_chain_name)
|
||||
|
||||
sglib.ShellCmd('iptables -A %s -j DROP' % i_chain_name)
|
||||
IPSet.destroy_sets(current_sets)
|
||||
|
||||
|
||||
def echo(self, req):
|
||||
cherrypy.log("echo: I am alive")
|
||||
|
||||
def index(self):
|
||||
req = sglib.Request.from_cherrypy_request(cherrypy.request)
|
||||
cmd_name = req.headers['command']
|
||||
|
||||
if not hasattr(self, cmd_name):
|
||||
raise ValueError("SecurityGroupAgent doesn't have a method called '%s'" % cmd_name)
|
||||
method = getattr(self, cmd_name)
|
||||
|
||||
return method(req)
|
||||
index.exposed = True
|
||||
|
||||
@staticmethod
|
||||
def start():
|
||||
cherrypy.log.access_file = '/var/log/cs-securitygroup.log'
|
||||
cherrypy.log.error_file = '/var/log/cs-securitygroup.log'
|
||||
cherrypy.server.socket_host = '0.0.0.0'
|
||||
cherrypy.server.socket_port = 9988
|
||||
cherrypy.quickstart(SGAgent())
|
||||
|
||||
@staticmethod
|
||||
def stop():
|
||||
cherrypy.engine.exit()
|
||||
|
||||
PID_FILE = '/var/run/cssgagent.pid'
|
||||
class SGAgentDaemon(sglib.Daemon):
|
||||
def __init__(self):
|
||||
super(SGAgentDaemon, self).__init__(PID_FILE)
|
||||
self.is_stopped = False
|
||||
self.agent = SGAgent()
|
||||
sglib.Daemon.register_atexit_hook(self._do_stop)
|
||||
|
||||
def _do_stop(self):
|
||||
if self.is_stopped:
|
||||
return
|
||||
self.is_stopped = True
|
||||
self.agent.stop()
|
||||
|
||||
def run(self):
|
||||
self.agent.start()
|
||||
|
||||
def stop(self):
|
||||
self.agent.stop()
|
||||
super(SGAgentDaemon, self).stop()
|
||||
|
||||
def main():
|
||||
usage = 'usage: python -c "from security_group_agent import cs_sg_agent; cs_sg_agent.main()" start|stop|restart'
|
||||
if len(sys.argv) != 2 or not sys.argv[1] in ['start', 'stop', 'restart']:
|
||||
print usage
|
||||
sys.exit(1)
|
||||
|
||||
cmd = sys.argv[1]
|
||||
agentdaemon = SGAgentDaemon()
|
||||
if cmd == 'start':
|
||||
agentdaemon.start()
|
||||
elif cmd == 'stop':
|
||||
agentdaemon.stop()
|
||||
else:
|
||||
agentdaemon.restart()
|
||||
|
||||
sys.exit(0)
|
||||
|
|
|
|||
|
|
@ -1,97 +1,97 @@
|
|||
# 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.
|
||||
#
|
||||
# Automatically generated by addcopyright.py at 01/29/2013
|
||||
'''
|
||||
Created on Dec 25, 2012
|
||||
|
||||
@author: Frank
|
||||
'''
|
||||
import xml.etree.ElementTree as etree
|
||||
import re
|
||||
import types
|
||||
|
||||
class XmlObject(object):
|
||||
def __init__(self, tag):
|
||||
self.__tag_name__ = tag
|
||||
|
||||
def put_attr(self, name, val):
|
||||
val = val.strip().strip('\t')
|
||||
setattr(self, name + '_', val)
|
||||
|
||||
def put_text(self, val):
|
||||
val = val.strip().strip('\n').strip('\t')
|
||||
if val == "":
|
||||
setattr(self, 'text_', None)
|
||||
else:
|
||||
setattr(self, 'text_', val)
|
||||
|
||||
def put_node(self, name, val):
|
||||
if not hasattr(self, name):
|
||||
setattr(self, name, val)
|
||||
return
|
||||
|
||||
nodes = getattr(self, name)
|
||||
if not isinstance(nodes, types.ListType):
|
||||
nodes = []
|
||||
old = getattr(self, name)
|
||||
nodes.append(old)
|
||||
nodes.append(val)
|
||||
setattr(self, name, nodes)
|
||||
else:
|
||||
nodes.append(val)
|
||||
setattr(self, name, nodes)
|
||||
|
||||
def get(self, name, default=None):
|
||||
if hasattr(self, name):
|
||||
val = getattr(self, name)
|
||||
if name.endswith('_'):
|
||||
return val
|
||||
else:
|
||||
return val.text_
|
||||
else:
|
||||
return default
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name.endswith('__'):
|
||||
n = name[:-1]
|
||||
if hasattr(self, n):
|
||||
return getattr(self, n)
|
||||
else:
|
||||
return None
|
||||
else:
|
||||
e = AttributeError('%s has no attribute %s. missing attribute %s in element <%s>' % (self.__class__.__name__, name, name, self.__tag_name__))
|
||||
setattr(e, 'missing_attrib', name)
|
||||
setattr(e, 'tag_name', self.__tag_name__)
|
||||
raise e
|
||||
|
||||
|
||||
def _loads(node):
|
||||
xo = XmlObject(node.tag)
|
||||
for key in node.attrib.keys():
|
||||
xo.put_attr(key, node.attrib.get(key))
|
||||
if node.text:
|
||||
xo.put_text(node.text)
|
||||
for n in list(node):
|
||||
sub_xo = _loads(n)
|
||||
xo.put_node(n.tag, sub_xo)
|
||||
return xo
|
||||
|
||||
def loads(xmlstr):
|
||||
xmlstr = re.sub(r'xmlns=".*"', '', xmlstr)
|
||||
root = etree.fromstring(xmlstr)
|
||||
return _loads(root)
|
||||
# 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.
|
||||
#
|
||||
# Automatically generated by addcopyright.py at 01/29/2013
|
||||
'''
|
||||
Created on Dec 25, 2012
|
||||
|
||||
@author: Frank
|
||||
'''
|
||||
import xml.etree.ElementTree as etree
|
||||
import re
|
||||
import types
|
||||
|
||||
class XmlObject(object):
|
||||
def __init__(self, tag):
|
||||
self.__tag_name__ = tag
|
||||
|
||||
def put_attr(self, name, val):
|
||||
val = val.strip().strip('\t')
|
||||
setattr(self, name + '_', val)
|
||||
|
||||
def put_text(self, val):
|
||||
val = val.strip().strip('\n').strip('\t')
|
||||
if val == "":
|
||||
setattr(self, 'text_', None)
|
||||
else:
|
||||
setattr(self, 'text_', val)
|
||||
|
||||
def put_node(self, name, val):
|
||||
if not hasattr(self, name):
|
||||
setattr(self, name, val)
|
||||
return
|
||||
|
||||
nodes = getattr(self, name)
|
||||
if not isinstance(nodes, types.ListType):
|
||||
nodes = []
|
||||
old = getattr(self, name)
|
||||
nodes.append(old)
|
||||
nodes.append(val)
|
||||
setattr(self, name, nodes)
|
||||
else:
|
||||
nodes.append(val)
|
||||
setattr(self, name, nodes)
|
||||
|
||||
def get(self, name, default=None):
|
||||
if hasattr(self, name):
|
||||
val = getattr(self, name)
|
||||
if name.endswith('_'):
|
||||
return val
|
||||
else:
|
||||
return val.text_
|
||||
else:
|
||||
return default
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name.endswith('__'):
|
||||
n = name[:-1]
|
||||
if hasattr(self, n):
|
||||
return getattr(self, n)
|
||||
else:
|
||||
return None
|
||||
else:
|
||||
e = AttributeError('%s has no attribute %s. missing attribute %s in element <%s>' % (self.__class__.__name__, name, name, self.__tag_name__))
|
||||
setattr(e, 'missing_attrib', name)
|
||||
setattr(e, 'tag_name', self.__tag_name__)
|
||||
raise e
|
||||
|
||||
|
||||
def _loads(node):
|
||||
xo = XmlObject(node.tag)
|
||||
for key in node.attrib.keys():
|
||||
xo.put_attr(key, node.attrib.get(key))
|
||||
if node.text:
|
||||
xo.put_text(node.text)
|
||||
for n in list(node):
|
||||
sub_xo = _loads(n)
|
||||
xo.put_node(n.tag, sub_xo)
|
||||
return xo
|
||||
|
||||
def loads(xmlstr):
|
||||
xmlstr = re.sub(r'xmlns=".*"', '', xmlstr)
|
||||
root = etree.fromstring(xmlstr)
|
||||
return _loads(root)
|
||||
|
|
|
|||
|
|
@ -1,200 +1,200 @@
|
|||
# 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.
|
||||
""" BVT tests for Hosts Test
|
||||
"""
|
||||
|
||||
# Import Local Modules
|
||||
from marvin.codes import FAILED
|
||||
from marvin.cloudstackTestCase import *
|
||||
from marvin.cloudstackAPI import *
|
||||
from marvin.lib.utils import *
|
||||
from marvin.lib.base import *
|
||||
from marvin.lib.common import *
|
||||
from nose.plugins.attrib import attr
|
||||
from marvin.sshClient import SshClient
|
||||
import time
|
||||
from time import sleep
|
||||
|
||||
_multiprocess_shared_ = False
|
||||
|
||||
|
||||
class TestHostHA(cloudstackTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.logger = logging.getLogger('TestHM')
|
||||
self.stream_handler = logging.StreamHandler()
|
||||
self.logger.setLevel(logging.DEBUG)
|
||||
self.logger.addHandler(self.stream_handler)
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.hypervisor = self.testClient.getHypervisorInfo()
|
||||
self.mgtSvrDetails = self.config.__dict__["mgtSvr"][0].__dict__
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.services = self.testClient.getParsedTestDataConfig()
|
||||
self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests())
|
||||
self.pod = get_pod(self.apiclient, self.zone.id)
|
||||
self.cleanup = []
|
||||
self.services = {
|
||||
"service_offering": {
|
||||
"name": "Ultra Tiny Instance",
|
||||
"displaytext": "Ultra Tiny Instance",
|
||||
"cpunumber": 1,
|
||||
"cpuspeed": 100,
|
||||
"memory": 128,
|
||||
},
|
||||
"service_offering_local": {
|
||||
"name": "Ultra Tiny Local Instance",
|
||||
"displaytext": "Ultra Tiny Local Instance",
|
||||
"cpunumber": 1,
|
||||
"cpuspeed": 100,
|
||||
"memory": 128,
|
||||
"storagetype": "local"
|
||||
},
|
||||
"vm": {
|
||||
"username": "root",
|
||||
"password": "password",
|
||||
"ssh_port": 22,
|
||||
# Hypervisor type should be same as
|
||||
# hypervisor type of cluster
|
||||
"privateport": 22,
|
||||
"publicport": 22,
|
||||
"protocol": 'TCP',
|
||||
},
|
||||
"natrule": {
|
||||
"privateport": 22,
|
||||
"publicport": 22,
|
||||
"startport": 22,
|
||||
"endport": 22,
|
||||
"protocol": "TCP",
|
||||
"cidrlist": '0.0.0.0/0',
|
||||
},
|
||||
"ostype": 'CentOS 5.3 (64-bit)',
|
||||
"sleep": 60,
|
||||
"timeout": 10,
|
||||
}
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
# Clean up, terminate the created templates
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
|
||||
return
|
||||
|
||||
def checkHostDown(self, fromHostIp, testHostIp):
|
||||
try:
|
||||
ssh = SshClient(fromHostIp, 22, "root", "password")
|
||||
res = ssh.execute("ping -c 1 %s" % testHostIp)
|
||||
result = str(res)
|
||||
if result.count("100% packet loss") == 1:
|
||||
return True, 1
|
||||
else:
|
||||
return False, 1
|
||||
except Exception as e:
|
||||
self.logger.debug("Got exception %s" % e)
|
||||
return False, 1
|
||||
|
||||
def checkHostUp(self, fromHostIp, testHostIp):
|
||||
try:
|
||||
ssh = SshClient(fromHostIp, 22, "root", "password")
|
||||
res = ssh.execute("ping -c 1 %s" % testHostIp)
|
||||
result = str(res)
|
||||
if result.count(" 0% packet loss") == 1:
|
||||
return True, 1
|
||||
else:
|
||||
return False, 1
|
||||
except Exception as e:
|
||||
self.logger.debug("Got exception %s" % e)
|
||||
return False, 1
|
||||
|
||||
def checkHostStateInCloudstack(self, state, hostId):
|
||||
try:
|
||||
listHost = Host.list(
|
||||
self.apiclient,
|
||||
type='Routing',
|
||||
zoneid=self.zone.id,
|
||||
podid=self.pod.id,
|
||||
id=hostId
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(listHost, list),
|
||||
True,
|
||||
"Check if listHost returns a valid response"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
len(listHost),
|
||||
1,
|
||||
"Check if listHost returns a host"
|
||||
)
|
||||
self.logger.debug(" Host state is %s " % listHost[0].state)
|
||||
if listHost[0].state == state:
|
||||
return True, 1
|
||||
else:
|
||||
return False, 1
|
||||
except Exception as e:
|
||||
self.logger.debug("Got exception %s" % e)
|
||||
return False, 1
|
||||
|
||||
def updateConfigurAndRestart(self, name, value):
|
||||
Configurations.update(self.apiclient, name, value)
|
||||
self.RestartServers()
|
||||
time.sleep(self.services["sleep"])
|
||||
|
||||
def RestartServers(self):
|
||||
""" Restart management
|
||||
server and usage server """
|
||||
sshClient = SshClient(self.mgtSvrDetails["mgtSvrIp"],
|
||||
22,
|
||||
self.mgtSvrDetails["user"],
|
||||
self.mgtSvrDetails["passwd"]
|
||||
)
|
||||
command = "service cloudstack-management restart"
|
||||
sshClient.execute(command)
|
||||
return
|
||||
|
||||
@attr(
|
||||
tags=[
|
||||
"advanced",
|
||||
"advancedns",
|
||||
"smoke",
|
||||
"basic",
|
||||
"eip",
|
||||
"sg"],
|
||||
required_hardware="true")
|
||||
def test_01_host_ha_with_nfs_storagepool_with_vm(self):
|
||||
Configurations.update(self.apiclient, "ping.timeout", "150")
|
||||
self.updateConfigurAndRestart("ping.interval", "150")
|
||||
|
||||
listHost = Host.list(
|
||||
self.apiclient,
|
||||
type='Routing',
|
||||
zoneid=self.zone.id,
|
||||
podid=self.pod.id,
|
||||
)
|
||||
for host in listHost:
|
||||
self.logger.debug('Hypervisor = {}'.format(host.id))
|
||||
|
||||
|
||||
hostToTest = listHost[0]
|
||||
hostUpInCloudstack = wait_until(40, 10, self.checkHostStateInCloudstack, "Up", hostToTest.id)
|
||||
|
||||
if not(hostUpInCloudstack):
|
||||
raise self.fail("Host is not up %s, in cloudstack so failing test " % (hostToTest.ipaddress))
|
||||
return
|
||||
# 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.
|
||||
""" BVT tests for Hosts Test
|
||||
"""
|
||||
|
||||
# Import Local Modules
|
||||
from marvin.codes import FAILED
|
||||
from marvin.cloudstackTestCase import *
|
||||
from marvin.cloudstackAPI import *
|
||||
from marvin.lib.utils import *
|
||||
from marvin.lib.base import *
|
||||
from marvin.lib.common import *
|
||||
from nose.plugins.attrib import attr
|
||||
from marvin.sshClient import SshClient
|
||||
import time
|
||||
from time import sleep
|
||||
|
||||
_multiprocess_shared_ = False
|
||||
|
||||
|
||||
class TestHostHA(cloudstackTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.logger = logging.getLogger('TestHM')
|
||||
self.stream_handler = logging.StreamHandler()
|
||||
self.logger.setLevel(logging.DEBUG)
|
||||
self.logger.addHandler(self.stream_handler)
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.hypervisor = self.testClient.getHypervisorInfo()
|
||||
self.mgtSvrDetails = self.config.__dict__["mgtSvr"][0].__dict__
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.services = self.testClient.getParsedTestDataConfig()
|
||||
self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests())
|
||||
self.pod = get_pod(self.apiclient, self.zone.id)
|
||||
self.cleanup = []
|
||||
self.services = {
|
||||
"service_offering": {
|
||||
"name": "Ultra Tiny Instance",
|
||||
"displaytext": "Ultra Tiny Instance",
|
||||
"cpunumber": 1,
|
||||
"cpuspeed": 100,
|
||||
"memory": 128,
|
||||
},
|
||||
"service_offering_local": {
|
||||
"name": "Ultra Tiny Local Instance",
|
||||
"displaytext": "Ultra Tiny Local Instance",
|
||||
"cpunumber": 1,
|
||||
"cpuspeed": 100,
|
||||
"memory": 128,
|
||||
"storagetype": "local"
|
||||
},
|
||||
"vm": {
|
||||
"username": "root",
|
||||
"password": "password",
|
||||
"ssh_port": 22,
|
||||
# Hypervisor type should be same as
|
||||
# hypervisor type of cluster
|
||||
"privateport": 22,
|
||||
"publicport": 22,
|
||||
"protocol": 'TCP',
|
||||
},
|
||||
"natrule": {
|
||||
"privateport": 22,
|
||||
"publicport": 22,
|
||||
"startport": 22,
|
||||
"endport": 22,
|
||||
"protocol": "TCP",
|
||||
"cidrlist": '0.0.0.0/0',
|
||||
},
|
||||
"ostype": 'CentOS 5.3 (64-bit)',
|
||||
"sleep": 60,
|
||||
"timeout": 10,
|
||||
}
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
# Clean up, terminate the created templates
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
|
||||
return
|
||||
|
||||
def checkHostDown(self, fromHostIp, testHostIp):
|
||||
try:
|
||||
ssh = SshClient(fromHostIp, 22, "root", "password")
|
||||
res = ssh.execute("ping -c 1 %s" % testHostIp)
|
||||
result = str(res)
|
||||
if result.count("100% packet loss") == 1:
|
||||
return True, 1
|
||||
else:
|
||||
return False, 1
|
||||
except Exception as e:
|
||||
self.logger.debug("Got exception %s" % e)
|
||||
return False, 1
|
||||
|
||||
def checkHostUp(self, fromHostIp, testHostIp):
|
||||
try:
|
||||
ssh = SshClient(fromHostIp, 22, "root", "password")
|
||||
res = ssh.execute("ping -c 1 %s" % testHostIp)
|
||||
result = str(res)
|
||||
if result.count(" 0% packet loss") == 1:
|
||||
return True, 1
|
||||
else:
|
||||
return False, 1
|
||||
except Exception as e:
|
||||
self.logger.debug("Got exception %s" % e)
|
||||
return False, 1
|
||||
|
||||
def checkHostStateInCloudstack(self, state, hostId):
|
||||
try:
|
||||
listHost = Host.list(
|
||||
self.apiclient,
|
||||
type='Routing',
|
||||
zoneid=self.zone.id,
|
||||
podid=self.pod.id,
|
||||
id=hostId
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(listHost, list),
|
||||
True,
|
||||
"Check if listHost returns a valid response"
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
len(listHost),
|
||||
1,
|
||||
"Check if listHost returns a host"
|
||||
)
|
||||
self.logger.debug(" Host state is %s " % listHost[0].state)
|
||||
if listHost[0].state == state:
|
||||
return True, 1
|
||||
else:
|
||||
return False, 1
|
||||
except Exception as e:
|
||||
self.logger.debug("Got exception %s" % e)
|
||||
return False, 1
|
||||
|
||||
def updateConfigurAndRestart(self, name, value):
|
||||
Configurations.update(self.apiclient, name, value)
|
||||
self.RestartServers()
|
||||
time.sleep(self.services["sleep"])
|
||||
|
||||
def RestartServers(self):
|
||||
""" Restart management
|
||||
server and usage server """
|
||||
sshClient = SshClient(self.mgtSvrDetails["mgtSvrIp"],
|
||||
22,
|
||||
self.mgtSvrDetails["user"],
|
||||
self.mgtSvrDetails["passwd"]
|
||||
)
|
||||
command = "service cloudstack-management restart"
|
||||
sshClient.execute(command)
|
||||
return
|
||||
|
||||
@attr(
|
||||
tags=[
|
||||
"advanced",
|
||||
"advancedns",
|
||||
"smoke",
|
||||
"basic",
|
||||
"eip",
|
||||
"sg"],
|
||||
required_hardware="true")
|
||||
def test_01_host_ha_with_nfs_storagepool_with_vm(self):
|
||||
Configurations.update(self.apiclient, "ping.timeout", "150")
|
||||
self.updateConfigurAndRestart("ping.interval", "150")
|
||||
|
||||
listHost = Host.list(
|
||||
self.apiclient,
|
||||
type='Routing',
|
||||
zoneid=self.zone.id,
|
||||
podid=self.pod.id,
|
||||
)
|
||||
for host in listHost:
|
||||
self.logger.debug('Hypervisor = {}'.format(host.id))
|
||||
|
||||
|
||||
hostToTest = listHost[0]
|
||||
hostUpInCloudstack = wait_until(40, 10, self.checkHostStateInCloudstack, "Up", hostToTest.id)
|
||||
|
||||
if not(hostUpInCloudstack):
|
||||
raise self.fail("Host is not up %s, in cloudstack so failing test " % (hostToTest.ipaddress))
|
||||
return
|
||||
|
|
|
|||
|
|
@ -1,217 +1,217 @@
|
|||
# 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.
|
||||
from marvin.cloudstackTestCase import cloudstackTestCase
|
||||
from marvin.lib.base import *
|
||||
from marvin.lib.common import get_zone, get_domain, get_template
|
||||
from marvin.lib.utils import cleanup_resources
|
||||
|
||||
|
||||
class Services:
|
||||
"""Test multi tag support in compute offerings
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.services = {
|
||||
"account": {
|
||||
"email": "john@doe.de",
|
||||
"firstname": "Test",
|
||||
"lastname": "User",
|
||||
"username": "test",
|
||||
# Random characters are appended for unique
|
||||
# username
|
||||
"password": "password",
|
||||
},
|
||||
"service_offering_0": {
|
||||
"name": "NoTag",
|
||||
"displaytext": "NoTag",
|
||||
"cpunumber": 1,
|
||||
"cpuspeed": 100,
|
||||
# in MHz
|
||||
"memory": 128,
|
||||
# In MBs
|
||||
},
|
||||
"service_offering_1": {
|
||||
"name": "OneTag",
|
||||
"displaytext": "OneTag",
|
||||
"cpunumber": 1,
|
||||
"cpuspeed": 100,
|
||||
"hosttags": "tag1",
|
||||
# in MHz
|
||||
"memory": 128,
|
||||
# In MBs
|
||||
},
|
||||
"service_offering_2": {
|
||||
"name": "TwoTag",
|
||||
"displaytext": "TwoTag",
|
||||
"cpunumber": 1,
|
||||
"cpuspeed": 100,
|
||||
"hosttags": "tag2,tag1",
|
||||
# in MHz
|
||||
"memory": 128,
|
||||
# In MBs
|
||||
},
|
||||
"service_offering_not_existing_tag": {
|
||||
"name": "NotExistingTag",
|
||||
"displaytext": "NotExistingTag",
|
||||
"cpunumber": 1,
|
||||
"cpuspeed": 100,
|
||||
"hosttags": "tagX",
|
||||
# in MHz
|
||||
"memory": 128,
|
||||
# In MBs
|
||||
},
|
||||
"virtual_machine": {
|
||||
"name": "TestVM",
|
||||
"displayname": "TestVM"
|
||||
},
|
||||
"template": {
|
||||
"displaytext": "Ubuntu",
|
||||
"name": "Ubuntu16 x64",
|
||||
"ostype": 'Ubuntu 16.04 (64-bit)',
|
||||
"templatefilter": 'self',
|
||||
},
|
||||
"network": {
|
||||
"name": "Guest",
|
||||
},
|
||||
"host": {
|
||||
"name": ""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class TestMultiTagSupport(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.testClient = super(TestMultiTagSupport, cls).getClsTestClient()
|
||||
cls.hypervisor = cls.testClient.getHypervisorInfo()
|
||||
cls.api_client = cls.testClient.getApiClient()
|
||||
cls.services = Services().services
|
||||
cls.zone = get_zone(cls.api_client)
|
||||
cls.domain = get_domain(cls.api_client)
|
||||
cls.network = cls.get_network()
|
||||
cls.host = cls.get_host()
|
||||
cls.host_tags = cls.host["hosttags"]
|
||||
|
||||
cls.template = get_template(
|
||||
cls.api_client,
|
||||
cls.zone.id,
|
||||
cls.services["template"]["ostype"]
|
||||
)
|
||||
|
||||
cls.service_offering_list = []
|
||||
for x in range(0, 3):
|
||||
cls.service_offering_list.append(ServiceOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["service_offering_" + str(x)]
|
||||
))
|
||||
|
||||
cls.service_offering_ne_tag = ServiceOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["service_offering_not_existing_tag"]
|
||||
)
|
||||
|
||||
cls.account = Account.create(
|
||||
cls.api_client,
|
||||
cls.services["account"],
|
||||
admin=True,
|
||||
)
|
||||
|
||||
cls._cleanup = [
|
||||
cls.account,
|
||||
cls.service_offering_ne_tag,
|
||||
] + cls.service_offering_list
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
# Cleanup resources used
|
||||
print("Cleanup resources used")
|
||||
Host.update(cls.api_client, id=cls.host["id"], hosttags=cls.host_tags)
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def test_multi_tags(self):
|
||||
for x in range(0, len(self.service_offering_list)):
|
||||
|
||||
if hasattr(self.service_offering_list[x], 'hosttags'):
|
||||
Host.update(self.api_client, id=self.host["id"], hosttags=self.service_offering_list[x].hosttags)
|
||||
|
||||
vm = VirtualMachine.create(
|
||||
self.api_client,
|
||||
self.services["virtual_machine"],
|
||||
accountid=self.account.name,
|
||||
domainid=self.account.domainid,
|
||||
zoneid=self.zone.id,
|
||||
serviceofferingid=self.service_offering_list[x].id,
|
||||
templateid=self.template.id,
|
||||
networkids=self.network.id
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(vm, VirtualMachine),
|
||||
True,
|
||||
"VM %s should be created with service offering %s " %
|
||||
(self.services["virtual_machine"]["name"], self.service_offering_list[x].name))
|
||||
|
||||
vm.delete(self.api_client, True)
|
||||
|
||||
def test_no_existing_tag(self):
|
||||
|
||||
with self.assertRaises(Exception):
|
||||
VirtualMachine.create(
|
||||
self.api_client,
|
||||
self.services["virtual_machine"],
|
||||
accountid=self.account.name,
|
||||
domainid=self.account.domainid,
|
||||
zoneid=self.zone.id,
|
||||
serviceofferingid=self.service_offering_ne_tag.id,
|
||||
templateid=self.template.id,
|
||||
networkids=self.network.id
|
||||
)
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def get_network(cls):
|
||||
networks = Network.list(cls.api_client, zoneid=cls.zone.id)
|
||||
if len(networks) == 1:
|
||||
return networks[0]
|
||||
|
||||
if len(networks) > 1:
|
||||
for network in networks:
|
||||
if network.name == cls.services["network"]["name"]:
|
||||
return network
|
||||
raise ValueError("No suitable network found, check network name in service object")
|
||||
|
||||
raise ValueError("No network found for zone with id %s" % cls.zone.id)
|
||||
|
||||
@classmethod
|
||||
def get_host(cls):
|
||||
hosts = Host.list(cls.api_client, zoneid=cls.zone.id)
|
||||
|
||||
if len(hosts) == 1:
|
||||
return hosts[0]
|
||||
|
||||
if len(hosts) > 1:
|
||||
for host in hosts:
|
||||
if host.name == cls.services["host"]["name"]:
|
||||
return host
|
||||
raise ValueError("No suitable host found, check host name in service object")
|
||||
|
||||
raise ValueError("No host found for zone with id %s" % cls.zone.id)
|
||||
# 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.
|
||||
from marvin.cloudstackTestCase import cloudstackTestCase
|
||||
from marvin.lib.base import *
|
||||
from marvin.lib.common import get_zone, get_domain, get_template
|
||||
from marvin.lib.utils import cleanup_resources
|
||||
|
||||
|
||||
class Services:
|
||||
"""Test multi tag support in compute offerings
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.services = {
|
||||
"account": {
|
||||
"email": "john@doe.de",
|
||||
"firstname": "Test",
|
||||
"lastname": "User",
|
||||
"username": "test",
|
||||
# Random characters are appended for unique
|
||||
# username
|
||||
"password": "password",
|
||||
},
|
||||
"service_offering_0": {
|
||||
"name": "NoTag",
|
||||
"displaytext": "NoTag",
|
||||
"cpunumber": 1,
|
||||
"cpuspeed": 100,
|
||||
# in MHz
|
||||
"memory": 128,
|
||||
# In MBs
|
||||
},
|
||||
"service_offering_1": {
|
||||
"name": "OneTag",
|
||||
"displaytext": "OneTag",
|
||||
"cpunumber": 1,
|
||||
"cpuspeed": 100,
|
||||
"hosttags": "tag1",
|
||||
# in MHz
|
||||
"memory": 128,
|
||||
# In MBs
|
||||
},
|
||||
"service_offering_2": {
|
||||
"name": "TwoTag",
|
||||
"displaytext": "TwoTag",
|
||||
"cpunumber": 1,
|
||||
"cpuspeed": 100,
|
||||
"hosttags": "tag2,tag1",
|
||||
# in MHz
|
||||
"memory": 128,
|
||||
# In MBs
|
||||
},
|
||||
"service_offering_not_existing_tag": {
|
||||
"name": "NotExistingTag",
|
||||
"displaytext": "NotExistingTag",
|
||||
"cpunumber": 1,
|
||||
"cpuspeed": 100,
|
||||
"hosttags": "tagX",
|
||||
# in MHz
|
||||
"memory": 128,
|
||||
# In MBs
|
||||
},
|
||||
"virtual_machine": {
|
||||
"name": "TestVM",
|
||||
"displayname": "TestVM"
|
||||
},
|
||||
"template": {
|
||||
"displaytext": "Ubuntu",
|
||||
"name": "Ubuntu16 x64",
|
||||
"ostype": 'Ubuntu 16.04 (64-bit)',
|
||||
"templatefilter": 'self',
|
||||
},
|
||||
"network": {
|
||||
"name": "Guest",
|
||||
},
|
||||
"host": {
|
||||
"name": ""
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class TestMultiTagSupport(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.testClient = super(TestMultiTagSupport, cls).getClsTestClient()
|
||||
cls.hypervisor = cls.testClient.getHypervisorInfo()
|
||||
cls.api_client = cls.testClient.getApiClient()
|
||||
cls.services = Services().services
|
||||
cls.zone = get_zone(cls.api_client)
|
||||
cls.domain = get_domain(cls.api_client)
|
||||
cls.network = cls.get_network()
|
||||
cls.host = cls.get_host()
|
||||
cls.host_tags = cls.host["hosttags"]
|
||||
|
||||
cls.template = get_template(
|
||||
cls.api_client,
|
||||
cls.zone.id,
|
||||
cls.services["template"]["ostype"]
|
||||
)
|
||||
|
||||
cls.service_offering_list = []
|
||||
for x in range(0, 3):
|
||||
cls.service_offering_list.append(ServiceOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["service_offering_" + str(x)]
|
||||
))
|
||||
|
||||
cls.service_offering_ne_tag = ServiceOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["service_offering_not_existing_tag"]
|
||||
)
|
||||
|
||||
cls.account = Account.create(
|
||||
cls.api_client,
|
||||
cls.services["account"],
|
||||
admin=True,
|
||||
)
|
||||
|
||||
cls._cleanup = [
|
||||
cls.account,
|
||||
cls.service_offering_ne_tag,
|
||||
] + cls.service_offering_list
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
# Cleanup resources used
|
||||
print("Cleanup resources used")
|
||||
Host.update(cls.api_client, id=cls.host["id"], hosttags=cls.host_tags)
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def test_multi_tags(self):
|
||||
for x in range(0, len(self.service_offering_list)):
|
||||
|
||||
if hasattr(self.service_offering_list[x], 'hosttags'):
|
||||
Host.update(self.api_client, id=self.host["id"], hosttags=self.service_offering_list[x].hosttags)
|
||||
|
||||
vm = VirtualMachine.create(
|
||||
self.api_client,
|
||||
self.services["virtual_machine"],
|
||||
accountid=self.account.name,
|
||||
domainid=self.account.domainid,
|
||||
zoneid=self.zone.id,
|
||||
serviceofferingid=self.service_offering_list[x].id,
|
||||
templateid=self.template.id,
|
||||
networkids=self.network.id
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(vm, VirtualMachine),
|
||||
True,
|
||||
"VM %s should be created with service offering %s " %
|
||||
(self.services["virtual_machine"]["name"], self.service_offering_list[x].name))
|
||||
|
||||
vm.delete(self.api_client, True)
|
||||
|
||||
def test_no_existing_tag(self):
|
||||
|
||||
with self.assertRaises(Exception):
|
||||
VirtualMachine.create(
|
||||
self.api_client,
|
||||
self.services["virtual_machine"],
|
||||
accountid=self.account.name,
|
||||
domainid=self.account.domainid,
|
||||
zoneid=self.zone.id,
|
||||
serviceofferingid=self.service_offering_ne_tag.id,
|
||||
templateid=self.template.id,
|
||||
networkids=self.network.id
|
||||
)
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def get_network(cls):
|
||||
networks = Network.list(cls.api_client, zoneid=cls.zone.id)
|
||||
if len(networks) == 1:
|
||||
return networks[0]
|
||||
|
||||
if len(networks) > 1:
|
||||
for network in networks:
|
||||
if network.name == cls.services["network"]["name"]:
|
||||
return network
|
||||
raise ValueError("No suitable network found, check network name in service object")
|
||||
|
||||
raise ValueError("No network found for zone with id %s" % cls.zone.id)
|
||||
|
||||
@classmethod
|
||||
def get_host(cls):
|
||||
hosts = Host.list(cls.api_client, zoneid=cls.zone.id)
|
||||
|
||||
if len(hosts) == 1:
|
||||
return hosts[0]
|
||||
|
||||
if len(hosts) > 1:
|
||||
for host in hosts:
|
||||
if host.name == cls.services["host"]["name"]:
|
||||
return host
|
||||
raise ValueError("No suitable host found, check host name in service object")
|
||||
|
||||
raise ValueError("No host found for zone with id %s" % cls.zone.id)
|
||||
|
|
|
|||
|
|
@ -1,269 +1,269 @@
|
|||
# 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.
|
||||
"""
|
||||
BVT tests for NCC integration with cloudstack
|
||||
"""
|
||||
#Import Local Modules
|
||||
from marvin.cloudstackTestCase import cloudstackTestCase
|
||||
from marvin.lib.common import get_domain, get_zone, get_template
|
||||
from marvin.lib import ncc
|
||||
from marvin.lib.base import (Account,
|
||||
VirtualMachine,
|
||||
PublicIPAddress,
|
||||
LoadBalancerRule,
|
||||
ServiceOffering,
|
||||
NetworkOffering,
|
||||
Network,
|
||||
NATRule,
|
||||
PhysicalNetwork,
|
||||
NetworkServiceProvider,
|
||||
RegisteredServicePackage)
|
||||
from marvin.lib.utils import cleanup_resources
|
||||
from nose.plugins.attrib import attr
|
||||
import logging
|
||||
|
||||
|
||||
class TestNccIntegrationDedicated(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.testClient = super(TestNccIntegrationDedicated, cls).getClsTestClient()
|
||||
cls.api_client = cls.testClient.getApiClient()
|
||||
cls.services = cls.testClient.getParsedTestDataConfig()
|
||||
cls._cleanup = []
|
||||
|
||||
cls.logger = logging.getLogger('TestNccIntegrationDedicated')
|
||||
cls.stream_handler = logging.StreamHandler()
|
||||
cls.logger.setLevel(logging.DEBUG)
|
||||
cls.logger.addHandler(cls.stream_handler)
|
||||
|
||||
# Get Zone, Domain and templates
|
||||
cls.domain = get_domain(cls.api_client)
|
||||
cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
|
||||
cls.services['mode'] = cls.zone.networktype
|
||||
cls.template = get_template(
|
||||
cls.api_client,
|
||||
cls.zone.id,
|
||||
cls.services["ostype"] )
|
||||
ncc_ip = cls.services["NCC"]["NCCIP"]
|
||||
ns_ip = cls.services["NSDedicated"]["NSIP"]
|
||||
cls.debug("NS IP - Dedicated: %s" % ns_ip)
|
||||
|
||||
mgmt_srv_ip = cls.config.__dict__["mgtSvr"][0].__dict__["mgtSvrIp"]
|
||||
#ncc_ip = "10.102.195.215"
|
||||
#ns_ip = "10.102.195.210"
|
||||
cls.ns = ncc.NCC(ncc_ip, ns_ip, mgmt_srv_ip, logger=cls.logger)
|
||||
cls.ns.registerCCP(cls.api_client)
|
||||
cls.ns.registerNS()
|
||||
cls.ns.assignNStoCSZone()
|
||||
spname = cls.services["servicepackage_dedicated"]["name"]
|
||||
|
||||
# Create Service package and get device group id, tenant group id and service package id
|
||||
# These would be needed later for clean up
|
||||
|
||||
(cls.dv_group_id, cls.tnt_group_id, cls.srv_pkg_id) = cls.ns.createServicePackages(
|
||||
spname,
|
||||
"NetScalerVPX",
|
||||
ns_ip,
|
||||
isolation_policy="dedicated")
|
||||
cls.debug("Created service package in NCC")
|
||||
cls.debug("dv_group, tnt_group, srv_pkg_id: %s %s %s" %(cls.dv_group_id,cls.tnt_group_id, cls.srv_pkg_id))
|
||||
|
||||
srv_pkg_list = RegisteredServicePackage.list(cls.api_client)
|
||||
# Choose the one created
|
||||
cls.srv_pkg_uuid = None
|
||||
for sp in srv_pkg_list:
|
||||
if sp.name == spname:
|
||||
cls.srv_pkg_uuid = sp.id
|
||||
#srv_pkg_id = srv_pkg_list[0].id
|
||||
|
||||
cls.account = Account.create(
|
||||
cls.api_client,
|
||||
cls.services["account"]
|
||||
)
|
||||
cls._cleanup.append(cls.account)
|
||||
|
||||
try:
|
||||
cls.services["nw_off_ncc_DedicatedSP"]["servicepackageuuid"] = cls.srv_pkg_uuid
|
||||
cls.services["nw_off_ncc_DedicatedSP"]["servicepackagedescription"] = "A NetScalerVPX is dedicated per network."
|
||||
cls.network_offering = NetworkOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["nw_off_ncc_DedicatedSP"])
|
||||
except Exception as e:
|
||||
raise Exception ("Unable to create network offering with Service package % s due to exception % s"
|
||||
% (cls.srv_pkg_uuid, e))
|
||||
|
||||
# Network offering should be removed so that service package may be deleted later
|
||||
cls._cleanup.append(cls.network_offering)
|
||||
|
||||
cls.network_offering.update(cls.api_client, state = "Enabled")
|
||||
cls.service_offering = ServiceOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["service_offering"]
|
||||
)
|
||||
cls.services["small"]["template"] = cls.template.id
|
||||
|
||||
# Enable Netscaler Service Provider
|
||||
|
||||
cls.phy_nws = PhysicalNetwork.list(cls.api_client,zoneid=cls.zone.id)
|
||||
if isinstance(cls.phy_nws, list):
|
||||
physical_network = cls.phy_nws[0]
|
||||
|
||||
try:
|
||||
cls.ns_service_provider = NetworkServiceProvider.list(cls.api_client,name='Netscaler')
|
||||
if isinstance(cls.ns_service_provider, list):
|
||||
ns_provider = cls.ns_service_provider[0]
|
||||
except:
|
||||
raise Exception ("Netscaler service provider not found!!")
|
||||
|
||||
try:
|
||||
if ns_provider.state != "Enabled":
|
||||
NetworkServiceProvider.update(cls.api_client, id=ns_provider.id, physicalnetworkid=physical_network.id, state="Enabled")
|
||||
except:
|
||||
raise Exception ("Enabling Netscaler Service provider failed. Unable to proceed")
|
||||
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
# Cleanup resources used
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
cls.ns.cleanup_ncc(cls.dv_group_id, cls.srv_pkg_uuid, cls.srv_pkg_id, cls.tnt_group_id)
|
||||
return
|
||||
|
||||
def setUp(self):
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
return
|
||||
|
||||
|
||||
@attr(tags=["ncc"], required_hardware="true")
|
||||
def test_01_dedicated_first_network(self):
|
||||
# Create network
|
||||
self.debug("Creating network with network offering: %s" % self.network_offering.id)
|
||||
self.network = Network.create(
|
||||
self.apiclient,
|
||||
self.services["network"],
|
||||
accountid=self.account.name,
|
||||
domainid=self.account.domainid,
|
||||
networkofferingid=self.network_offering.id,
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
self.debug("Created network: %s" % self.network.id)
|
||||
|
||||
self.debug("Trying VM deploy with network created on account: %s" % self.account.name)
|
||||
|
||||
self.virtual_machine = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["small"],
|
||||
accountid=self.account.name,
|
||||
domainid=self.account.domainid,
|
||||
zoneid=self.zone.id,
|
||||
networkids=self.network.id,
|
||||
serviceofferingid=self.service_offering.id
|
||||
)
|
||||
self.debug("Deployed VM in network: %s" % self.network.id)
|
||||
list_vm_response = VirtualMachine.list(
|
||||
self.apiclient,
|
||||
id=self.virtual_machine.id
|
||||
)
|
||||
self.debug(
|
||||
"Verify listVirtualMachines response for virtual machine: %s"
|
||||
% self.virtual_machine.id
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(list_vm_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list")
|
||||
vm_response = list_vm_response[0]
|
||||
|
||||
self.assertEqual(
|
||||
vm_response.state,
|
||||
"Running",
|
||||
"VM state should be running after deployment"
|
||||
)
|
||||
|
||||
self.debug("Aquiring public IP for network: %s" % self.network.id)
|
||||
|
||||
ip_with_lb_rule = PublicIPAddress.create(
|
||||
self.apiclient,
|
||||
accountid=self.account.name,
|
||||
zoneid=self.zone.id,
|
||||
domainid=self.account.domainid,
|
||||
networkid=self.network.id)
|
||||
|
||||
self.debug(
|
||||
"Creating LB rule for IP address: %s with round robin algo" %
|
||||
ip_with_lb_rule.ipaddress.ipaddress)
|
||||
|
||||
self.services["lbrule"]["alg"] = 'roundrobin'
|
||||
lb_rule = LoadBalancerRule.create(
|
||||
self.apiclient,
|
||||
self.services["lbrule"],
|
||||
ipaddressid=ip_with_lb_rule.ipaddress.id,
|
||||
accountid=self.account.name,
|
||||
networkid=self.network.id
|
||||
)
|
||||
|
||||
lb_rules = LoadBalancerRule.list(
|
||||
self.apiclient,
|
||||
id=lb_rule.id,
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(lb_rules, list),
|
||||
True,
|
||||
"List LB rules should return a newly created LB rule"
|
||||
)
|
||||
self.debug("Adding %s to the LB rule %s" % (
|
||||
self.virtual_machine.name,
|
||||
lb_rule.name
|
||||
))
|
||||
lb_rule.assign(self.apiclient, [self.virtual_machine])
|
||||
|
||||
@attr(tags=["ncc"], required_hardware="true")
|
||||
def test_02_dedicated_another_network(self):
|
||||
# Create network
|
||||
self.network = Network.create(
|
||||
self.apiclient,
|
||||
self.services["network"],
|
||||
accountid=self.account.name,
|
||||
domainid=self.account.domainid,
|
||||
networkofferingid=self.network_offering.id,
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
self.debug("Created network: %s" % self.network.id)
|
||||
|
||||
self.debug("Trying VM deploy with network created on account: %s" % self.account.name)
|
||||
|
||||
with self.assertRaises(Exception):
|
||||
self.virtual_machine = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["small"],
|
||||
accountid=self.account.name,
|
||||
domainid=self.account.domainid,
|
||||
networkids=self.network.id,
|
||||
zoneid=self.zone.id,
|
||||
serviceofferingid=self.service_offering.id
|
||||
)
|
||||
return
|
||||
# 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.
|
||||
"""
|
||||
BVT tests for NCC integration with cloudstack
|
||||
"""
|
||||
#Import Local Modules
|
||||
from marvin.cloudstackTestCase import cloudstackTestCase
|
||||
from marvin.lib.common import get_domain, get_zone, get_template
|
||||
from marvin.lib import ncc
|
||||
from marvin.lib.base import (Account,
|
||||
VirtualMachine,
|
||||
PublicIPAddress,
|
||||
LoadBalancerRule,
|
||||
ServiceOffering,
|
||||
NetworkOffering,
|
||||
Network,
|
||||
NATRule,
|
||||
PhysicalNetwork,
|
||||
NetworkServiceProvider,
|
||||
RegisteredServicePackage)
|
||||
from marvin.lib.utils import cleanup_resources
|
||||
from nose.plugins.attrib import attr
|
||||
import logging
|
||||
|
||||
|
||||
class TestNccIntegrationDedicated(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.testClient = super(TestNccIntegrationDedicated, cls).getClsTestClient()
|
||||
cls.api_client = cls.testClient.getApiClient()
|
||||
cls.services = cls.testClient.getParsedTestDataConfig()
|
||||
cls._cleanup = []
|
||||
|
||||
cls.logger = logging.getLogger('TestNccIntegrationDedicated')
|
||||
cls.stream_handler = logging.StreamHandler()
|
||||
cls.logger.setLevel(logging.DEBUG)
|
||||
cls.logger.addHandler(cls.stream_handler)
|
||||
|
||||
# Get Zone, Domain and templates
|
||||
cls.domain = get_domain(cls.api_client)
|
||||
cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
|
||||
cls.services['mode'] = cls.zone.networktype
|
||||
cls.template = get_template(
|
||||
cls.api_client,
|
||||
cls.zone.id,
|
||||
cls.services["ostype"] )
|
||||
ncc_ip = cls.services["NCC"]["NCCIP"]
|
||||
ns_ip = cls.services["NSDedicated"]["NSIP"]
|
||||
cls.debug("NS IP - Dedicated: %s" % ns_ip)
|
||||
|
||||
mgmt_srv_ip = cls.config.__dict__["mgtSvr"][0].__dict__["mgtSvrIp"]
|
||||
#ncc_ip = "10.102.195.215"
|
||||
#ns_ip = "10.102.195.210"
|
||||
cls.ns = ncc.NCC(ncc_ip, ns_ip, mgmt_srv_ip, logger=cls.logger)
|
||||
cls.ns.registerCCP(cls.api_client)
|
||||
cls.ns.registerNS()
|
||||
cls.ns.assignNStoCSZone()
|
||||
spname = cls.services["servicepackage_dedicated"]["name"]
|
||||
|
||||
# Create Service package and get device group id, tenant group id and service package id
|
||||
# These would be needed later for clean up
|
||||
|
||||
(cls.dv_group_id, cls.tnt_group_id, cls.srv_pkg_id) = cls.ns.createServicePackages(
|
||||
spname,
|
||||
"NetScalerVPX",
|
||||
ns_ip,
|
||||
isolation_policy="dedicated")
|
||||
cls.debug("Created service package in NCC")
|
||||
cls.debug("dv_group, tnt_group, srv_pkg_id: %s %s %s" %(cls.dv_group_id,cls.tnt_group_id, cls.srv_pkg_id))
|
||||
|
||||
srv_pkg_list = RegisteredServicePackage.list(cls.api_client)
|
||||
# Choose the one created
|
||||
cls.srv_pkg_uuid = None
|
||||
for sp in srv_pkg_list:
|
||||
if sp.name == spname:
|
||||
cls.srv_pkg_uuid = sp.id
|
||||
#srv_pkg_id = srv_pkg_list[0].id
|
||||
|
||||
cls.account = Account.create(
|
||||
cls.api_client,
|
||||
cls.services["account"]
|
||||
)
|
||||
cls._cleanup.append(cls.account)
|
||||
|
||||
try:
|
||||
cls.services["nw_off_ncc_DedicatedSP"]["servicepackageuuid"] = cls.srv_pkg_uuid
|
||||
cls.services["nw_off_ncc_DedicatedSP"]["servicepackagedescription"] = "A NetScalerVPX is dedicated per network."
|
||||
cls.network_offering = NetworkOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["nw_off_ncc_DedicatedSP"])
|
||||
except Exception as e:
|
||||
raise Exception ("Unable to create network offering with Service package % s due to exception % s"
|
||||
% (cls.srv_pkg_uuid, e))
|
||||
|
||||
# Network offering should be removed so that service package may be deleted later
|
||||
cls._cleanup.append(cls.network_offering)
|
||||
|
||||
cls.network_offering.update(cls.api_client, state = "Enabled")
|
||||
cls.service_offering = ServiceOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["service_offering"]
|
||||
)
|
||||
cls.services["small"]["template"] = cls.template.id
|
||||
|
||||
# Enable Netscaler Service Provider
|
||||
|
||||
cls.phy_nws = PhysicalNetwork.list(cls.api_client,zoneid=cls.zone.id)
|
||||
if isinstance(cls.phy_nws, list):
|
||||
physical_network = cls.phy_nws[0]
|
||||
|
||||
try:
|
||||
cls.ns_service_provider = NetworkServiceProvider.list(cls.api_client,name='Netscaler')
|
||||
if isinstance(cls.ns_service_provider, list):
|
||||
ns_provider = cls.ns_service_provider[0]
|
||||
except:
|
||||
raise Exception ("Netscaler service provider not found!!")
|
||||
|
||||
try:
|
||||
if ns_provider.state != "Enabled":
|
||||
NetworkServiceProvider.update(cls.api_client, id=ns_provider.id, physicalnetworkid=physical_network.id, state="Enabled")
|
||||
except:
|
||||
raise Exception ("Enabling Netscaler Service provider failed. Unable to proceed")
|
||||
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
# Cleanup resources used
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
cls.ns.cleanup_ncc(cls.dv_group_id, cls.srv_pkg_uuid, cls.srv_pkg_id, cls.tnt_group_id)
|
||||
return
|
||||
|
||||
def setUp(self):
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
return
|
||||
|
||||
|
||||
@attr(tags=["ncc"], required_hardware="true")
|
||||
def test_01_dedicated_first_network(self):
|
||||
# Create network
|
||||
self.debug("Creating network with network offering: %s" % self.network_offering.id)
|
||||
self.network = Network.create(
|
||||
self.apiclient,
|
||||
self.services["network"],
|
||||
accountid=self.account.name,
|
||||
domainid=self.account.domainid,
|
||||
networkofferingid=self.network_offering.id,
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
self.debug("Created network: %s" % self.network.id)
|
||||
|
||||
self.debug("Trying VM deploy with network created on account: %s" % self.account.name)
|
||||
|
||||
self.virtual_machine = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["small"],
|
||||
accountid=self.account.name,
|
||||
domainid=self.account.domainid,
|
||||
zoneid=self.zone.id,
|
||||
networkids=self.network.id,
|
||||
serviceofferingid=self.service_offering.id
|
||||
)
|
||||
self.debug("Deployed VM in network: %s" % self.network.id)
|
||||
list_vm_response = VirtualMachine.list(
|
||||
self.apiclient,
|
||||
id=self.virtual_machine.id
|
||||
)
|
||||
self.debug(
|
||||
"Verify listVirtualMachines response for virtual machine: %s"
|
||||
% self.virtual_machine.id
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(list_vm_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list")
|
||||
vm_response = list_vm_response[0]
|
||||
|
||||
self.assertEqual(
|
||||
vm_response.state,
|
||||
"Running",
|
||||
"VM state should be running after deployment"
|
||||
)
|
||||
|
||||
self.debug("Aquiring public IP for network: %s" % self.network.id)
|
||||
|
||||
ip_with_lb_rule = PublicIPAddress.create(
|
||||
self.apiclient,
|
||||
accountid=self.account.name,
|
||||
zoneid=self.zone.id,
|
||||
domainid=self.account.domainid,
|
||||
networkid=self.network.id)
|
||||
|
||||
self.debug(
|
||||
"Creating LB rule for IP address: %s with round robin algo" %
|
||||
ip_with_lb_rule.ipaddress.ipaddress)
|
||||
|
||||
self.services["lbrule"]["alg"] = 'roundrobin'
|
||||
lb_rule = LoadBalancerRule.create(
|
||||
self.apiclient,
|
||||
self.services["lbrule"],
|
||||
ipaddressid=ip_with_lb_rule.ipaddress.id,
|
||||
accountid=self.account.name,
|
||||
networkid=self.network.id
|
||||
)
|
||||
|
||||
lb_rules = LoadBalancerRule.list(
|
||||
self.apiclient,
|
||||
id=lb_rule.id,
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(lb_rules, list),
|
||||
True,
|
||||
"List LB rules should return a newly created LB rule"
|
||||
)
|
||||
self.debug("Adding %s to the LB rule %s" % (
|
||||
self.virtual_machine.name,
|
||||
lb_rule.name
|
||||
))
|
||||
lb_rule.assign(self.apiclient, [self.virtual_machine])
|
||||
|
||||
@attr(tags=["ncc"], required_hardware="true")
|
||||
def test_02_dedicated_another_network(self):
|
||||
# Create network
|
||||
self.network = Network.create(
|
||||
self.apiclient,
|
||||
self.services["network"],
|
||||
accountid=self.account.name,
|
||||
domainid=self.account.domainid,
|
||||
networkofferingid=self.network_offering.id,
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
self.debug("Created network: %s" % self.network.id)
|
||||
|
||||
self.debug("Trying VM deploy with network created on account: %s" % self.account.name)
|
||||
|
||||
with self.assertRaises(Exception):
|
||||
self.virtual_machine = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["small"],
|
||||
accountid=self.account.name,
|
||||
domainid=self.account.domainid,
|
||||
networkids=self.network.id,
|
||||
zoneid=self.zone.id,
|
||||
serviceofferingid=self.service_offering.id
|
||||
)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -1,323 +1,323 @@
|
|||
# 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.
|
||||
"""
|
||||
BVT tests for NCC integration with cloudstack
|
||||
"""
|
||||
#Import Local Modules
|
||||
from marvin.cloudstackTestCase import cloudstackTestCase
|
||||
from marvin.lib.common import get_domain, get_zone, get_template
|
||||
from marvin.lib import ncc
|
||||
from marvin.lib.base import (Account,
|
||||
VirtualMachine,
|
||||
PublicIPAddress,
|
||||
LoadBalancerRule,
|
||||
ServiceOffering,
|
||||
NetworkOffering,
|
||||
Network,
|
||||
NATRule,
|
||||
PhysicalNetwork,
|
||||
NetworkServiceProvider,
|
||||
RegisteredServicePackage)
|
||||
from marvin.lib.utils import cleanup_resources
|
||||
from nose.plugins.attrib import attr
|
||||
import logging
|
||||
|
||||
|
||||
class TestNccIntegrationShared(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.testClient = super(TestNccIntegrationShared, cls).getClsTestClient()
|
||||
cls.api_client = cls.testClient.getApiClient()
|
||||
cls.services = cls.testClient.getParsedTestDataConfig()
|
||||
cls._cleanup = []
|
||||
|
||||
cls.logger = logging.getLogger('TestNccIntegrationShared')
|
||||
cls.stream_handler = logging.StreamHandler()
|
||||
cls.logger.setLevel(logging.DEBUG)
|
||||
cls.logger.addHandler(cls.stream_handler)
|
||||
|
||||
# Get Zone, Domain and templates
|
||||
cls.domain = get_domain(cls.api_client)
|
||||
cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
|
||||
cls.services['mode'] = cls.zone.networktype
|
||||
cls.template = get_template(
|
||||
cls.api_client,
|
||||
cls.zone.id,
|
||||
cls.services["ostype"] )
|
||||
ncc_ip=cls.services["NCC"]["NCCIP"]
|
||||
ns_ip=cls.services["NSShared"]["NSIP"]
|
||||
cls.debug("NS IP: Shared: %s" % ns_ip)
|
||||
|
||||
mgmt_srv_ip = cls.config.__dict__["mgtSvr"][0].__dict__["mgtSvrIp"]
|
||||
#ncc_ip = "10.102.195.215"
|
||||
#ns_ip = "10.102.195.210"
|
||||
cls.ns = ncc.NCC(ncc_ip, ns_ip, mgmt_srv_ip, logger=cls.logger)
|
||||
cls.ns.registerCCP(cls.api_client)
|
||||
cls.ns.registerNS()
|
||||
cls.ns.assignNStoCSZone()
|
||||
spname = cls.services["servicepackage_shared"]["name"]
|
||||
cls.debug("SPname (Shared): %s" % spname)
|
||||
#spname="SharedSP9"
|
||||
# Create Service package and get device group id, tenant group id and service package id
|
||||
# These would be needed later for clean up
|
||||
|
||||
(cls.dv_group_id, cls.tnt_group_id, cls.srv_pkg_id) = cls.ns.createServicePackages(
|
||||
spname,
|
||||
"NetScalerVPX",
|
||||
ns_ip)
|
||||
srv_pkg_list = RegisteredServicePackage.list(cls.api_client)
|
||||
# Choose the one created
|
||||
cls.srv_pkg_uuid = None
|
||||
for sp in srv_pkg_list:
|
||||
if sp.name == spname:
|
||||
cls.srv_pkg_uuid = sp.id
|
||||
#srv_pkg_id = srv_pkg_list[0].id
|
||||
|
||||
cls.account = Account.create(
|
||||
cls.api_client,
|
||||
cls.services["account"]
|
||||
)
|
||||
cls._cleanup.append(cls.account)
|
||||
|
||||
try:
|
||||
cls.services["nw_off_ncc_SharedSP"]["servicepackageuuid"] = cls.srv_pkg_uuid
|
||||
cls.services["nw_off_ncc_SharedSP"]["servicepackagedescription"] = "A NetScalerVPX is shared across all networks."
|
||||
cls.network_offering = NetworkOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["nw_off_ncc_SharedSP"])
|
||||
except Exception as e:
|
||||
raise Exception ("Unable to create network offering with Service package % s due to exception % s"
|
||||
% (cls.srv_pkg_uuid, e))
|
||||
|
||||
# Network offering should be removed so that service package may be deleted later
|
||||
cls._cleanup.append(cls.network_offering)
|
||||
|
||||
cls.network_offering.update(cls.api_client, state = "Enabled")
|
||||
cls.service_offering_shared = ServiceOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["service_offering"]
|
||||
)
|
||||
cls.services["small"]["template"] = cls.template.id
|
||||
|
||||
# Enable Netscaler Service Provider
|
||||
|
||||
cls.phy_nws = PhysicalNetwork.list(cls.api_client,zoneid=cls.zone.id)
|
||||
if isinstance(cls.phy_nws, list):
|
||||
physical_network = cls.phy_nws[0]
|
||||
|
||||
try:
|
||||
cls.ns_service_provider = NetworkServiceProvider.list(cls.api_client,name='Netscaler')
|
||||
if isinstance(cls.ns_service_provider, list):
|
||||
ns_provider = cls.ns_service_provider[0]
|
||||
except:
|
||||
raise Exception ("Netscaler service provider not found!!")
|
||||
|
||||
try:
|
||||
if ns_provider.state != "Enabled":
|
||||
NetworkServiceProvider.update(cls.api_client, id=ns_provider.id, physicalnetworkid=physical_network.id, state="Enabled")
|
||||
except:
|
||||
raise Exception ("Enabling Netscaler Service provider failed. Unable to proceed")
|
||||
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
# Cleanup resources used
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
cls.ns.cleanup_ncc(cls.dv_group_id, cls.srv_pkg_uuid, cls.srv_pkg_id, cls.tnt_group_id)
|
||||
return
|
||||
|
||||
def setUp(self):
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
return
|
||||
|
||||
@attr(tags=["ncc"], required_hardware="true")
|
||||
def test_01_shared_first_network(self):
|
||||
# Create network
|
||||
self.debug("Creating network with network offering: %s" % self.network_offering.id)
|
||||
self.network = Network.create(
|
||||
self.apiclient,
|
||||
self.services["network"],
|
||||
accountid=self.account.name,
|
||||
domainid=self.account.domainid,
|
||||
networkofferingid=self.network_offering.id,
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
self.debug("Created network: %s" % self.network.id)
|
||||
|
||||
self.debug("Trying VM deploy with network created on account: %s" % self.account.name)
|
||||
|
||||
self.virtual_machine = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["small"],
|
||||
accountid=self.account.name,
|
||||
domainid=self.account.domainid,
|
||||
zoneid=self.zone.id,
|
||||
networkids=self.network.id,
|
||||
serviceofferingid=self.service_offering_shared.id)
|
||||
self.debug("Deployed VM in network: %s" % self.network.id)
|
||||
list_vm_response = VirtualMachine.list(
|
||||
self.apiclient,
|
||||
id=self.virtual_machine.id
|
||||
)
|
||||
self.debug(
|
||||
"Verify listVirtualMachines response for virtual machine: %s"
|
||||
% self.virtual_machine.id
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(list_vm_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list")
|
||||
vm_response = list_vm_response[0]
|
||||
|
||||
self.assertEqual(
|
||||
vm_response.state,
|
||||
"Running",
|
||||
"VM state should be running after deployment"
|
||||
)
|
||||
|
||||
self.debug("Acquiring public IP for network: %s" % self.network.id)
|
||||
|
||||
ip_with_lb_rule = PublicIPAddress.create(
|
||||
self.apiclient,
|
||||
accountid=self.account.name,
|
||||
zoneid=self.zone.id,
|
||||
domainid=self.account.domainid,
|
||||
networkid=self.network.id)
|
||||
|
||||
self.debug(
|
||||
"Creating LB rule for IP address: %s with round robin algo" %
|
||||
ip_with_lb_rule.ipaddress.ipaddress)
|
||||
|
||||
self.services["lbrule"]["alg"] = 'roundrobin'
|
||||
lb_rule = LoadBalancerRule.create(
|
||||
self.apiclient,
|
||||
self.services["lbrule"],
|
||||
ipaddressid=ip_with_lb_rule.ipaddress.id,
|
||||
accountid=self.account.name,
|
||||
networkid=self.network.id
|
||||
)
|
||||
|
||||
lb_rules = LoadBalancerRule.list(
|
||||
self.apiclient,
|
||||
id=lb_rule.id,
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(lb_rules, list),
|
||||
True,
|
||||
"List LB rules should return a newly created LB rule"
|
||||
)
|
||||
self.debug("Adding %s to the LB rule %s" % (
|
||||
self.virtual_machine.name,
|
||||
lb_rule.name
|
||||
))
|
||||
lb_rule.assign(self.apiclient, [self.virtual_machine])
|
||||
|
||||
@attr(tags=["ncc"], required_hardware="true")
|
||||
def test_02_shared_another_network(self):
|
||||
# Create network
|
||||
self.debug("Creating network with network offering: %s" % self.network_offering.id)
|
||||
self.network = Network.create(
|
||||
self.apiclient,
|
||||
self.services["network"],
|
||||
accountid=self.account.name,
|
||||
domainid=self.account.domainid,
|
||||
networkofferingid=self.network_offering.id,
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
self.debug("Created network: %s" % self.network.id)
|
||||
|
||||
self.debug("Trying VM deploy with network created on account: %s" % self.account.name)
|
||||
|
||||
self.virtual_machine = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["small"],
|
||||
accountid=self.account.name,
|
||||
domainid=self.account.domainid,
|
||||
networkids=self.network.id,
|
||||
zoneid=self.zone.id,
|
||||
serviceofferingid=self.service_offering_shared.id
|
||||
)
|
||||
self.debug("Deployed VM in network: %s" % self.network.id)
|
||||
list_vm_response = VirtualMachine.list(
|
||||
self.apiclient,
|
||||
id=self.virtual_machine.id
|
||||
)
|
||||
self.debug(
|
||||
"Verify listVirtualMachines response for virtual machine: %s"
|
||||
% self.virtual_machine.id
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(list_vm_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list")
|
||||
vm_response = list_vm_response[0]
|
||||
|
||||
self.assertEqual(
|
||||
vm_response.state,
|
||||
"Running",
|
||||
"VM state should be running after deployment"
|
||||
)
|
||||
|
||||
self.debug("Aquiring public IP for network: %s" % self.network.id)
|
||||
|
||||
ip_with_lb_rule = PublicIPAddress.create(
|
||||
self.apiclient,
|
||||
accountid=self.account.name,
|
||||
zoneid=self.zone.id,
|
||||
domainid=self.account.domainid,
|
||||
networkid=self.network.id)
|
||||
|
||||
self.debug(
|
||||
"Creating LB rule for IP address: %s with round robin algo" %
|
||||
ip_with_lb_rule.ipaddress.ipaddress)
|
||||
|
||||
self.services["lbrule"]["alg"] = 'roundrobin'
|
||||
lb_rule = LoadBalancerRule.create(
|
||||
self.apiclient,
|
||||
self.services["lbrule"],
|
||||
ipaddressid=ip_with_lb_rule.ipaddress.id,
|
||||
accountid=self.account.name,
|
||||
networkid=self.network.id
|
||||
)
|
||||
|
||||
lb_rules = LoadBalancerRule.list(
|
||||
self.apiclient,
|
||||
id=lb_rule.id,
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(lb_rules, list),
|
||||
True,
|
||||
"List LB rules should return a newly created LB rule"
|
||||
)
|
||||
self.debug("Adding %s to the LB rule %s" % (
|
||||
self.virtual_machine.name,
|
||||
lb_rule.name
|
||||
))
|
||||
lb_rule.assign(self.apiclient, [self.virtual_machine])
|
||||
return
|
||||
# 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.
|
||||
"""
|
||||
BVT tests for NCC integration with cloudstack
|
||||
"""
|
||||
#Import Local Modules
|
||||
from marvin.cloudstackTestCase import cloudstackTestCase
|
||||
from marvin.lib.common import get_domain, get_zone, get_template
|
||||
from marvin.lib import ncc
|
||||
from marvin.lib.base import (Account,
|
||||
VirtualMachine,
|
||||
PublicIPAddress,
|
||||
LoadBalancerRule,
|
||||
ServiceOffering,
|
||||
NetworkOffering,
|
||||
Network,
|
||||
NATRule,
|
||||
PhysicalNetwork,
|
||||
NetworkServiceProvider,
|
||||
RegisteredServicePackage)
|
||||
from marvin.lib.utils import cleanup_resources
|
||||
from nose.plugins.attrib import attr
|
||||
import logging
|
||||
|
||||
|
||||
class TestNccIntegrationShared(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.testClient = super(TestNccIntegrationShared, cls).getClsTestClient()
|
||||
cls.api_client = cls.testClient.getApiClient()
|
||||
cls.services = cls.testClient.getParsedTestDataConfig()
|
||||
cls._cleanup = []
|
||||
|
||||
cls.logger = logging.getLogger('TestNccIntegrationShared')
|
||||
cls.stream_handler = logging.StreamHandler()
|
||||
cls.logger.setLevel(logging.DEBUG)
|
||||
cls.logger.addHandler(cls.stream_handler)
|
||||
|
||||
# Get Zone, Domain and templates
|
||||
cls.domain = get_domain(cls.api_client)
|
||||
cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
|
||||
cls.services['mode'] = cls.zone.networktype
|
||||
cls.template = get_template(
|
||||
cls.api_client,
|
||||
cls.zone.id,
|
||||
cls.services["ostype"] )
|
||||
ncc_ip=cls.services["NCC"]["NCCIP"]
|
||||
ns_ip=cls.services["NSShared"]["NSIP"]
|
||||
cls.debug("NS IP: Shared: %s" % ns_ip)
|
||||
|
||||
mgmt_srv_ip = cls.config.__dict__["mgtSvr"][0].__dict__["mgtSvrIp"]
|
||||
#ncc_ip = "10.102.195.215"
|
||||
#ns_ip = "10.102.195.210"
|
||||
cls.ns = ncc.NCC(ncc_ip, ns_ip, mgmt_srv_ip, logger=cls.logger)
|
||||
cls.ns.registerCCP(cls.api_client)
|
||||
cls.ns.registerNS()
|
||||
cls.ns.assignNStoCSZone()
|
||||
spname = cls.services["servicepackage_shared"]["name"]
|
||||
cls.debug("SPname (Shared): %s" % spname)
|
||||
#spname="SharedSP9"
|
||||
# Create Service package and get device group id, tenant group id and service package id
|
||||
# These would be needed later for clean up
|
||||
|
||||
(cls.dv_group_id, cls.tnt_group_id, cls.srv_pkg_id) = cls.ns.createServicePackages(
|
||||
spname,
|
||||
"NetScalerVPX",
|
||||
ns_ip)
|
||||
srv_pkg_list = RegisteredServicePackage.list(cls.api_client)
|
||||
# Choose the one created
|
||||
cls.srv_pkg_uuid = None
|
||||
for sp in srv_pkg_list:
|
||||
if sp.name == spname:
|
||||
cls.srv_pkg_uuid = sp.id
|
||||
#srv_pkg_id = srv_pkg_list[0].id
|
||||
|
||||
cls.account = Account.create(
|
||||
cls.api_client,
|
||||
cls.services["account"]
|
||||
)
|
||||
cls._cleanup.append(cls.account)
|
||||
|
||||
try:
|
||||
cls.services["nw_off_ncc_SharedSP"]["servicepackageuuid"] = cls.srv_pkg_uuid
|
||||
cls.services["nw_off_ncc_SharedSP"]["servicepackagedescription"] = "A NetScalerVPX is shared across all networks."
|
||||
cls.network_offering = NetworkOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["nw_off_ncc_SharedSP"])
|
||||
except Exception as e:
|
||||
raise Exception ("Unable to create network offering with Service package % s due to exception % s"
|
||||
% (cls.srv_pkg_uuid, e))
|
||||
|
||||
# Network offering should be removed so that service package may be deleted later
|
||||
cls._cleanup.append(cls.network_offering)
|
||||
|
||||
cls.network_offering.update(cls.api_client, state = "Enabled")
|
||||
cls.service_offering_shared = ServiceOffering.create(
|
||||
cls.api_client,
|
||||
cls.services["service_offering"]
|
||||
)
|
||||
cls.services["small"]["template"] = cls.template.id
|
||||
|
||||
# Enable Netscaler Service Provider
|
||||
|
||||
cls.phy_nws = PhysicalNetwork.list(cls.api_client,zoneid=cls.zone.id)
|
||||
if isinstance(cls.phy_nws, list):
|
||||
physical_network = cls.phy_nws[0]
|
||||
|
||||
try:
|
||||
cls.ns_service_provider = NetworkServiceProvider.list(cls.api_client,name='Netscaler')
|
||||
if isinstance(cls.ns_service_provider, list):
|
||||
ns_provider = cls.ns_service_provider[0]
|
||||
except:
|
||||
raise Exception ("Netscaler service provider not found!!")
|
||||
|
||||
try:
|
||||
if ns_provider.state != "Enabled":
|
||||
NetworkServiceProvider.update(cls.api_client, id=ns_provider.id, physicalnetworkid=physical_network.id, state="Enabled")
|
||||
except:
|
||||
raise Exception ("Enabling Netscaler Service provider failed. Unable to proceed")
|
||||
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
# Cleanup resources used
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
cls.ns.cleanup_ncc(cls.dv_group_id, cls.srv_pkg_uuid, cls.srv_pkg_id, cls.tnt_group_id)
|
||||
return
|
||||
|
||||
def setUp(self):
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
return
|
||||
|
||||
@attr(tags=["ncc"], required_hardware="true")
|
||||
def test_01_shared_first_network(self):
|
||||
# Create network
|
||||
self.debug("Creating network with network offering: %s" % self.network_offering.id)
|
||||
self.network = Network.create(
|
||||
self.apiclient,
|
||||
self.services["network"],
|
||||
accountid=self.account.name,
|
||||
domainid=self.account.domainid,
|
||||
networkofferingid=self.network_offering.id,
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
self.debug("Created network: %s" % self.network.id)
|
||||
|
||||
self.debug("Trying VM deploy with network created on account: %s" % self.account.name)
|
||||
|
||||
self.virtual_machine = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["small"],
|
||||
accountid=self.account.name,
|
||||
domainid=self.account.domainid,
|
||||
zoneid=self.zone.id,
|
||||
networkids=self.network.id,
|
||||
serviceofferingid=self.service_offering_shared.id)
|
||||
self.debug("Deployed VM in network: %s" % self.network.id)
|
||||
list_vm_response = VirtualMachine.list(
|
||||
self.apiclient,
|
||||
id=self.virtual_machine.id
|
||||
)
|
||||
self.debug(
|
||||
"Verify listVirtualMachines response for virtual machine: %s"
|
||||
% self.virtual_machine.id
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(list_vm_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list")
|
||||
vm_response = list_vm_response[0]
|
||||
|
||||
self.assertEqual(
|
||||
vm_response.state,
|
||||
"Running",
|
||||
"VM state should be running after deployment"
|
||||
)
|
||||
|
||||
self.debug("Acquiring public IP for network: %s" % self.network.id)
|
||||
|
||||
ip_with_lb_rule = PublicIPAddress.create(
|
||||
self.apiclient,
|
||||
accountid=self.account.name,
|
||||
zoneid=self.zone.id,
|
||||
domainid=self.account.domainid,
|
||||
networkid=self.network.id)
|
||||
|
||||
self.debug(
|
||||
"Creating LB rule for IP address: %s with round robin algo" %
|
||||
ip_with_lb_rule.ipaddress.ipaddress)
|
||||
|
||||
self.services["lbrule"]["alg"] = 'roundrobin'
|
||||
lb_rule = LoadBalancerRule.create(
|
||||
self.apiclient,
|
||||
self.services["lbrule"],
|
||||
ipaddressid=ip_with_lb_rule.ipaddress.id,
|
||||
accountid=self.account.name,
|
||||
networkid=self.network.id
|
||||
)
|
||||
|
||||
lb_rules = LoadBalancerRule.list(
|
||||
self.apiclient,
|
||||
id=lb_rule.id,
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(lb_rules, list),
|
||||
True,
|
||||
"List LB rules should return a newly created LB rule"
|
||||
)
|
||||
self.debug("Adding %s to the LB rule %s" % (
|
||||
self.virtual_machine.name,
|
||||
lb_rule.name
|
||||
))
|
||||
lb_rule.assign(self.apiclient, [self.virtual_machine])
|
||||
|
||||
@attr(tags=["ncc"], required_hardware="true")
|
||||
def test_02_shared_another_network(self):
|
||||
# Create network
|
||||
self.debug("Creating network with network offering: %s" % self.network_offering.id)
|
||||
self.network = Network.create(
|
||||
self.apiclient,
|
||||
self.services["network"],
|
||||
accountid=self.account.name,
|
||||
domainid=self.account.domainid,
|
||||
networkofferingid=self.network_offering.id,
|
||||
zoneid=self.zone.id
|
||||
)
|
||||
self.debug("Created network: %s" % self.network.id)
|
||||
|
||||
self.debug("Trying VM deploy with network created on account: %s" % self.account.name)
|
||||
|
||||
self.virtual_machine = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["small"],
|
||||
accountid=self.account.name,
|
||||
domainid=self.account.domainid,
|
||||
networkids=self.network.id,
|
||||
zoneid=self.zone.id,
|
||||
serviceofferingid=self.service_offering_shared.id
|
||||
)
|
||||
self.debug("Deployed VM in network: %s" % self.network.id)
|
||||
list_vm_response = VirtualMachine.list(
|
||||
self.apiclient,
|
||||
id=self.virtual_machine.id
|
||||
)
|
||||
self.debug(
|
||||
"Verify listVirtualMachines response for virtual machine: %s"
|
||||
% self.virtual_machine.id
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(list_vm_response, list),
|
||||
True,
|
||||
"Check list response returns a valid list")
|
||||
vm_response = list_vm_response[0]
|
||||
|
||||
self.assertEqual(
|
||||
vm_response.state,
|
||||
"Running",
|
||||
"VM state should be running after deployment"
|
||||
)
|
||||
|
||||
self.debug("Aquiring public IP for network: %s" % self.network.id)
|
||||
|
||||
ip_with_lb_rule = PublicIPAddress.create(
|
||||
self.apiclient,
|
||||
accountid=self.account.name,
|
||||
zoneid=self.zone.id,
|
||||
domainid=self.account.domainid,
|
||||
networkid=self.network.id)
|
||||
|
||||
self.debug(
|
||||
"Creating LB rule for IP address: %s with round robin algo" %
|
||||
ip_with_lb_rule.ipaddress.ipaddress)
|
||||
|
||||
self.services["lbrule"]["alg"] = 'roundrobin'
|
||||
lb_rule = LoadBalancerRule.create(
|
||||
self.apiclient,
|
||||
self.services["lbrule"],
|
||||
ipaddressid=ip_with_lb_rule.ipaddress.id,
|
||||
accountid=self.account.name,
|
||||
networkid=self.network.id
|
||||
)
|
||||
|
||||
lb_rules = LoadBalancerRule.list(
|
||||
self.apiclient,
|
||||
id=lb_rule.id,
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(lb_rules, list),
|
||||
True,
|
||||
"List LB rules should return a newly created LB rule"
|
||||
)
|
||||
self.debug("Adding %s to the LB rule %s" % (
|
||||
self.virtual_machine.name,
|
||||
lb_rule.name
|
||||
))
|
||||
lb_rule.assign(self.apiclient, [self.virtual_machine])
|
||||
return
|
||||
|
|
|
|||
Loading…
Reference in New Issue