Add `pre-commit` workflow with 3 Git hooks (#6273)

Co-authored-by: dahn <daan@onecht.net>
This commit is contained in:
John Bampton 2023-01-11 21:25:31 +10:00 committed by GitHub
parent a85973a0ca
commit 00426ede46
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 2509 additions and 2449 deletions

View File

@ -15,7 +15,7 @@
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
name: Lint Code Base name: Lint
on: [pull_request] on: [pull_request]
@ -31,7 +31,7 @@ jobs:
permissions: permissions:
contents: read # for actions/checkout to fetch code contents: read # for actions/checkout to fetch code
statuses: write # for github/super-linter to mark status of each linter run statuses: write # for github/super-linter to mark status of each linter run
name: SuperLinter Check name: Super-Linter Check
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout Code - name: Checkout Code
@ -39,10 +39,28 @@ jobs:
with: with:
# Full git history is needed to get a proper list of changed files within `super-linter` # Full git history is needed to get a proper list of changed files within `super-linter`
fetch-depth: 0 fetch-depth: 0
- name: SuperLinter - name: Super-Linter
uses: github/super-linter@v4 uses: github/super-linter@v4
env: env:
DEFAULT_BRANCH: main DEFAULT_BRANCH: main
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VALIDATE_ALL_CODEBASE: false VALIDATE_ALL_CODEBASE: false
VALIDATE_PYTHON_FLAKE8: true 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

42
.pre-commit-config.yaml Normal file
View File

@ -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

View File

@ -1,61 +1,61 @@
// Licensed to the Apache Software Foundation (ASF) under one // Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file // or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information // distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file // regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the // to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance // "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at // with the License. You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, // Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an // software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the // KIND, either express or implied. See the License for the
// specific language governing permissions and limitations // specific language governing permissions and limitations
// under the License. // under the License.
package com.cloud.host; package com.cloud.host;
import com.cloud.service.ServiceOfferingVO; import com.cloud.service.ServiceOfferingVO;
import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine;
import java.util.Arrays; import java.util.Arrays;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import org.junit.Test; import org.junit.Test;
import org.junit.Before; import org.junit.Before;
public class HostVOTest { public class HostVOTest {
HostVO host; HostVO host;
ServiceOfferingVO offering; ServiceOfferingVO offering;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
host = new HostVO(); host = new HostVO();
offering = new ServiceOfferingVO("TestSO", 0, 0, 0, 0, 0, offering = new ServiceOfferingVO("TestSO", 0, 0, 0, 0, 0,
false, "TestSO", false,VirtualMachine.Type.User,false); false, "TestSO", false,VirtualMachine.Type.User,false);
} }
@Test @Test
public void testNoSO() { public void testNoSO() {
assertFalse(host.checkHostServiceOfferingTags(null)); assertFalse(host.checkHostServiceOfferingTags(null));
} }
@Test @Test
public void testNoTag() { public void testNoTag() {
assertTrue(host.checkHostServiceOfferingTags(offering)); assertTrue(host.checkHostServiceOfferingTags(offering));
} }
@Test @Test
public void testRightTag() { public void testRightTag() {
host.setHostTags(Arrays.asList("tag1","tag2")); host.setHostTags(Arrays.asList("tag1","tag2"));
offering.setHostTag("tag2,tag1"); offering.setHostTag("tag2,tag1");
assertTrue(host.checkHostServiceOfferingTags(offering)); assertTrue(host.checkHostServiceOfferingTags(offering));
} }
@Test @Test
public void testWrongTag() { public void testWrongTag() {
host.setHostTags(Arrays.asList("tag1","tag2")); host.setHostTags(Arrays.asList("tag1","tag2"));
offering.setHostTag("tag2,tag4"); offering.setHostTag("tag2,tag4");
assertFalse(host.checkHostServiceOfferingTags(offering)); assertFalse(host.checkHostServiceOfferingTags(offering));
} }
} }

View File

@ -1,26 +1,26 @@
// Licensed to the Apache Software Foundation (ASF) under one // Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file // or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information // distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file // regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the // to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance // "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at // with the License. You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, // Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an // software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the // KIND, either express or implied. See the License for the
// specific language governing permissions and limitations // specific language governing permissions and limitations
// under the License. // under the License.
// //
package com.cloud.baremetal.database; package com.cloud.baremetal.database;
import com.cloud.utils.db.GenericDao; import com.cloud.utils.db.GenericDao;
/** /**
* Created by frank on 5/8/14. * Created by frank on 5/8/14.
*/ */
public interface BaremetalRctDao extends GenericDao<BaremetalRctVO, Long> { public interface BaremetalRctDao extends GenericDao<BaremetalRctVO, Long> {
} }

View File

@ -1,26 +1,26 @@
// Licensed to the Apache Software Foundation (ASF) under one // Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file // or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information // distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file // regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the // to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance // "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at // with the License. You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, // Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an // software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the // KIND, either express or implied. See the License for the
// specific language governing permissions and limitations // specific language governing permissions and limitations
// under the License. // under the License.
// //
package com.cloud.baremetal.database; package com.cloud.baremetal.database;
import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericDaoBase;
/** /**
* Created by frank on 5/8/14. * Created by frank on 5/8/14.
*/ */
public class BaremetalRctDaoImpl extends GenericDaoBase<BaremetalRctVO, Long> implements BaremetalRctDao { public class BaremetalRctDaoImpl extends GenericDaoBase<BaremetalRctVO, Long> implements BaremetalRctDao {
} }

View File

@ -1,82 +1,82 @@
// Licensed to the Apache Software Foundation (ASF) under one // Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file // or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information // distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file // regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the // to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance // "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at // with the License. You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, // Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an // software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the // KIND, either express or implied. See the License for the
// specific language governing permissions and limitations // specific language governing permissions and limitations
// under the License. // under the License.
// //
package com.cloud.baremetal.database; package com.cloud.baremetal.database;
import org.apache.cloudstack.api.Identity; import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity; import org.apache.cloudstack.api.InternalIdentity;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.GeneratedValue; import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType; import javax.persistence.GenerationType;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.Table; import javax.persistence.Table;
import java.util.UUID; import java.util.UUID;
/** /**
* Created by frank on 5/8/14. * Created by frank on 5/8/14.
*/ */
@Entity @Entity
@Table(name = "baremetal_rct") @Table(name = "baremetal_rct")
public class BaremetalRctVO implements InternalIdentity, Identity { public class BaremetalRctVO implements InternalIdentity, Identity {
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id") @Column(name = "id")
private long id; private long id;
@Column(name = "uuid") @Column(name = "uuid")
private String uuid = UUID.randomUUID().toString(); private String uuid = UUID.randomUUID().toString();
@Column(name = "url") @Column(name = "url")
private String url; private String url;
@Column(name = "rct") @Column(name = "rct")
private String rct; private String rct;
public long getId() { public long getId() {
return id; return id;
} }
public void setId(long id) { public void setId(long id) {
this.id = id; this.id = id;
} }
public String getUuid() { public String getUuid() {
return uuid; return uuid;
} }
public void setUuid(String uuid) { public void setUuid(String uuid) {
this.uuid = uuid; this.uuid = uuid;
} }
public String getUrl() { public String getUrl() {
return url; return url;
} }
public void setUrl(String url) { public void setUrl(String url) {
this.url = url; this.url = url;
} }
public String getRct() { public String getRct() {
return rct; return rct;
} }
public void setRct(String rct) { public void setRct(String rct) {
this.rct = rct; this.rct = rct;
} }
} }

View File

@ -1,125 +1,125 @@
// Licensed to the Apache Software Foundation (ASF) under one // Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file // or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information // distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file // regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the // to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance // "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at // with the License. You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, // Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an // software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the // KIND, either express or implied. See the License for the
// specific language governing permissions and limitations // specific language governing permissions and limitations
// under the License. // under the License.
// //
package com.cloud.baremetal.manager; package com.cloud.baremetal.manager;
import java.util.List; import java.util.List;
/** /**
* Created by frank on 5/8/14. * Created by frank on 5/8/14.
*/ */
public class BaremetalRct { public class BaremetalRct {
public static class SwitchEntry { public static class SwitchEntry {
private String ip; private String ip;
private String username; private String username;
private String password; private String password;
private String type; private String type;
public String getIp() { public String getIp() {
return ip; return ip;
} }
public void setIp(String ip) { public void setIp(String ip) {
this.ip = ip; this.ip = ip;
} }
public String getUsername() { public String getUsername() {
return username; return username;
} }
public void setUsername(String username) { public void setUsername(String username) {
this.username = username; this.username = username;
} }
public String getPassword() { public String getPassword() {
return password; return password;
} }
public void setPassword(String password) { public void setPassword(String password) {
this.password = password; this.password = password;
} }
public String getType() { public String getType() {
return type; return type;
} }
public void setType(String type) { public void setType(String type) {
this.type = type; this.type = type;
} }
} }
public static class HostEntry { public static class HostEntry {
private String uuid; private String uuid;
private String mac; private String mac;
private String port; private String port;
public String getUuid() { public String getUuid() {
return uuid; return uuid;
} }
public void setUuid(String uuid) { public void setUuid(String uuid) {
this.uuid = uuid; this.uuid = uuid;
} }
public String getMac() { public String getMac() {
return mac; return mac;
} }
public void setMac(String mac) { public void setMac(String mac) {
this.mac = mac; this.mac = mac;
} }
public String getPort() { public String getPort() {
return port; return port;
} }
public void setPort(String port) { public void setPort(String port) {
this.port = port; this.port = port;
} }
} }
public static class Rack { public static class Rack {
private SwitchEntry l2Switch; private SwitchEntry l2Switch;
private List<HostEntry> hosts; private List<HostEntry> hosts;
public SwitchEntry getL2Switch() { public SwitchEntry getL2Switch() {
return l2Switch; return l2Switch;
} }
public void setL2Switch(SwitchEntry l2Switch) { public void setL2Switch(SwitchEntry l2Switch) {
this.l2Switch = l2Switch; this.l2Switch = l2Switch;
} }
public List<HostEntry> getHosts() { public List<HostEntry> getHosts() {
return hosts; return hosts;
} }
public void setHosts(List<HostEntry> hosts) { public void setHosts(List<HostEntry> hosts) {
this.hosts = hosts; this.hosts = hosts;
} }
} }
private List<Rack> racks; private List<Rack> racks;
public List<Rack> getRacks() { public List<Rack> getRacks() {
return racks; return racks;
} }
public void setRacks(List<Rack> racks) { public void setRacks(List<Rack> racks) {
this.racks = racks; this.racks = racks;
} }
} }

View File

@ -1,43 +1,43 @@
// Licensed to the Apache Software Foundation (ASF) under one // Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file // or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information // distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file // regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the // to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance // "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at // with the License. You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, // Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an // software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the // KIND, either express or implied. See the License for the
// specific language governing permissions and limitations // specific language governing permissions and limitations
// under the License. // under the License.
// //
package com.cloud.baremetal.manager; package com.cloud.baremetal.manager;
import com.cloud.baremetal.networkservice.BaremetalRctResponse; import com.cloud.baremetal.networkservice.BaremetalRctResponse;
import com.cloud.baremetal.networkservice.BaremetalSwitchBackend; import com.cloud.baremetal.networkservice.BaremetalSwitchBackend;
import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeployDestination;
import com.cloud.network.Network; import com.cloud.network.Network;
import com.cloud.utils.component.Manager; import com.cloud.utils.component.Manager;
import com.cloud.utils.component.PluggableService; import com.cloud.utils.component.PluggableService;
import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.VirtualMachineProfile;
import org.apache.cloudstack.api.AddBaremetalRctCmd; import org.apache.cloudstack.api.AddBaremetalRctCmd;
import org.apache.cloudstack.api.DeleteBaremetalRctCmd; import org.apache.cloudstack.api.DeleteBaremetalRctCmd;
public interface BaremetalVlanManager extends Manager, PluggableService { public interface BaremetalVlanManager extends Manager, PluggableService {
BaremetalRctResponse addRct(AddBaremetalRctCmd cmd); BaremetalRctResponse addRct(AddBaremetalRctCmd cmd);
void prepareVlan(Network nw, DeployDestination destHost); void prepareVlan(Network nw, DeployDestination destHost);
void releaseVlan(Network nw, VirtualMachineProfile vm); void releaseVlan(Network nw, VirtualMachineProfile vm);
void registerSwitchBackend(BaremetalSwitchBackend backend); void registerSwitchBackend(BaremetalSwitchBackend backend);
void deleteRct(DeleteBaremetalRctCmd cmd); void deleteRct(DeleteBaremetalRctCmd cmd);
BaremetalRctResponse listRct(); BaremetalRctResponse listRct();
} }

View File

@ -1,272 +1,272 @@
// Licensed to the Apache Software Foundation (ASF) under one // Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file // or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information // distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file // regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the // to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance // "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at // with the License. You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, // Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an // software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the // KIND, either express or implied. See the License for the
// specific language governing permissions and limitations // specific language governing permissions and limitations
// under the License. // under the License.
// //
package com.cloud.baremetal.manager; package com.cloud.baremetal.manager;
import com.cloud.baremetal.database.BaremetalRctDao; import com.cloud.baremetal.database.BaremetalRctDao;
import com.cloud.baremetal.database.BaremetalRctVO; import com.cloud.baremetal.database.BaremetalRctVO;
import com.cloud.baremetal.networkservice.BaremetalRctResponse; import com.cloud.baremetal.networkservice.BaremetalRctResponse;
import com.cloud.baremetal.networkservice.BaremetalSwitchBackend; import com.cloud.baremetal.networkservice.BaremetalSwitchBackend;
import com.cloud.baremetal.networkservice.BaremetalVlanStruct; import com.cloud.baremetal.networkservice.BaremetalVlanStruct;
import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeployDestination;
import com.cloud.host.HostVO; import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao; import com.cloud.host.dao.HostDao;
import com.cloud.network.Network; import com.cloud.network.Network;
import com.cloud.network.Networks; import com.cloud.network.Networks;
import com.cloud.user.Account; import com.cloud.user.Account;
import com.cloud.user.AccountManager; import com.cloud.user.AccountManager;
import com.cloud.user.AccountVO; import com.cloud.user.AccountVO;
import com.cloud.user.User; import com.cloud.user.User;
import com.cloud.user.UserVO; import com.cloud.user.UserVO;
import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserDao; import com.cloud.user.dao.UserDao;
import com.cloud.utils.component.ManagerBase; import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.db.QueryBuilder; import com.cloud.utils.db.QueryBuilder;
import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.VirtualMachineProfile;
import com.google.gson.Gson; import com.google.gson.Gson;
import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.AddBaremetalRctCmd; import org.apache.cloudstack.api.AddBaremetalRctCmd;
import org.apache.cloudstack.api.DeleteBaremetalRctCmd; import org.apache.cloudstack.api.DeleteBaremetalRctCmd;
import org.apache.cloudstack.api.ListBaremetalRctCmd; import org.apache.cloudstack.api.ListBaremetalRctCmd;
import org.apache.cloudstack.utils.baremetal.BaremetalUtils; import org.apache.cloudstack.utils.baremetal.BaremetalUtils;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import javax.inject.Inject; import javax.inject.Inject;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
/** /**
* Created by frank on 5/8/14. * Created by frank on 5/8/14.
*/ */
public class BaremetalVlanManagerImpl extends ManagerBase implements BaremetalVlanManager { public class BaremetalVlanManagerImpl extends ManagerBase implements BaremetalVlanManager {
private Gson gson = new Gson(); private Gson gson = new Gson();
@Inject @Inject
private BaremetalRctDao rctDao; private BaremetalRctDao rctDao;
@Inject @Inject
private HostDao hostDao; private HostDao hostDao;
@Inject @Inject
private AccountDao acntDao; private AccountDao acntDao;
@Inject @Inject
private UserDao userDao; private UserDao userDao;
@Inject @Inject
private AccountManager acntMgr; private AccountManager acntMgr;
private Map<String, BaremetalSwitchBackend> backends; private Map<String, BaremetalSwitchBackend> backends;
private class RackPair { private class RackPair {
BaremetalRct.Rack rack; BaremetalRct.Rack rack;
BaremetalRct.HostEntry host; BaremetalRct.HostEntry host;
} }
public void setBackends(Map<String, BaremetalSwitchBackend> backends) { public void setBackends(Map<String, BaremetalSwitchBackend> backends) {
this.backends = backends; this.backends = backends;
} }
@Override @Override
public BaremetalRctResponse addRct(AddBaremetalRctCmd cmd) { public BaremetalRctResponse addRct(AddBaremetalRctCmd cmd) {
try { try {
List<BaremetalRctVO> existings = rctDao.listAll(); List<BaremetalRctVO> existings = rctDao.listAll();
if (!existings.isEmpty()) { if (!existings.isEmpty()) {
throw new CloudRuntimeException(String.format("there is some RCT existing. A CloudStack deployment accepts only one RCT")); throw new CloudRuntimeException(String.format("there is some RCT existing. A CloudStack deployment accepts only one RCT"));
} }
URL url = new URL(cmd.getRctUrl()); URL url = new URL(cmd.getRctUrl());
RestTemplate rest = new RestTemplate(); RestTemplate rest = new RestTemplate();
String rctStr = rest.getForObject(url.toString(), String.class); String rctStr = rest.getForObject(url.toString(), String.class);
// validate it's right format // validate it's right format
BaremetalRct rct = gson.fromJson(rctStr, BaremetalRct.class); BaremetalRct rct = gson.fromJson(rctStr, BaremetalRct.class);
QueryBuilder<BaremetalRctVO> sc = QueryBuilder.create(BaremetalRctVO.class); QueryBuilder<BaremetalRctVO> sc = QueryBuilder.create(BaremetalRctVO.class);
sc.and(sc.entity().getUrl(), SearchCriteria.Op.EQ, cmd.getRctUrl()); sc.and(sc.entity().getUrl(), SearchCriteria.Op.EQ, cmd.getRctUrl());
BaremetalRctVO vo = sc.find(); BaremetalRctVO vo = sc.find();
if (vo == null) { if (vo == null) {
vo = new BaremetalRctVO(); vo = new BaremetalRctVO();
vo.setRct(gson.toJson(rct)); vo.setRct(gson.toJson(rct));
vo.setUrl(cmd.getRctUrl()); vo.setUrl(cmd.getRctUrl());
vo = rctDao.persist(vo); vo = rctDao.persist(vo);
} else { } else {
vo.setRct(gson.toJson(rct)); vo.setRct(gson.toJson(rct));
rctDao.update(vo.getId(), vo); rctDao.update(vo.getId(), vo);
} }
BaremetalRctResponse rsp = new BaremetalRctResponse(); BaremetalRctResponse rsp = new BaremetalRctResponse();
rsp.setUrl(vo.getUrl()); rsp.setUrl(vo.getUrl());
rsp.setId(vo.getUuid()); rsp.setId(vo.getUuid());
rsp.setObjectName("baremetalrct"); rsp.setObjectName("baremetalrct");
return rsp; return rsp;
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
throw new IllegalArgumentException(String.format("%s is not a legal http url", cmd.getRctUrl())); throw new IllegalArgumentException(String.format("%s is not a legal http url", cmd.getRctUrl()));
} }
} }
@Override @Override
public void prepareVlan(Network nw, DeployDestination destHost) { public void prepareVlan(Network nw, DeployDestination destHost) {
List<BaremetalRctVO> vos = rctDao.listAll(); List<BaremetalRctVO> vos = rctDao.listAll();
if (vos.isEmpty()) { if (vos.isEmpty()) {
throw new CloudRuntimeException("no rack configuration found, please call addBaremetalRct to add one"); throw new CloudRuntimeException("no rack configuration found, please call addBaremetalRct to add one");
} }
BaremetalRctVO vo = vos.get(0); BaremetalRctVO vo = vos.get(0);
BaremetalRct rct = gson.fromJson(vo.getRct(), BaremetalRct.class); BaremetalRct rct = gson.fromJson(vo.getRct(), BaremetalRct.class);
RackPair rp = findRack(rct, destHost.getHost().getPrivateMacAddress()); RackPair rp = findRack(rct, destHost.getHost().getPrivateMacAddress());
if (rp == null) { 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())); 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())); int vlan = Integer.parseInt(Networks.BroadcastDomainType.getValue(nw.getBroadcastUri()));
BaremetalSwitchBackend backend = getSwitchBackend(rp.rack.getL2Switch().getType()); BaremetalSwitchBackend backend = getSwitchBackend(rp.rack.getL2Switch().getType());
BaremetalVlanStruct struct = new BaremetalVlanStruct(); BaremetalVlanStruct struct = new BaremetalVlanStruct();
struct.setHostMac(rp.host.getMac()); struct.setHostMac(rp.host.getMac());
struct.setPort(rp.host.getPort()); struct.setPort(rp.host.getPort());
struct.setSwitchIp(rp.rack.getL2Switch().getIp()); struct.setSwitchIp(rp.rack.getL2Switch().getIp());
struct.setSwitchPassword(rp.rack.getL2Switch().getPassword()); struct.setSwitchPassword(rp.rack.getL2Switch().getPassword());
struct.setSwitchType(rp.rack.getL2Switch().getType()); struct.setSwitchType(rp.rack.getL2Switch().getType());
struct.setSwitchUsername(rp.rack.getL2Switch().getUsername()); struct.setSwitchUsername(rp.rack.getL2Switch().getUsername());
struct.setVlan(vlan); struct.setVlan(vlan);
backend.prepareVlan(struct); backend.prepareVlan(struct);
} }
@Override @Override
public void releaseVlan(Network nw, VirtualMachineProfile vm) { public void releaseVlan(Network nw, VirtualMachineProfile vm) {
List<BaremetalRctVO> vos = rctDao.listAll(); List<BaremetalRctVO> vos = rctDao.listAll();
if (vos.isEmpty()) { if (vos.isEmpty()) {
throw new CloudRuntimeException("no rack configuration found, please call addBaremetalRct to add one"); throw new CloudRuntimeException("no rack configuration found, please call addBaremetalRct to add one");
} }
BaremetalRctVO vo = vos.get(0); BaremetalRctVO vo = vos.get(0);
BaremetalRct rct = gson.fromJson(vo.getRct(), BaremetalRct.class); BaremetalRct rct = gson.fromJson(vo.getRct(), BaremetalRct.class);
HostVO host = hostDao.findById(vm.getVirtualMachine().getHostId()); HostVO host = hostDao.findById(vm.getVirtualMachine().getHostId());
RackPair rp = findRack(rct, host.getPrivateMacAddress()); RackPair rp = findRack(rct, host.getPrivateMacAddress());
assert rp != null : String.format("where is my rack???"); assert rp != null : String.format("where is my rack???");
int vlan = Integer.parseInt(Networks.BroadcastDomainType.getValue(nw.getBroadcastUri())); int vlan = Integer.parseInt(Networks.BroadcastDomainType.getValue(nw.getBroadcastUri()));
BaremetalVlanStruct struct = new BaremetalVlanStruct(); BaremetalVlanStruct struct = new BaremetalVlanStruct();
struct.setHostMac(rp.host.getMac()); struct.setHostMac(rp.host.getMac());
struct.setPort(rp.host.getPort()); struct.setPort(rp.host.getPort());
struct.setSwitchIp(rp.rack.getL2Switch().getIp()); struct.setSwitchIp(rp.rack.getL2Switch().getIp());
struct.setSwitchPassword(rp.rack.getL2Switch().getPassword()); struct.setSwitchPassword(rp.rack.getL2Switch().getPassword());
struct.setSwitchType(rp.rack.getL2Switch().getType()); struct.setSwitchType(rp.rack.getL2Switch().getType());
struct.setSwitchUsername(rp.rack.getL2Switch().getUsername()); struct.setSwitchUsername(rp.rack.getL2Switch().getUsername());
struct.setVlan(vlan); struct.setVlan(vlan);
BaremetalSwitchBackend backend = getSwitchBackend(rp.rack.getL2Switch().getType()); BaremetalSwitchBackend backend = getSwitchBackend(rp.rack.getL2Switch().getType());
backend.removePortFromVlan(struct); backend.removePortFromVlan(struct);
} }
@Override @Override
public void registerSwitchBackend(BaremetalSwitchBackend backend) { public void registerSwitchBackend(BaremetalSwitchBackend backend) {
backends.put(backend.getSwitchBackendType(), backend); backends.put(backend.getSwitchBackendType(), backend);
} }
@Override @Override
public void deleteRct(DeleteBaremetalRctCmd cmd) { public void deleteRct(DeleteBaremetalRctCmd cmd) {
rctDao.remove(cmd.getId()); rctDao.remove(cmd.getId());
} }
@Override @Override
public BaremetalRctResponse listRct() { public BaremetalRctResponse listRct() {
List<BaremetalRctVO> vos = rctDao.listAll(); List<BaremetalRctVO> vos = rctDao.listAll();
if (!vos.isEmpty()) { if (!vos.isEmpty()) {
BaremetalRctVO vo = vos.get(0); BaremetalRctVO vo = vos.get(0);
BaremetalRctResponse rsp = new BaremetalRctResponse(); BaremetalRctResponse rsp = new BaremetalRctResponse();
rsp.setId(vo.getUuid()); rsp.setId(vo.getUuid());
rsp.setUrl(vo.getUrl()); rsp.setUrl(vo.getUrl());
rsp.setObjectName("baremetalrct"); rsp.setObjectName("baremetalrct");
return rsp; return rsp;
} }
return null; return null;
} }
private BaremetalSwitchBackend getSwitchBackend(String type) { private BaremetalSwitchBackend getSwitchBackend(String type) {
BaremetalSwitchBackend backend = backends.get(type); BaremetalSwitchBackend backend = backends.get(type);
if (backend == null) { if (backend == null) {
throw new CloudRuntimeException(String.format("cannot find switch backend[type:%s]", type)); throw new CloudRuntimeException(String.format("cannot find switch backend[type:%s]", type));
} }
return backend; return backend;
} }
private RackPair findRack(BaremetalRct rct, String mac) { private RackPair findRack(BaremetalRct rct, String mac) {
for (BaremetalRct.Rack rack : rct.getRacks()) { for (BaremetalRct.Rack rack : rct.getRacks()) {
for (BaremetalRct.HostEntry host : rack.getHosts()) { for (BaremetalRct.HostEntry host : rack.getHosts()) {
if (mac.equals(host.getMac())) { if (mac.equals(host.getMac())) {
RackPair p = new RackPair(); RackPair p = new RackPair();
p.host = host; p.host = host;
p.rack = rack; p.rack = rack;
return p; return p;
} }
} }
} }
return null; return null;
} }
@Override @Override
public String getName() { public String getName() {
return "Baremetal Vlan Manager"; return "Baremetal Vlan Manager";
} }
@Override @Override
public List<Class<?>> getCommands() { public List<Class<?>> getCommands() {
List<Class<?>> cmds = new ArrayList<Class<?>>(); List<Class<?>> cmds = new ArrayList<Class<?>>();
cmds.add(AddBaremetalRctCmd.class); cmds.add(AddBaremetalRctCmd.class);
cmds.add(ListBaremetalRctCmd.class); cmds.add(ListBaremetalRctCmd.class);
cmds.add(DeleteBaremetalRctCmd.class); cmds.add(DeleteBaremetalRctCmd.class);
return cmds; return cmds;
} }
@Override @Override
public boolean start() { public boolean start() {
QueryBuilder<AccountVO> acntq = QueryBuilder.create(AccountVO.class); QueryBuilder<AccountVO> acntq = QueryBuilder.create(AccountVO.class);
acntq.and(acntq.entity().getAccountName(), SearchCriteria.Op.EQ, BaremetalUtils.BAREMETAL_SYSTEM_ACCOUNT_NAME); acntq.and(acntq.entity().getAccountName(), SearchCriteria.Op.EQ, BaremetalUtils.BAREMETAL_SYSTEM_ACCOUNT_NAME);
AccountVO acnt = acntq.find(); AccountVO acnt = acntq.find();
if (acnt != null) { if (acnt != null) {
return true; return true;
} }
acnt = new AccountVO(); acnt = new AccountVO();
acnt.setAccountName(BaremetalUtils.BAREMETAL_SYSTEM_ACCOUNT_NAME); acnt.setAccountName(BaremetalUtils.BAREMETAL_SYSTEM_ACCOUNT_NAME);
acnt.setUuid(UUID.randomUUID().toString()); acnt.setUuid(UUID.randomUUID().toString());
acnt.setState(Account.State.ENABLED); acnt.setState(Account.State.ENABLED);
acnt.setDomainId(1); acnt.setDomainId(1);
acnt.setType(RoleType.User.getAccountType()); acnt.setType(RoleType.User.getAccountType());
acnt.setRoleId(RoleType.User.getId()); acnt.setRoleId(RoleType.User.getId());
acnt = acntDao.persist(acnt); acnt = acntDao.persist(acnt);
UserVO user = new UserVO(); UserVO user = new UserVO();
user.setState(Account.State.ENABLED); user.setState(Account.State.ENABLED);
user.setUuid(UUID.randomUUID().toString()); user.setUuid(UUID.randomUUID().toString());
user.setAccountId(acnt.getAccountId()); user.setAccountId(acnt.getAccountId());
user.setUsername(BaremetalUtils.BAREMETAL_SYSTEM_ACCOUNT_NAME); user.setUsername(BaremetalUtils.BAREMETAL_SYSTEM_ACCOUNT_NAME);
user.setFirstname(BaremetalUtils.BAREMETAL_SYSTEM_ACCOUNT_NAME); user.setFirstname(BaremetalUtils.BAREMETAL_SYSTEM_ACCOUNT_NAME);
user.setLastname(BaremetalUtils.BAREMETAL_SYSTEM_ACCOUNT_NAME); user.setLastname(BaremetalUtils.BAREMETAL_SYSTEM_ACCOUNT_NAME);
user.setPassword(UUID.randomUUID().toString()); user.setPassword(UUID.randomUUID().toString());
user.setSource(User.Source.UNKNOWN); user.setSource(User.Source.UNKNOWN);
user = userDao.persist(user); user = userDao.persist(user);
String[] keys = acntMgr.createApiKeyAndSecretKey(user.getId()); String[] keys = acntMgr.createApiKeyAndSecretKey(user.getId());
user.setApiKey(keys[0]); user.setApiKey(keys[0]);
user.setSecretKey(keys[1]); user.setSecretKey(keys[1]);
userDao.update(user.getId(), user); userDao.update(user.getId(), user);
return true; return true;
} }
} }

View File

@ -1,55 +1,55 @@
// Licensed to the Apache Software Foundation (ASF) under one // Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file // or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information // distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file // regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the // to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance // "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at // with the License. You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, // Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an // software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the // KIND, either express or implied. See the License for the
// specific language governing permissions and limitations // specific language governing permissions and limitations
// under the License. // under the License.
// //
package com.cloud.baremetal.networkservice; package com.cloud.baremetal.networkservice;
import com.cloud.baremetal.database.BaremetalRctVO; import com.cloud.baremetal.database.BaremetalRctVO;
import com.cloud.serializer.Param; import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse; import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.EntityReference; import org.apache.cloudstack.api.EntityReference;
/** /**
* Created by frank on 5/8/14. * Created by frank on 5/8/14.
*/ */
@EntityReference(value = BaremetalRctVO.class) @EntityReference(value = BaremetalRctVO.class)
public class BaremetalRctResponse extends BaseResponse { public class BaremetalRctResponse extends BaseResponse {
@SerializedName(ApiConstants.ID) @SerializedName(ApiConstants.ID)
@Param(description = "id of rct") @Param(description = "id of rct")
private String id; private String id;
@SerializedName(ApiConstants.URL) @SerializedName(ApiConstants.URL)
@Param(description = "url") @Param(description = "url")
private String url; private String url;
public String getId() { public String getId() {
return id; return id;
} }
public void setId(String id) { public void setId(String id) {
this.id = id; this.id = id;
} }
public String getUrl() { public String getUrl() {
return url; return url;
} }
public void setUrl(String url) { public void setUrl(String url) {
this.url = url; this.url = url;
} }
} }

View File

@ -1,34 +1,34 @@
// Licensed to the Apache Software Foundation (ASF) under one // Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file // or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information // distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file // regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the // to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance // "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at // with the License. You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, // Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an // software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the // KIND, either express or implied. See the License for the
// specific language governing permissions and limitations // specific language governing permissions and limitations
// under the License. // under the License.
// //
// Automatically generated by addcopyright.py at 01/29/2013 // Automatically generated by addcopyright.py at 01/29/2013
// Apache License, Version 2.0 (the "License"); you may not use this // Apache License, Version 2.0 (the "License"); you may not use this
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// //
// Automatically generated by addcopyright.py at 04/03/2012 // Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.baremetal.networkservice; package com.cloud.baremetal.networkservice;
/** /**
* Created by frank on 9/2/14. * Created by frank on 9/2/14.
*/ */
public interface BaremetalSwitchBackend { public interface BaremetalSwitchBackend {
String getSwitchBackendType(); String getSwitchBackendType();
void prepareVlan(BaremetalVlanStruct struct); void prepareVlan(BaremetalVlanStruct struct);
void removePortFromVlan(BaremetalVlanStruct struct); void removePortFromVlan(BaremetalVlanStruct struct);
} }

View File

@ -1,122 +1,122 @@
// Licensed to the Apache Software Foundation (ASF) under one // Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file // or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information // distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file // regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the // to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance // "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at // with the License. You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, // Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an // software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the // KIND, either express or implied. See the License for the
// specific language governing permissions and limitations // specific language governing permissions and limitations
// under the License. // under the License.
package com.cloud.baremetal.networkservice; package com.cloud.baremetal.networkservice;
/** /**
* Created by frank on 7/23/14. * Created by frank on 7/23/14.
*/ */
public class BaremetalVirtualRouterCommands { public class BaremetalVirtualRouterCommands {
public abstract static class AgentCommand { public abstract static class AgentCommand {
} }
public abstract static class AgentResponse { public abstract static class AgentResponse {
private boolean success; private boolean success;
private String error; private String error;
public boolean isSuccess() { public boolean isSuccess() {
return success; return success;
} }
public void setSuccess(boolean success) { public void setSuccess(boolean success) {
this.success = success; this.success = success;
} }
public String getError() { public String getError() {
return error; return error;
} }
public void setError(String error) { public void setError(String error) {
this.error = error; this.error = error;
} }
} }
public static class PreparePxeCmd extends AgentCommand { public static class PreparePxeCmd extends AgentCommand {
private String guestMac; private String guestMac;
private String templateUuid; private String templateUuid;
private String kickStartUrl; private String kickStartUrl;
private String initrdUrl; private String initrdUrl;
private String kernelUrl; private String kernelUrl;
public String getTemplateUuid() { public String getTemplateUuid() {
return templateUuid; return templateUuid;
} }
public void setTemplateUuid(String templateUuid) { public void setTemplateUuid(String templateUuid) {
this.templateUuid = templateUuid; this.templateUuid = templateUuid;
} }
public String getGuestMac() { public String getGuestMac() {
return guestMac; return guestMac;
} }
public void setGuestMac(String guestMac) { public void setGuestMac(String guestMac) {
this.guestMac = guestMac; this.guestMac = guestMac;
} }
public String getKickStartUrl() { public String getKickStartUrl() {
return kickStartUrl; return kickStartUrl;
} }
public void setKickStartUrl(String kickStartUrl) { public void setKickStartUrl(String kickStartUrl) {
this.kickStartUrl = kickStartUrl; this.kickStartUrl = kickStartUrl;
} }
public String getInitrdUrl() { public String getInitrdUrl() {
return initrdUrl; return initrdUrl;
} }
public void setInitrdUrl(String initrdUrl) { public void setInitrdUrl(String initrdUrl) {
this.initrdUrl = initrdUrl; this.initrdUrl = initrdUrl;
} }
public String getKernelUrl() { public String getKernelUrl() {
return kernelUrl; return kernelUrl;
} }
public void setKernelUrl(String kernelUrl) { public void setKernelUrl(String kernelUrl) {
this.kernelUrl = kernelUrl; this.kernelUrl = kernelUrl;
} }
} }
public static class PreparePxeRsp extends AgentResponse { public static class PreparePxeRsp extends AgentResponse {
} }
public static class PrepareSourceNatCmd extends AgentCommand { public static class PrepareSourceNatCmd extends AgentCommand {
private String internalStorageServerIp; private String internalStorageServerIp;
private String managementNicIp; private String managementNicIp;
public String getInternalStorageServerIp() { public String getInternalStorageServerIp() {
return internalStorageServerIp; return internalStorageServerIp;
} }
public void setInternalStorageServerIp(String internalStorageServerIp) { public void setInternalStorageServerIp(String internalStorageServerIp) {
this.internalStorageServerIp = internalStorageServerIp; this.internalStorageServerIp = internalStorageServerIp;
} }
public String getManagementNicIp() { public String getManagementNicIp() {
return managementNicIp; return managementNicIp;
} }
public void setManagementNicIp(String managementNicIp) { public void setManagementNicIp(String managementNicIp) {
this.managementNicIp = managementNicIp; this.managementNicIp = managementNicIp;
} }
} }
public static class PrepareSourceNatRsp extends AgentResponse { public static class PrepareSourceNatRsp extends AgentResponse {
} }
} }

View File

@ -1,92 +1,92 @@
// Licensed to the Apache Software Foundation (ASF) under one // Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file // or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information // distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file // regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the // to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance // "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at // with the License. You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, // Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an // software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the // KIND, either express or implied. See the License for the
// specific language governing permissions and limitations // specific language governing permissions and limitations
// under the License. // under the License.
// //
// Automatically generated by addcopyright.py at 01/29/2013 // Automatically generated by addcopyright.py at 01/29/2013
// Apache License, Version 2.0 (the "License"); you may not use this // Apache License, Version 2.0 (the "License"); you may not use this
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// //
// Automatically generated by addcopyright.py at 04/03/2012 // Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.baremetal.networkservice; package com.cloud.baremetal.networkservice;
/** /**
* Created by frank on 9/2/14. * Created by frank on 9/2/14.
*/ */
public class BaremetalVlanStruct { public class BaremetalVlanStruct {
private String switchType; private String switchType;
private String switchIp; private String switchIp;
private String switchUsername; private String switchUsername;
private String switchPassword; private String switchPassword;
private String hostMac; private String hostMac;
private String port; private String port;
private int vlan; private int vlan;
public String getSwitchType() { public String getSwitchType() {
return switchType; return switchType;
} }
public void setSwitchType(String switchType) { public void setSwitchType(String switchType) {
this.switchType = switchType; this.switchType = switchType;
} }
public String getSwitchIp() { public String getSwitchIp() {
return switchIp; return switchIp;
} }
public void setSwitchIp(String switchIp) { public void setSwitchIp(String switchIp) {
this.switchIp = switchIp; this.switchIp = switchIp;
} }
public String getSwitchUsername() { public String getSwitchUsername() {
return switchUsername; return switchUsername;
} }
public void setSwitchUsername(String switchUsername) { public void setSwitchUsername(String switchUsername) {
this.switchUsername = switchUsername; this.switchUsername = switchUsername;
} }
public String getSwitchPassword() { public String getSwitchPassword() {
return switchPassword; return switchPassword;
} }
public void setSwitchPassword(String switchPassword) { public void setSwitchPassword(String switchPassword) {
this.switchPassword = switchPassword; this.switchPassword = switchPassword;
} }
public String getHostMac() { public String getHostMac() {
return hostMac; return hostMac;
} }
public void setHostMac(String hostMac) { public void setHostMac(String hostMac) {
this.hostMac = hostMac; this.hostMac = hostMac;
} }
public String getPort() { public String getPort() {
return port; return port;
} }
public void setPort(String port) { public void setPort(String port) {
this.port = port; this.port = port;
} }
public int getVlan() { public int getVlan() {
return vlan; return vlan;
} }
public void setVlan(int vlan) { public void setVlan(int vlan) {
this.vlan = vlan; this.vlan = vlan;
} }
} }

View File

@ -1,56 +1,56 @@
// Licensed to the Apache Software Foundation (ASF) under one // Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file // or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information // distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file // regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the // to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance // "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at // with the License. You may obtain a copy of the License at
// //
// http://www.apache.org/licenses/LICENSE-2.0 // http://www.apache.org/licenses/LICENSE-2.0
// //
// Unless required by applicable law or agreed to in writing, // Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an // software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the // KIND, either express or implied. See the License for the
// specific language governing permissions and limitations // specific language governing permissions and limitations
// under the License. // under the License.
// //
// Automatically generated by addcopyright.py at 01/29/2013 // Automatically generated by addcopyright.py at 01/29/2013
// Apache License, Version 2.0 (the "License"); you may not use this // Apache License, Version 2.0 (the "License"); you may not use this
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// //
// Automatically generated by addcopyright.py at 04/03/2012 // Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.baremetal.networkservice; package com.cloud.baremetal.networkservice;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.xmlobject.XmlObject; import com.cloud.utils.xmlobject.XmlObject;
import com.cloud.utils.xmlobject.XmlObjectParser; import com.cloud.utils.xmlobject.XmlObjectParser;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.springframework.http.HttpEntity; import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpResponse; import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriComponentsBuilder;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
* Created by frank on 9/2/14. * Created by frank on 9/2/14.
*/ */
public class Force10BaremetalSwitchBackend implements BaremetalSwitchBackend { public class Force10BaremetalSwitchBackend implements BaremetalSwitchBackend {
private Logger logger = Logger.getLogger(Force10BaremetalSwitchBackend.class); private Logger logger = Logger.getLogger(Force10BaremetalSwitchBackend.class);
public static final String TYPE = "Force10"; public static final String TYPE = "Force10";
private static List<HttpStatus> successHttpStatusCode = new ArrayList<>(); private static List<HttpStatus> successHttpStatusCode = new ArrayList<>();
{ {
successHttpStatusCode.add(HttpStatus.OK); successHttpStatusCode.add(HttpStatus.OK);
@ -62,7 +62,7 @@ public class Force10BaremetalSwitchBackend implements BaremetalSwitchBackend {
successHttpStatusCode.add(HttpStatus.ALREADY_REPORTED); successHttpStatusCode.add(HttpStatus.ALREADY_REPORTED);
} }
RestTemplate rest = new RestTemplate(); RestTemplate rest = new RestTemplate();
{ {
// fake error handler, we handle error in business logic code // fake error handler, we handle error in business logic code
rest.setErrorHandler(new ResponseErrorHandler() { rest.setErrorHandler(new ResponseErrorHandler() {
@ -70,7 +70,7 @@ public class Force10BaremetalSwitchBackend implements BaremetalSwitchBackend {
public boolean hasError(ClientHttpResponse clientHttpResponse) throws IOException { public boolean hasError(ClientHttpResponse clientHttpResponse) throws IOException {
return false; return false;
} }
@Override @Override
public void handleError(ClientHttpResponse clientHttpResponse) throws IOException { public void handleError(ClientHttpResponse clientHttpResponse) throws IOException {
} }
@ -78,29 +78,29 @@ public class Force10BaremetalSwitchBackend implements BaremetalSwitchBackend {
} }
private String buildLink(String switchIp, String path) { private String buildLink(String switchIp, String path) {
UriComponentsBuilder builder = UriComponentsBuilder.newInstance(); UriComponentsBuilder builder = UriComponentsBuilder.newInstance();
builder.scheme("http"); builder.scheme("http");
builder.host(switchIp); builder.host(switchIp);
builder.port(8008); builder.port(8008);
builder.path(path); builder.path(path);
return builder.build().toUriString(); return builder.build().toUriString();
} }
@Override @Override
public String getSwitchBackendType() { public String getSwitchBackendType() {
return TYPE; return TYPE;
} }
@Override @Override
public void prepareVlan(BaremetalVlanStruct struct) { public void prepareVlan(BaremetalVlanStruct struct) {
String link = buildLink(struct.getSwitchIp(), String.format("/api/running/ftos/interface/vlan/%s", struct.getVlan())); String link = buildLink(struct.getSwitchIp(), String.format("/api/running/ftos/interface/vlan/%s", struct.getVlan()));
HttpHeaders headers = createBasicAuthenticationHeader(struct); HttpHeaders headers = createBasicAuthenticationHeader(struct);
HttpEntity<String> request = new HttpEntity<>(headers); HttpEntity<String> request = new HttpEntity<>(headers);
ResponseEntity rsp = rest.exchange(link, HttpMethod.GET, request, String.class); ResponseEntity rsp = rest.exchange(link, HttpMethod.GET, request, String.class);
logger.debug(String.format("http get: %s", link)); logger.debug(String.format("http get: %s", link));
if (rsp.getStatusCode() == HttpStatus.NOT_FOUND) { if (rsp.getStatusCode() == HttpStatus.NOT_FOUND) {
PortInfo port = new PortInfo(struct); PortInfo port = new PortInfo(struct);
XmlObject xml = new XmlObject("vlan").putElement("vlan-id", XmlObject xml = new XmlObject("vlan").putElement("vlan-id",
new XmlObject("vlan-id").setText(String.valueOf(struct.getVlan()))).putElement("untagged", new XmlObject("vlan-id").setText(String.valueOf(struct.getVlan()))).putElement("untagged",
new XmlObject("untagged").putElement(port.interfaceType, new XmlObject(port.interfaceType) 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)); logger.debug(String.format("http get: %s, body: %s", link, request));
rsp = rest.exchange(link, HttpMethod.POST, request, String.class); rsp = rest.exchange(link, HttpMethod.POST, request, String.class);
if (!successHttpStatusCode.contains(rsp.getStatusCode())) { 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())); struct.getVlan(), struct.getSwitchIp(),rsp.getStatusCode(), rsp.getBody()));
} else { } else {
logger.debug(String.format("successfully programmed vlan[%s] on Force10[ip:%s, port:%s]. http response[status code:%s, body:%s]", 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())); struct.getVlan(), struct.getSwitchIp(), struct.getPort(), rsp.getStatusCode(), rsp.getBody()));
} }
} else if (successHttpStatusCode.contains(rsp.getStatusCode())) { } else if (successHttpStatusCode.contains(rsp.getStatusCode())) {
PortInfo port = new PortInfo(struct); PortInfo port = new PortInfo(struct);
XmlObject xml = XmlObjectParser.parseFromString((String)rsp.getBody()); XmlObject xml = XmlObjectParser.parseFromString((String)rsp.getBody());
List<XmlObject> ports = xml.getAsList("untagged.tengigabitethernet"); List<XmlObject> ports = xml.getAsList("untagged.tengigabitethernet");
ports.addAll(xml.<XmlObject>getAsList("untagged.gigabitethernet")); ports.addAll(xml.<XmlObject>getAsList("untagged.gigabitethernet"));
ports.addAll(xml.<XmlObject>getAsList("untagged.fortyGigE")); ports.addAll(xml.<XmlObject>getAsList("untagged.fortyGigE"));
for (XmlObject pxml : ports) { for (XmlObject pxml : ports) {
XmlObject name = pxml.get("name"); XmlObject name = pxml.get("name");
if (port.port.equals(name.getText())) { 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())); logger.debug(String.format("port[%s] has joined in vlan[%s], no need to program again", struct.getPort(), struct.getVlan()));
return; return;
} }
} }
xml.removeElement("mtu"); xml.removeElement("mtu");
xml.setText(null); xml.setText(null);
XmlObject tag = xml.get("untagged"); XmlObject tag = xml.get("untagged");
@ -144,51 +144,51 @@ public class Force10BaremetalSwitchBackend implements BaremetalSwitchBackend {
request = new HttpEntity<>(xml.dump(), headers); request = new HttpEntity<>(xml.dump(), headers);
link = buildLink(struct.getSwitchIp(), String.format("/api/running/ftos/interface/vlan/%s", struct.getVlan())); 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)); 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())) { 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", 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())); struct.getVlan(), struct.getPort(), struct.getSwitchIp(), rsp.getStatusCode(), rsp.getBody()));
} else { } else {
logger.debug(String.format("successfully join port[%s] into vlan[%s] on Force10[ip:%s]. http response[status code:%s, body:%s]", 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())); struct.getPort(), struct.getVlan(), struct.getSwitchIp(), rsp.getStatusCode(), rsp.getBody()));
} }
} else { } else {
throw new CloudRuntimeException(String.format("force10[ip:%s] returns unexpected error[%s] when http getting %s, body dump:%s", 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())); struct.getSwitchIp(), rsp.getStatusCode(), link, rsp.getBody()));
} }
} }
@Override @Override
public void removePortFromVlan(BaremetalVlanStruct struct) { public void removePortFromVlan(BaremetalVlanStruct struct) {
String link = buildLink(struct.getSwitchIp(), String.format("/api/running/ftos/interface/vlan/%s", struct.getVlan())); String link = buildLink(struct.getSwitchIp(), String.format("/api/running/ftos/interface/vlan/%s", struct.getVlan()));
HttpHeaders headers = createBasicAuthenticationHeader(struct); HttpHeaders headers = createBasicAuthenticationHeader(struct);
HttpEntity<String> request = new HttpEntity<>(headers); HttpEntity<String> request = new HttpEntity<>(headers);
logger.debug(String.format("http get: %s, body: %s", link, request)); logger.debug(String.format("http get: %s, body: %s", link, request));
ResponseEntity rsp = rest.exchange(link, HttpMethod.GET, request, String.class); ResponseEntity rsp = rest.exchange(link, HttpMethod.GET, request, String.class);
if (rsp.getStatusCode() == HttpStatus.NOT_FOUND) { 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())); 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) { } else if (rsp.getStatusCode() == HttpStatus.OK) {
PortInfo port = new PortInfo(struct); PortInfo port = new PortInfo(struct);
XmlObject xml = XmlObjectParser.parseFromString((String)rsp.getBody()); XmlObject xml = XmlObjectParser.parseFromString((String)rsp.getBody());
List<XmlObject> ports = xml.getAsList("untagged.tengigabitethernet"); List<XmlObject> ports = xml.getAsList("untagged.tengigabitethernet");
ports.addAll(xml.<XmlObject>getAsList("untagged.gigabitethernet")); ports.addAll(xml.<XmlObject>getAsList("untagged.gigabitethernet"));
ports.addAll(xml.<XmlObject>getAsList("untagged.fortyGigE")); ports.addAll(xml.<XmlObject>getAsList("untagged.fortyGigE"));
List<XmlObject> newPorts = new ArrayList<>(); List<XmlObject> newPorts = new ArrayList<>();
boolean needRemove = false; boolean needRemove = false;
for (XmlObject pxml : ports) { for (XmlObject pxml : ports) {
XmlObject name = pxml.get("name"); XmlObject name = pxml.get("name");
if (port.port.equals(name.getText())) { if (port.port.equals(name.getText())) {
needRemove = true; needRemove = true;
continue; continue;
} }
newPorts.add(pxml); newPorts.add(pxml);
} }
if (!needRemove) { if (!needRemove) {
return; return;
} }
xml.setText(null); xml.setText(null);
xml.removeElement("mtu"); xml.removeElement("mtu");
XmlObject tagged = xml.get("untagged"); XmlObject tagged = xml.get("untagged");
@ -197,56 +197,56 @@ public class Force10BaremetalSwitchBackend implements BaremetalSwitchBackend {
tagged.putElement(p.getTag(), p); tagged.putElement(p.getTag(), p);
} }
request = new HttpEntity<>(xml.dump(), headers); request = new HttpEntity<>(xml.dump(), headers);
logger.debug(String.format("http get: %s, body: %s", link, request)); 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())) { 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", 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())); struct.getVlan(), struct.getPort(), struct.getSwitchIp(), rsp.getStatusCode(), rsp.getBody()));
} else { } else {
logger.debug(String.format("removed port[%s] from vlan[%s] on force10[ip:%s]", struct.getPort(), struct.getVlan(), struct.getSwitchIp())); logger.debug(String.format("removed port[%s] from vlan[%s] on force10[ip:%s]", struct.getPort(), struct.getVlan(), struct.getSwitchIp()));
} }
} else { } else {
throw new CloudRuntimeException(String.format("force10[ip:%s] returns unexpected error[%s] when http getting %s, body dump:%s", 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())); struct.getSwitchIp(), rsp.getStatusCode(), link, rsp.getBody()));
} }
} }
private HttpHeaders createBasicAuthenticationHeader(BaremetalVlanStruct struct) { private HttpHeaders createBasicAuthenticationHeader(BaremetalVlanStruct struct) {
String plainCreds = String.format("%s:%s", struct.getSwitchUsername(), struct.getSwitchPassword()); String plainCreds = String.format("%s:%s", struct.getSwitchUsername(), struct.getSwitchPassword());
byte[] plainCredsBytes = plainCreds.getBytes(); byte[] plainCredsBytes = plainCreds.getBytes();
byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes); byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
String base64Creds = new String(base64CredsBytes); String base64Creds = new String(base64CredsBytes);
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "Basic " + base64Creds); headers.add("Authorization", "Basic " + base64Creds);
headers.setAccept(Arrays.asList(MediaType.ALL)); headers.setAccept(Arrays.asList(MediaType.ALL));
headers.setContentType(MediaType.valueOf("application/vnd.yang.data+xml")); headers.setContentType(MediaType.valueOf("application/vnd.yang.data+xml"));
return headers; return headers;
} }
private class PortInfo { private class PortInfo {
static final String G_IFACE = "gigabitethernet"; static final String G_IFACE = "gigabitethernet";
static final String TEN_G_IFACE = "tengigabitethernet"; static final String TEN_G_IFACE = "tengigabitethernet";
static final String FOURTY_G_IFACE = "fortyGigE"; static final String FOURTY_G_IFACE = "fortyGigE";
private String interfaceType; private String interfaceType;
private String port; private String port;
PortInfo(BaremetalVlanStruct struct) { PortInfo(BaremetalVlanStruct struct) {
String[] ps = StringUtils.split(struct.getPort(), ":"); String[] ps = StringUtils.split(struct.getPort(), ":");
if (ps.length == 1) { if (ps.length == 1) {
interfaceType = TEN_G_IFACE; interfaceType = TEN_G_IFACE;
port = ps[0]; port = ps[0];
} else if (ps.length == 2) { } else if (ps.length == 2) {
interfaceType = ps[0]; interfaceType = ps[0];
if (!interfaceType.equals(G_IFACE) && !interfaceType.equals(TEN_G_IFACE) && !interfaceType.equals(FOURTY_G_IFACE)) { 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)); 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]; port = ps[1];
} else { } 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())); 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()));
} }
} }
} }
} }

View File

@ -1,236 +1,236 @@
# Licensed to the Apache Software Foundation (ASF) under one # Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file # or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information # distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file # regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the # to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance # "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at # with the License. You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, # Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an # software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the # KIND, either express or implied. See the License for the
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
# #
# Automatically generated by addcopyright.py at 01/29/2013 # Automatically generated by addcopyright.py at 01/29/2013
''' '''
Created on Jan 2, 2013 Created on Jan 2, 2013
@author: frank @author: frank
''' '''
import cherrypy import cherrypy
import sglib import sglib
import xmlobject import xmlobject
import types import types
import uuid import uuid
import os.path import os.path
import sys import sys
import os import os
class SGRule(object): class SGRule(object):
def __init__(self): def __init__(self):
self.protocol = None self.protocol = None
self.start_port = None self.start_port = None
self.end_port = None self.end_port = None
self.allowed_ips = [] self.allowed_ips = []
class IPSet(object): class IPSet(object):
IPSET_TYPE = 'hash:ip' IPSET_TYPE = 'hash:ip'
def __init__(self, setname, ips): def __init__(self, setname, ips):
self.ips = ips self.ips = ips
self.name = setname self.name = setname
def create(self): def create(self):
tmpname = str(uuid.uuid4()).replace('-', '')[0:30] tmpname = str(uuid.uuid4()).replace('-', '')[0:30]
sglib.ShellCmd('ipset -N %s %s' % (tmpname, self.IPSET_TYPE))() sglib.ShellCmd('ipset -N %s %s' % (tmpname, self.IPSET_TYPE))()
try: try:
for ip in self.ips: for ip in self.ips:
sglib.ShellCmd('ipset -A %s %s' % (tmpname, ip))() sglib.ShellCmd('ipset -A %s %s' % (tmpname, ip))()
try: try:
sglib.ShellCmd('ipset -N %s %s' % (self.name, self.IPSET_TYPE))() sglib.ShellCmd('ipset -N %s %s' % (self.name, self.IPSET_TYPE))()
cherrypy.log('created new ipset: %s' % self.name) cherrypy.log('created new ipset: %s' % self.name)
except Exception: except Exception:
cherrypy.log('%s already exists, no need to create new' % self.name) cherrypy.log('%s already exists, no need to create new' % self.name)
finally: finally:
sglib.ShellCmd('ipset -W %s %s' % (tmpname, self.name))() sglib.ShellCmd('ipset -W %s %s' % (tmpname, self.name))()
sglib.ShellCmd('ipset -F %s' % tmpname)() sglib.ShellCmd('ipset -F %s' % tmpname)()
sglib.ShellCmd('ipset -X %s' % tmpname)() sglib.ShellCmd('ipset -X %s' % tmpname)()
@staticmethod @staticmethod
def destroy_sets(sets_to_keep): def destroy_sets(sets_to_keep):
sets = sglib.ShellCmd('ipset list')() sets = sglib.ShellCmd('ipset list')()
for s in sets.split('\n'): for s in sets.split('\n'):
if 'Name:' in s: if 'Name:' in s:
set_name = s.split(':', 1)[1].strip() set_name = s.split(':', 1)[1].strip()
if not set_name in sets_to_keep: if not set_name in sets_to_keep:
sglib.ShellCmd('ipset destroy %s' % set_name)() sglib.ShellCmd('ipset destroy %s' % set_name)()
cherrypy.log('destroyed unused ipset: %s' % set_name) cherrypy.log('destroyed unused ipset: %s' % set_name)
class SGAgent(object): class SGAgent(object):
def __init__(self): def __init__(self):
pass pass
def _self_list(self, obj): def _self_list(self, obj):
if isinstance(obj, types.ListType): if isinstance(obj, types.ListType):
return obj return obj
else: else:
return [obj] return [obj]
def set_rules(self, req): def set_rules(self, req):
body = req.body body = req.body
doc = xmlobject.loads(body) doc = xmlobject.loads(body)
vm_name = doc.vmName.text_ vm_name = doc.vmName.text_
vm_id = doc.vmId.text_ vm_id = doc.vmId.text_
vm_ip = doc.vmIp.text_ vm_ip = doc.vmIp.text_
vm_mac = doc.vmMac.text_ vm_mac = doc.vmMac.text_
sig = doc.signature.text_ sig = doc.signature.text_
seq = doc.sequenceNumber.text_ seq = doc.sequenceNumber.text_
def parse_rules(rules, lst): def parse_rules(rules, lst):
for i in self._self_list(rules): for i in self._self_list(rules):
r = SGRule() r = SGRule()
r.protocol = i.protocol.text_ r.protocol = i.protocol.text_
r.start_port = i.startPort.text_ r.start_port = i.startPort.text_
r.end_port = i.endPort.text_ r.end_port = i.endPort.text_
if hasattr(i, 'ip'): if hasattr(i, 'ip'):
for ip in self._self_list(i.ip): for ip in self._self_list(i.ip):
r.allowed_ips.append(ip.text_) r.allowed_ips.append(ip.text_)
lst.append(r) lst.append(r)
i_rules = [] i_rules = []
if hasattr(doc, 'ingressRules'): if hasattr(doc, 'ingressRules'):
parse_rules(doc.ingressRules, i_rules) parse_rules(doc.ingressRules, i_rules)
e_rules = [] e_rules = []
if hasattr(doc, 'egressRules'): if hasattr(doc, 'egressRules'):
parse_rules(doc.egressRules, e_rules) parse_rules(doc.egressRules, e_rules)
def create_chain(name): def create_chain(name):
try: try:
sglib.ShellCmd('iptables -F %s' % name)() sglib.ShellCmd('iptables -F %s' % name)()
except Exception: except Exception:
sglib.ShellCmd('iptables -N %s' % name)() sglib.ShellCmd('iptables -N %s' % name)()
def apply_rules(rules, chainname, direction, action, current_set_names): def apply_rules(rules, chainname, direction, action, current_set_names):
create_chain(chainname) create_chain(chainname)
for r in i_rules: for r in i_rules:
allow_any = False allow_any = False
if '0.0.0.0/0' in r.allowed_ips: if '0.0.0.0/0' in r.allowed_ips:
allow_any = True allow_any = True
r.allowed_ips.remove('0.0.0.0/0') r.allowed_ips.remove('0.0.0.0/0')
if r.allowed_ips: if r.allowed_ips:
setname = '_'.join([chainname, r.protocol, r.start_port, r.end_port]) setname = '_'.join([chainname, r.protocol, r.start_port, r.end_port])
ipset = IPSet(setname, r.allowed_ips) ipset = IPSet(setname, r.allowed_ips)
ipset.create() ipset.create()
current_set_names.append(setname) current_set_names.append(setname)
if r.protocol == 'all': if r.protocol == 'all':
cmd = ['iptables -I', chainname, '-m state --state NEW -m set --set', setname, direction, '-j', action] cmd = ['iptables -I', chainname, '-m state --state NEW -m set --set', setname, direction, '-j', action]
sglib.ShellCmd(' '.join(cmd))() sglib.ShellCmd(' '.join(cmd))()
elif r.protocol != 'icmp': elif r.protocol != 'icmp':
port_range = ":".join([r.start_port, r.end_port]) 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] 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))() sglib.ShellCmd(' '.join(cmd))()
else: else:
port_range = "/".join([r.start_port, r.end_port]) port_range = "/".join([r.start_port, r.end_port])
if r.start_port == "-1": if r.start_port == "-1":
port_range = "any" port_range = "any"
cmd = ['iptables', '-I', i_chain_name, '-p', 'icmp', '--icmp-type', port_range, '-m set --set', setname, direction, '-j', action] cmd = ['iptables', '-I', i_chain_name, '-p', 'icmp', '--icmp-type', port_range, '-m set --set', setname, direction, '-j', action]
sglib.ShellCmd(' '.join(cmd))() sglib.ShellCmd(' '.join(cmd))()
if allow_any and r.protocol != 'all': if allow_any and r.protocol != 'all':
if r.protocol != 'icmp': if r.protocol != 'icmp':
port_range = ":".join([r.start_port, r.end_port]) 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] cmd = ['iptables', '-I', chainname, '-p', r.protocol, '-m', r.protocol, '--dport', port_range, '-m', 'state', '--state', 'NEW', '-j', action]
sglib.ShellCmd(' '.join(cmd))() sglib.ShellCmd(' '.join(cmd))()
else: else:
port_range = "/".join([r.start_port, r.end_port]) port_range = "/".join([r.start_port, r.end_port])
if r.start_port == "-1": if r.start_port == "-1":
port_range = "any" port_range = "any"
cmd = ['iptables', '-I', i_chain_name, '-p', 'icmp', '--icmp-type', port_range, '-j', action] cmd = ['iptables', '-I', i_chain_name, '-p', 'icmp', '--icmp-type', port_range, '-j', action]
sglib.ShellCmd(' '.join(cmd))() sglib.ShellCmd(' '.join(cmd))()
current_sets = [] current_sets = []
i_chain_name = vm_name + '-in' i_chain_name = vm_name + '-in'
apply_rules(i_rules, i_chain_name, 'src', 'ACCEPT', current_sets) apply_rules(i_rules, i_chain_name, 'src', 'ACCEPT', current_sets)
e_chain_name = vm_name + '-eg' e_chain_name = vm_name + '-eg'
apply_rules(e_rules, e_chain_name, 'dst', 'RETURN', current_sets) apply_rules(e_rules, e_chain_name, 'dst', 'RETURN', current_sets)
if e_rules: if e_rules:
sglib.ShellCmd('iptables -A %s -j RETURN' % e_chain_name) sglib.ShellCmd('iptables -A %s -j RETURN' % e_chain_name)
else: else:
sglib.ShellCmd('iptables -A %s -j DROP' % e_chain_name) sglib.ShellCmd('iptables -A %s -j DROP' % e_chain_name)
sglib.ShellCmd('iptables -A %s -j DROP' % i_chain_name) sglib.ShellCmd('iptables -A %s -j DROP' % i_chain_name)
IPSet.destroy_sets(current_sets) IPSet.destroy_sets(current_sets)
def echo(self, req): def echo(self, req):
cherrypy.log("echo: I am alive") cherrypy.log("echo: I am alive")
def index(self): def index(self):
req = sglib.Request.from_cherrypy_request(cherrypy.request) req = sglib.Request.from_cherrypy_request(cherrypy.request)
cmd_name = req.headers['command'] cmd_name = req.headers['command']
if not hasattr(self, cmd_name): if not hasattr(self, cmd_name):
raise ValueError("SecurityGroupAgent doesn't have a method called '%s'" % cmd_name) raise ValueError("SecurityGroupAgent doesn't have a method called '%s'" % cmd_name)
method = getattr(self, cmd_name) method = getattr(self, cmd_name)
return method(req) return method(req)
index.exposed = True index.exposed = True
@staticmethod @staticmethod
def start(): def start():
cherrypy.log.access_file = '/var/log/cs-securitygroup.log' cherrypy.log.access_file = '/var/log/cs-securitygroup.log'
cherrypy.log.error_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_host = '0.0.0.0'
cherrypy.server.socket_port = 9988 cherrypy.server.socket_port = 9988
cherrypy.quickstart(SGAgent()) cherrypy.quickstart(SGAgent())
@staticmethod @staticmethod
def stop(): def stop():
cherrypy.engine.exit() cherrypy.engine.exit()
PID_FILE = '/var/run/cssgagent.pid' PID_FILE = '/var/run/cssgagent.pid'
class SGAgentDaemon(sglib.Daemon): class SGAgentDaemon(sglib.Daemon):
def __init__(self): def __init__(self):
super(SGAgentDaemon, self).__init__(PID_FILE) super(SGAgentDaemon, self).__init__(PID_FILE)
self.is_stopped = False self.is_stopped = False
self.agent = SGAgent() self.agent = SGAgent()
sglib.Daemon.register_atexit_hook(self._do_stop) sglib.Daemon.register_atexit_hook(self._do_stop)
def _do_stop(self): def _do_stop(self):
if self.is_stopped: if self.is_stopped:
return return
self.is_stopped = True self.is_stopped = True
self.agent.stop() self.agent.stop()
def run(self): def run(self):
self.agent.start() self.agent.start()
def stop(self): def stop(self):
self.agent.stop() self.agent.stop()
super(SGAgentDaemon, self).stop() super(SGAgentDaemon, self).stop()
def main(): def main():
usage = 'usage: python -c "from security_group_agent import cs_sg_agent; cs_sg_agent.main()" start|stop|restart' 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']: if len(sys.argv) != 2 or not sys.argv[1] in ['start', 'stop', 'restart']:
print usage print usage
sys.exit(1) sys.exit(1)
cmd = sys.argv[1] cmd = sys.argv[1]
agentdaemon = SGAgentDaemon() agentdaemon = SGAgentDaemon()
if cmd == 'start': if cmd == 'start':
agentdaemon.start() agentdaemon.start()
elif cmd == 'stop': elif cmd == 'stop':
agentdaemon.stop() agentdaemon.stop()
else: else:
agentdaemon.restart() agentdaemon.restart()
sys.exit(0) sys.exit(0)

View File

@ -1,97 +1,97 @@
# Licensed to the Apache Software Foundation (ASF) under one # Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file # or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information # distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file # regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the # to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance # "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at # with the License. You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, # Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an # software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the # KIND, either express or implied. See the License for the
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
# #
# Automatically generated by addcopyright.py at 01/29/2013 # Automatically generated by addcopyright.py at 01/29/2013
''' '''
Created on Dec 25, 2012 Created on Dec 25, 2012
@author: Frank @author: Frank
''' '''
import xml.etree.ElementTree as etree import xml.etree.ElementTree as etree
import re import re
import types import types
class XmlObject(object): class XmlObject(object):
def __init__(self, tag): def __init__(self, tag):
self.__tag_name__ = tag self.__tag_name__ = tag
def put_attr(self, name, val): def put_attr(self, name, val):
val = val.strip().strip('\t') val = val.strip().strip('\t')
setattr(self, name + '_', val) setattr(self, name + '_', val)
def put_text(self, val): def put_text(self, val):
val = val.strip().strip('\n').strip('\t') val = val.strip().strip('\n').strip('\t')
if val == "": if val == "":
setattr(self, 'text_', None) setattr(self, 'text_', None)
else: else:
setattr(self, 'text_', val) setattr(self, 'text_', val)
def put_node(self, name, val): def put_node(self, name, val):
if not hasattr(self, name): if not hasattr(self, name):
setattr(self, name, val) setattr(self, name, val)
return return
nodes = getattr(self, name) nodes = getattr(self, name)
if not isinstance(nodes, types.ListType): if not isinstance(nodes, types.ListType):
nodes = [] nodes = []
old = getattr(self, name) old = getattr(self, name)
nodes.append(old) nodes.append(old)
nodes.append(val) nodes.append(val)
setattr(self, name, nodes) setattr(self, name, nodes)
else: else:
nodes.append(val) nodes.append(val)
setattr(self, name, nodes) setattr(self, name, nodes)
def get(self, name, default=None): def get(self, name, default=None):
if hasattr(self, name): if hasattr(self, name):
val = getattr(self, name) val = getattr(self, name)
if name.endswith('_'): if name.endswith('_'):
return val return val
else: else:
return val.text_ return val.text_
else: else:
return default return default
def __getattr__(self, name): def __getattr__(self, name):
if name.endswith('__'): if name.endswith('__'):
n = name[:-1] n = name[:-1]
if hasattr(self, n): if hasattr(self, n):
return getattr(self, n) return getattr(self, n)
else: else:
return None return None
else: else:
e = AttributeError('%s has no attribute %s. missing attribute %s in element <%s>' % (self.__class__.__name__, name, name, self.__tag_name__)) 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, 'missing_attrib', name)
setattr(e, 'tag_name', self.__tag_name__) setattr(e, 'tag_name', self.__tag_name__)
raise e raise e
def _loads(node): def _loads(node):
xo = XmlObject(node.tag) xo = XmlObject(node.tag)
for key in node.attrib.keys(): for key in node.attrib.keys():
xo.put_attr(key, node.attrib.get(key)) xo.put_attr(key, node.attrib.get(key))
if node.text: if node.text:
xo.put_text(node.text) xo.put_text(node.text)
for n in list(node): for n in list(node):
sub_xo = _loads(n) sub_xo = _loads(n)
xo.put_node(n.tag, sub_xo) xo.put_node(n.tag, sub_xo)
return xo return xo
def loads(xmlstr): def loads(xmlstr):
xmlstr = re.sub(r'xmlns=".*"', '', xmlstr) xmlstr = re.sub(r'xmlns=".*"', '', xmlstr)
root = etree.fromstring(xmlstr) root = etree.fromstring(xmlstr)
return _loads(root) return _loads(root)

View File

@ -1,200 +1,200 @@
# Licensed to the Apache Software Foundation (ASF) under one # Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file # or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information # distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file # regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the # to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance # "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at # with the License. You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, # Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an # software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the # KIND, either express or implied. See the License for the
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
""" BVT tests for Hosts Test """ BVT tests for Hosts Test
""" """
# Import Local Modules # Import Local Modules
from marvin.codes import FAILED from marvin.codes import FAILED
from marvin.cloudstackTestCase import * from marvin.cloudstackTestCase import *
from marvin.cloudstackAPI import * from marvin.cloudstackAPI import *
from marvin.lib.utils import * from marvin.lib.utils import *
from marvin.lib.base import * from marvin.lib.base import *
from marvin.lib.common import * from marvin.lib.common import *
from nose.plugins.attrib import attr from nose.plugins.attrib import attr
from marvin.sshClient import SshClient from marvin.sshClient import SshClient
import time import time
from time import sleep from time import sleep
_multiprocess_shared_ = False _multiprocess_shared_ = False
class TestHostHA(cloudstackTestCase): class TestHostHA(cloudstackTestCase):
def setUp(self): def setUp(self):
self.logger = logging.getLogger('TestHM') self.logger = logging.getLogger('TestHM')
self.stream_handler = logging.StreamHandler() self.stream_handler = logging.StreamHandler()
self.logger.setLevel(logging.DEBUG) self.logger.setLevel(logging.DEBUG)
self.logger.addHandler(self.stream_handler) self.logger.addHandler(self.stream_handler)
self.apiclient = self.testClient.getApiClient() self.apiclient = self.testClient.getApiClient()
self.hypervisor = self.testClient.getHypervisorInfo() self.hypervisor = self.testClient.getHypervisorInfo()
self.mgtSvrDetails = self.config.__dict__["mgtSvr"][0].__dict__ self.mgtSvrDetails = self.config.__dict__["mgtSvr"][0].__dict__
self.dbclient = self.testClient.getDbConnection() self.dbclient = self.testClient.getDbConnection()
self.services = self.testClient.getParsedTestDataConfig() self.services = self.testClient.getParsedTestDataConfig()
self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests()) self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests())
self.pod = get_pod(self.apiclient, self.zone.id) self.pod = get_pod(self.apiclient, self.zone.id)
self.cleanup = [] self.cleanup = []
self.services = { self.services = {
"service_offering": { "service_offering": {
"name": "Ultra Tiny Instance", "name": "Ultra Tiny Instance",
"displaytext": "Ultra Tiny Instance", "displaytext": "Ultra Tiny Instance",
"cpunumber": 1, "cpunumber": 1,
"cpuspeed": 100, "cpuspeed": 100,
"memory": 128, "memory": 128,
}, },
"service_offering_local": { "service_offering_local": {
"name": "Ultra Tiny Local Instance", "name": "Ultra Tiny Local Instance",
"displaytext": "Ultra Tiny Local Instance", "displaytext": "Ultra Tiny Local Instance",
"cpunumber": 1, "cpunumber": 1,
"cpuspeed": 100, "cpuspeed": 100,
"memory": 128, "memory": 128,
"storagetype": "local" "storagetype": "local"
}, },
"vm": { "vm": {
"username": "root", "username": "root",
"password": "password", "password": "password",
"ssh_port": 22, "ssh_port": 22,
# Hypervisor type should be same as # Hypervisor type should be same as
# hypervisor type of cluster # hypervisor type of cluster
"privateport": 22, "privateport": 22,
"publicport": 22, "publicport": 22,
"protocol": 'TCP', "protocol": 'TCP',
}, },
"natrule": { "natrule": {
"privateport": 22, "privateport": 22,
"publicport": 22, "publicport": 22,
"startport": 22, "startport": 22,
"endport": 22, "endport": 22,
"protocol": "TCP", "protocol": "TCP",
"cidrlist": '0.0.0.0/0', "cidrlist": '0.0.0.0/0',
}, },
"ostype": 'CentOS 5.3 (64-bit)', "ostype": 'CentOS 5.3 (64-bit)',
"sleep": 60, "sleep": 60,
"timeout": 10, "timeout": 10,
} }
def tearDown(self): def tearDown(self):
try: try:
# Clean up, terminate the created templates # Clean up, terminate the created templates
cleanup_resources(self.apiclient, self.cleanup) cleanup_resources(self.apiclient, self.cleanup)
except Exception as e: except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e) raise Exception("Warning: Exception during cleanup : %s" % e)
return return
def checkHostDown(self, fromHostIp, testHostIp): def checkHostDown(self, fromHostIp, testHostIp):
try: try:
ssh = SshClient(fromHostIp, 22, "root", "password") ssh = SshClient(fromHostIp, 22, "root", "password")
res = ssh.execute("ping -c 1 %s" % testHostIp) res = ssh.execute("ping -c 1 %s" % testHostIp)
result = str(res) result = str(res)
if result.count("100% packet loss") == 1: if result.count("100% packet loss") == 1:
return True, 1 return True, 1
else: else:
return False, 1 return False, 1
except Exception as e: except Exception as e:
self.logger.debug("Got exception %s" % e) self.logger.debug("Got exception %s" % e)
return False, 1 return False, 1
def checkHostUp(self, fromHostIp, testHostIp): def checkHostUp(self, fromHostIp, testHostIp):
try: try:
ssh = SshClient(fromHostIp, 22, "root", "password") ssh = SshClient(fromHostIp, 22, "root", "password")
res = ssh.execute("ping -c 1 %s" % testHostIp) res = ssh.execute("ping -c 1 %s" % testHostIp)
result = str(res) result = str(res)
if result.count(" 0% packet loss") == 1: if result.count(" 0% packet loss") == 1:
return True, 1 return True, 1
else: else:
return False, 1 return False, 1
except Exception as e: except Exception as e:
self.logger.debug("Got exception %s" % e) self.logger.debug("Got exception %s" % e)
return False, 1 return False, 1
def checkHostStateInCloudstack(self, state, hostId): def checkHostStateInCloudstack(self, state, hostId):
try: try:
listHost = Host.list( listHost = Host.list(
self.apiclient, self.apiclient,
type='Routing', type='Routing',
zoneid=self.zone.id, zoneid=self.zone.id,
podid=self.pod.id, podid=self.pod.id,
id=hostId id=hostId
) )
self.assertEqual( self.assertEqual(
isinstance(listHost, list), isinstance(listHost, list),
True, True,
"Check if listHost returns a valid response" "Check if listHost returns a valid response"
) )
self.assertEqual( self.assertEqual(
len(listHost), len(listHost),
1, 1,
"Check if listHost returns a host" "Check if listHost returns a host"
) )
self.logger.debug(" Host state is %s " % listHost[0].state) self.logger.debug(" Host state is %s " % listHost[0].state)
if listHost[0].state == state: if listHost[0].state == state:
return True, 1 return True, 1
else: else:
return False, 1 return False, 1
except Exception as e: except Exception as e:
self.logger.debug("Got exception %s" % e) self.logger.debug("Got exception %s" % e)
return False, 1 return False, 1
def updateConfigurAndRestart(self, name, value): def updateConfigurAndRestart(self, name, value):
Configurations.update(self.apiclient, name, value) Configurations.update(self.apiclient, name, value)
self.RestartServers() self.RestartServers()
time.sleep(self.services["sleep"]) time.sleep(self.services["sleep"])
def RestartServers(self): def RestartServers(self):
""" Restart management """ Restart management
server and usage server """ server and usage server """
sshClient = SshClient(self.mgtSvrDetails["mgtSvrIp"], sshClient = SshClient(self.mgtSvrDetails["mgtSvrIp"],
22, 22,
self.mgtSvrDetails["user"], self.mgtSvrDetails["user"],
self.mgtSvrDetails["passwd"] self.mgtSvrDetails["passwd"]
) )
command = "service cloudstack-management restart" command = "service cloudstack-management restart"
sshClient.execute(command) sshClient.execute(command)
return return
@attr( @attr(
tags=[ tags=[
"advanced", "advanced",
"advancedns", "advancedns",
"smoke", "smoke",
"basic", "basic",
"eip", "eip",
"sg"], "sg"],
required_hardware="true") required_hardware="true")
def test_01_host_ha_with_nfs_storagepool_with_vm(self): def test_01_host_ha_with_nfs_storagepool_with_vm(self):
Configurations.update(self.apiclient, "ping.timeout", "150") Configurations.update(self.apiclient, "ping.timeout", "150")
self.updateConfigurAndRestart("ping.interval", "150") self.updateConfigurAndRestart("ping.interval", "150")
listHost = Host.list( listHost = Host.list(
self.apiclient, self.apiclient,
type='Routing', type='Routing',
zoneid=self.zone.id, zoneid=self.zone.id,
podid=self.pod.id, podid=self.pod.id,
) )
for host in listHost: for host in listHost:
self.logger.debug('Hypervisor = {}'.format(host.id)) self.logger.debug('Hypervisor = {}'.format(host.id))
hostToTest = listHost[0] hostToTest = listHost[0]
hostUpInCloudstack = wait_until(40, 10, self.checkHostStateInCloudstack, "Up", hostToTest.id) hostUpInCloudstack = wait_until(40, 10, self.checkHostStateInCloudstack, "Up", hostToTest.id)
if not(hostUpInCloudstack): if not(hostUpInCloudstack):
raise self.fail("Host is not up %s, in cloudstack so failing test " % (hostToTest.ipaddress)) raise self.fail("Host is not up %s, in cloudstack so failing test " % (hostToTest.ipaddress))
return return

View File

@ -1,217 +1,217 @@
# Licensed to the Apache Software Foundation (ASF) under one # Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file # or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information # distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file # regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the # to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance # "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at # with the License. You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, # Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an # software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the # KIND, either express or implied. See the License for the
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
from marvin.cloudstackTestCase import cloudstackTestCase from marvin.cloudstackTestCase import cloudstackTestCase
from marvin.lib.base import * from marvin.lib.base import *
from marvin.lib.common import get_zone, get_domain, get_template from marvin.lib.common import get_zone, get_domain, get_template
from marvin.lib.utils import cleanup_resources from marvin.lib.utils import cleanup_resources
class Services: class Services:
"""Test multi tag support in compute offerings """Test multi tag support in compute offerings
""" """
def __init__(self): def __init__(self):
self.services = { self.services = {
"account": { "account": {
"email": "john@doe.de", "email": "john@doe.de",
"firstname": "Test", "firstname": "Test",
"lastname": "User", "lastname": "User",
"username": "test", "username": "test",
# Random characters are appended for unique # Random characters are appended for unique
# username # username
"password": "password", "password": "password",
}, },
"service_offering_0": { "service_offering_0": {
"name": "NoTag", "name": "NoTag",
"displaytext": "NoTag", "displaytext": "NoTag",
"cpunumber": 1, "cpunumber": 1,
"cpuspeed": 100, "cpuspeed": 100,
# in MHz # in MHz
"memory": 128, "memory": 128,
# In MBs # In MBs
}, },
"service_offering_1": { "service_offering_1": {
"name": "OneTag", "name": "OneTag",
"displaytext": "OneTag", "displaytext": "OneTag",
"cpunumber": 1, "cpunumber": 1,
"cpuspeed": 100, "cpuspeed": 100,
"hosttags": "tag1", "hosttags": "tag1",
# in MHz # in MHz
"memory": 128, "memory": 128,
# In MBs # In MBs
}, },
"service_offering_2": { "service_offering_2": {
"name": "TwoTag", "name": "TwoTag",
"displaytext": "TwoTag", "displaytext": "TwoTag",
"cpunumber": 1, "cpunumber": 1,
"cpuspeed": 100, "cpuspeed": 100,
"hosttags": "tag2,tag1", "hosttags": "tag2,tag1",
# in MHz # in MHz
"memory": 128, "memory": 128,
# In MBs # In MBs
}, },
"service_offering_not_existing_tag": { "service_offering_not_existing_tag": {
"name": "NotExistingTag", "name": "NotExistingTag",
"displaytext": "NotExistingTag", "displaytext": "NotExistingTag",
"cpunumber": 1, "cpunumber": 1,
"cpuspeed": 100, "cpuspeed": 100,
"hosttags": "tagX", "hosttags": "tagX",
# in MHz # in MHz
"memory": 128, "memory": 128,
# In MBs # In MBs
}, },
"virtual_machine": { "virtual_machine": {
"name": "TestVM", "name": "TestVM",
"displayname": "TestVM" "displayname": "TestVM"
}, },
"template": { "template": {
"displaytext": "Ubuntu", "displaytext": "Ubuntu",
"name": "Ubuntu16 x64", "name": "Ubuntu16 x64",
"ostype": 'Ubuntu 16.04 (64-bit)', "ostype": 'Ubuntu 16.04 (64-bit)',
"templatefilter": 'self', "templatefilter": 'self',
}, },
"network": { "network": {
"name": "Guest", "name": "Guest",
}, },
"host": { "host": {
"name": "" "name": ""
} }
} }
class TestMultiTagSupport(cloudstackTestCase): class TestMultiTagSupport(cloudstackTestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
cls.testClient = super(TestMultiTagSupport, cls).getClsTestClient() cls.testClient = super(TestMultiTagSupport, cls).getClsTestClient()
cls.hypervisor = cls.testClient.getHypervisorInfo() cls.hypervisor = cls.testClient.getHypervisorInfo()
cls.api_client = cls.testClient.getApiClient() cls.api_client = cls.testClient.getApiClient()
cls.services = Services().services cls.services = Services().services
cls.zone = get_zone(cls.api_client) cls.zone = get_zone(cls.api_client)
cls.domain = get_domain(cls.api_client) cls.domain = get_domain(cls.api_client)
cls.network = cls.get_network() cls.network = cls.get_network()
cls.host = cls.get_host() cls.host = cls.get_host()
cls.host_tags = cls.host["hosttags"] cls.host_tags = cls.host["hosttags"]
cls.template = get_template( cls.template = get_template(
cls.api_client, cls.api_client,
cls.zone.id, cls.zone.id,
cls.services["template"]["ostype"] cls.services["template"]["ostype"]
) )
cls.service_offering_list = [] cls.service_offering_list = []
for x in range(0, 3): for x in range(0, 3):
cls.service_offering_list.append(ServiceOffering.create( cls.service_offering_list.append(ServiceOffering.create(
cls.api_client, cls.api_client,
cls.services["service_offering_" + str(x)] cls.services["service_offering_" + str(x)]
)) ))
cls.service_offering_ne_tag = ServiceOffering.create( cls.service_offering_ne_tag = ServiceOffering.create(
cls.api_client, cls.api_client,
cls.services["service_offering_not_existing_tag"] cls.services["service_offering_not_existing_tag"]
) )
cls.account = Account.create( cls.account = Account.create(
cls.api_client, cls.api_client,
cls.services["account"], cls.services["account"],
admin=True, admin=True,
) )
cls._cleanup = [ cls._cleanup = [
cls.account, cls.account,
cls.service_offering_ne_tag, cls.service_offering_ne_tag,
] + cls.service_offering_list ] + cls.service_offering_list
@classmethod @classmethod
def tearDownClass(cls): def tearDownClass(cls):
try: try:
# Cleanup resources used # Cleanup resources used
print("Cleanup resources used") print("Cleanup resources used")
Host.update(cls.api_client, id=cls.host["id"], hosttags=cls.host_tags) Host.update(cls.api_client, id=cls.host["id"], hosttags=cls.host_tags)
cleanup_resources(cls.api_client, cls._cleanup) cleanup_resources(cls.api_client, cls._cleanup)
except Exception as e: except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e) raise Exception("Warning: Exception during cleanup : %s" % e)
return return
def test_multi_tags(self): def test_multi_tags(self):
for x in range(0, len(self.service_offering_list)): for x in range(0, len(self.service_offering_list)):
if hasattr(self.service_offering_list[x], 'hosttags'): if hasattr(self.service_offering_list[x], 'hosttags'):
Host.update(self.api_client, id=self.host["id"], hosttags=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( vm = VirtualMachine.create(
self.api_client, self.api_client,
self.services["virtual_machine"], self.services["virtual_machine"],
accountid=self.account.name, accountid=self.account.name,
domainid=self.account.domainid, domainid=self.account.domainid,
zoneid=self.zone.id, zoneid=self.zone.id,
serviceofferingid=self.service_offering_list[x].id, serviceofferingid=self.service_offering_list[x].id,
templateid=self.template.id, templateid=self.template.id,
networkids=self.network.id networkids=self.network.id
) )
self.assertEqual( self.assertEqual(
isinstance(vm, VirtualMachine), isinstance(vm, VirtualMachine),
True, True,
"VM %s should be created with service offering %s " % "VM %s should be created with service offering %s " %
(self.services["virtual_machine"]["name"], self.service_offering_list[x].name)) (self.services["virtual_machine"]["name"], self.service_offering_list[x].name))
vm.delete(self.api_client, True) vm.delete(self.api_client, True)
def test_no_existing_tag(self): def test_no_existing_tag(self):
with self.assertRaises(Exception): with self.assertRaises(Exception):
VirtualMachine.create( VirtualMachine.create(
self.api_client, self.api_client,
self.services["virtual_machine"], self.services["virtual_machine"],
accountid=self.account.name, accountid=self.account.name,
domainid=self.account.domainid, domainid=self.account.domainid,
zoneid=self.zone.id, zoneid=self.zone.id,
serviceofferingid=self.service_offering_ne_tag.id, serviceofferingid=self.service_offering_ne_tag.id,
templateid=self.template.id, templateid=self.template.id,
networkids=self.network.id networkids=self.network.id
) )
return return
@classmethod @classmethod
def get_network(cls): def get_network(cls):
networks = Network.list(cls.api_client, zoneid=cls.zone.id) networks = Network.list(cls.api_client, zoneid=cls.zone.id)
if len(networks) == 1: if len(networks) == 1:
return networks[0] return networks[0]
if len(networks) > 1: if len(networks) > 1:
for network in networks: for network in networks:
if network.name == cls.services["network"]["name"]: if network.name == cls.services["network"]["name"]:
return network return network
raise ValueError("No suitable network found, check network name in service object") 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) raise ValueError("No network found for zone with id %s" % cls.zone.id)
@classmethod @classmethod
def get_host(cls): def get_host(cls):
hosts = Host.list(cls.api_client, zoneid=cls.zone.id) hosts = Host.list(cls.api_client, zoneid=cls.zone.id)
if len(hosts) == 1: if len(hosts) == 1:
return hosts[0] return hosts[0]
if len(hosts) > 1: if len(hosts) > 1:
for host in hosts: for host in hosts:
if host.name == cls.services["host"]["name"]: if host.name == cls.services["host"]["name"]:
return host return host
raise ValueError("No suitable host found, check host name in service object") 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) raise ValueError("No host found for zone with id %s" % cls.zone.id)

View File

@ -1,269 +1,269 @@
# Licensed to the Apache Software Foundation (ASF) under one # Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file # or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information # distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file # regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the # to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance # "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at # with the License. You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, # Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an # software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the # KIND, either express or implied. See the License for the
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
""" """
BVT tests for NCC integration with cloudstack BVT tests for NCC integration with cloudstack
""" """
#Import Local Modules #Import Local Modules
from marvin.cloudstackTestCase import cloudstackTestCase from marvin.cloudstackTestCase import cloudstackTestCase
from marvin.lib.common import get_domain, get_zone, get_template from marvin.lib.common import get_domain, get_zone, get_template
from marvin.lib import ncc from marvin.lib import ncc
from marvin.lib.base import (Account, from marvin.lib.base import (Account,
VirtualMachine, VirtualMachine,
PublicIPAddress, PublicIPAddress,
LoadBalancerRule, LoadBalancerRule,
ServiceOffering, ServiceOffering,
NetworkOffering, NetworkOffering,
Network, Network,
NATRule, NATRule,
PhysicalNetwork, PhysicalNetwork,
NetworkServiceProvider, NetworkServiceProvider,
RegisteredServicePackage) RegisteredServicePackage)
from marvin.lib.utils import cleanup_resources from marvin.lib.utils import cleanup_resources
from nose.plugins.attrib import attr from nose.plugins.attrib import attr
import logging import logging
class TestNccIntegrationDedicated(cloudstackTestCase): class TestNccIntegrationDedicated(cloudstackTestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
cls.testClient = super(TestNccIntegrationDedicated, cls).getClsTestClient() cls.testClient = super(TestNccIntegrationDedicated, cls).getClsTestClient()
cls.api_client = cls.testClient.getApiClient() cls.api_client = cls.testClient.getApiClient()
cls.services = cls.testClient.getParsedTestDataConfig() cls.services = cls.testClient.getParsedTestDataConfig()
cls._cleanup = [] cls._cleanup = []
cls.logger = logging.getLogger('TestNccIntegrationDedicated') cls.logger = logging.getLogger('TestNccIntegrationDedicated')
cls.stream_handler = logging.StreamHandler() cls.stream_handler = logging.StreamHandler()
cls.logger.setLevel(logging.DEBUG) cls.logger.setLevel(logging.DEBUG)
cls.logger.addHandler(cls.stream_handler) cls.logger.addHandler(cls.stream_handler)
# Get Zone, Domain and templates # Get Zone, Domain and templates
cls.domain = get_domain(cls.api_client) cls.domain = get_domain(cls.api_client)
cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
cls.services['mode'] = cls.zone.networktype cls.services['mode'] = cls.zone.networktype
cls.template = get_template( cls.template = get_template(
cls.api_client, cls.api_client,
cls.zone.id, cls.zone.id,
cls.services["ostype"] ) cls.services["ostype"] )
ncc_ip = cls.services["NCC"]["NCCIP"] ncc_ip = cls.services["NCC"]["NCCIP"]
ns_ip = cls.services["NSDedicated"]["NSIP"] ns_ip = cls.services["NSDedicated"]["NSIP"]
cls.debug("NS IP - Dedicated: %s" % ns_ip) cls.debug("NS IP - Dedicated: %s" % ns_ip)
mgmt_srv_ip = cls.config.__dict__["mgtSvr"][0].__dict__["mgtSvrIp"] mgmt_srv_ip = cls.config.__dict__["mgtSvr"][0].__dict__["mgtSvrIp"]
#ncc_ip = "10.102.195.215" #ncc_ip = "10.102.195.215"
#ns_ip = "10.102.195.210" #ns_ip = "10.102.195.210"
cls.ns = ncc.NCC(ncc_ip, ns_ip, mgmt_srv_ip, logger=cls.logger) cls.ns = ncc.NCC(ncc_ip, ns_ip, mgmt_srv_ip, logger=cls.logger)
cls.ns.registerCCP(cls.api_client) cls.ns.registerCCP(cls.api_client)
cls.ns.registerNS() cls.ns.registerNS()
cls.ns.assignNStoCSZone() cls.ns.assignNStoCSZone()
spname = cls.services["servicepackage_dedicated"]["name"] spname = cls.services["servicepackage_dedicated"]["name"]
# Create Service package and get device group id, tenant group id and service package id # Create Service package and get device group id, tenant group id and service package id
# These would be needed later for clean up # These would be needed later for clean up
(cls.dv_group_id, cls.tnt_group_id, cls.srv_pkg_id) = cls.ns.createServicePackages( (cls.dv_group_id, cls.tnt_group_id, cls.srv_pkg_id) = cls.ns.createServicePackages(
spname, spname,
"NetScalerVPX", "NetScalerVPX",
ns_ip, ns_ip,
isolation_policy="dedicated") isolation_policy="dedicated")
cls.debug("Created service package in NCC") 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)) 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) srv_pkg_list = RegisteredServicePackage.list(cls.api_client)
# Choose the one created # Choose the one created
cls.srv_pkg_uuid = None cls.srv_pkg_uuid = None
for sp in srv_pkg_list: for sp in srv_pkg_list:
if sp.name == spname: if sp.name == spname:
cls.srv_pkg_uuid = sp.id cls.srv_pkg_uuid = sp.id
#srv_pkg_id = srv_pkg_list[0].id #srv_pkg_id = srv_pkg_list[0].id
cls.account = Account.create( cls.account = Account.create(
cls.api_client, cls.api_client,
cls.services["account"] cls.services["account"]
) )
cls._cleanup.append(cls.account) cls._cleanup.append(cls.account)
try: try:
cls.services["nw_off_ncc_DedicatedSP"]["servicepackageuuid"] = cls.srv_pkg_uuid 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.services["nw_off_ncc_DedicatedSP"]["servicepackagedescription"] = "A NetScalerVPX is dedicated per network."
cls.network_offering = NetworkOffering.create( cls.network_offering = NetworkOffering.create(
cls.api_client, cls.api_client,
cls.services["nw_off_ncc_DedicatedSP"]) cls.services["nw_off_ncc_DedicatedSP"])
except Exception as e: except Exception as e:
raise Exception ("Unable to create network offering with Service package % s due to exception % s" raise Exception ("Unable to create network offering with Service package % s due to exception % s"
% (cls.srv_pkg_uuid, e)) % (cls.srv_pkg_uuid, e))
# Network offering should be removed so that service package may be deleted later # Network offering should be removed so that service package may be deleted later
cls._cleanup.append(cls.network_offering) cls._cleanup.append(cls.network_offering)
cls.network_offering.update(cls.api_client, state = "Enabled") cls.network_offering.update(cls.api_client, state = "Enabled")
cls.service_offering = ServiceOffering.create( cls.service_offering = ServiceOffering.create(
cls.api_client, cls.api_client,
cls.services["service_offering"] cls.services["service_offering"]
) )
cls.services["small"]["template"] = cls.template.id cls.services["small"]["template"] = cls.template.id
# Enable Netscaler Service Provider # Enable Netscaler Service Provider
cls.phy_nws = PhysicalNetwork.list(cls.api_client,zoneid=cls.zone.id) cls.phy_nws = PhysicalNetwork.list(cls.api_client,zoneid=cls.zone.id)
if isinstance(cls.phy_nws, list): if isinstance(cls.phy_nws, list):
physical_network = cls.phy_nws[0] physical_network = cls.phy_nws[0]
try: try:
cls.ns_service_provider = NetworkServiceProvider.list(cls.api_client,name='Netscaler') cls.ns_service_provider = NetworkServiceProvider.list(cls.api_client,name='Netscaler')
if isinstance(cls.ns_service_provider, list): if isinstance(cls.ns_service_provider, list):
ns_provider = cls.ns_service_provider[0] ns_provider = cls.ns_service_provider[0]
except: except:
raise Exception ("Netscaler service provider not found!!") raise Exception ("Netscaler service provider not found!!")
try: try:
if ns_provider.state != "Enabled": if ns_provider.state != "Enabled":
NetworkServiceProvider.update(cls.api_client, id=ns_provider.id, physicalnetworkid=physical_network.id, state="Enabled") NetworkServiceProvider.update(cls.api_client, id=ns_provider.id, physicalnetworkid=physical_network.id, state="Enabled")
except: except:
raise Exception ("Enabling Netscaler Service provider failed. Unable to proceed") raise Exception ("Enabling Netscaler Service provider failed. Unable to proceed")
return return
@classmethod @classmethod
def tearDownClass(cls): def tearDownClass(cls):
try: try:
# Cleanup resources used # Cleanup resources used
cleanup_resources(cls.api_client, cls._cleanup) cleanup_resources(cls.api_client, cls._cleanup)
except Exception as e: except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % 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) cls.ns.cleanup_ncc(cls.dv_group_id, cls.srv_pkg_uuid, cls.srv_pkg_id, cls.tnt_group_id)
return return
def setUp(self): def setUp(self):
self.apiclient = self.testClient.getApiClient() self.apiclient = self.testClient.getApiClient()
return return
def tearDown(self): def tearDown(self):
return return
@attr(tags=["ncc"], required_hardware="true") @attr(tags=["ncc"], required_hardware="true")
def test_01_dedicated_first_network(self): def test_01_dedicated_first_network(self):
# Create network # Create network
self.debug("Creating network with network offering: %s" % self.network_offering.id) self.debug("Creating network with network offering: %s" % self.network_offering.id)
self.network = Network.create( self.network = Network.create(
self.apiclient, self.apiclient,
self.services["network"], self.services["network"],
accountid=self.account.name, accountid=self.account.name,
domainid=self.account.domainid, domainid=self.account.domainid,
networkofferingid=self.network_offering.id, networkofferingid=self.network_offering.id,
zoneid=self.zone.id zoneid=self.zone.id
) )
self.debug("Created network: %s" % self.network.id) self.debug("Created network: %s" % self.network.id)
self.debug("Trying VM deploy with network created on account: %s" % self.account.name) self.debug("Trying VM deploy with network created on account: %s" % self.account.name)
self.virtual_machine = VirtualMachine.create( self.virtual_machine = VirtualMachine.create(
self.apiclient, self.apiclient,
self.services["small"], self.services["small"],
accountid=self.account.name, accountid=self.account.name,
domainid=self.account.domainid, domainid=self.account.domainid,
zoneid=self.zone.id, zoneid=self.zone.id,
networkids=self.network.id, networkids=self.network.id,
serviceofferingid=self.service_offering.id serviceofferingid=self.service_offering.id
) )
self.debug("Deployed VM in network: %s" % self.network.id) self.debug("Deployed VM in network: %s" % self.network.id)
list_vm_response = VirtualMachine.list( list_vm_response = VirtualMachine.list(
self.apiclient, self.apiclient,
id=self.virtual_machine.id id=self.virtual_machine.id
) )
self.debug( self.debug(
"Verify listVirtualMachines response for virtual machine: %s" "Verify listVirtualMachines response for virtual machine: %s"
% self.virtual_machine.id % self.virtual_machine.id
) )
self.assertEqual( self.assertEqual(
isinstance(list_vm_response, list), isinstance(list_vm_response, list),
True, True,
"Check list response returns a valid list") "Check list response returns a valid list")
vm_response = list_vm_response[0] vm_response = list_vm_response[0]
self.assertEqual( self.assertEqual(
vm_response.state, vm_response.state,
"Running", "Running",
"VM state should be running after deployment" "VM state should be running after deployment"
) )
self.debug("Aquiring public IP for network: %s" % self.network.id) self.debug("Aquiring public IP for network: %s" % self.network.id)
ip_with_lb_rule = PublicIPAddress.create( ip_with_lb_rule = PublicIPAddress.create(
self.apiclient, self.apiclient,
accountid=self.account.name, accountid=self.account.name,
zoneid=self.zone.id, zoneid=self.zone.id,
domainid=self.account.domainid, domainid=self.account.domainid,
networkid=self.network.id) networkid=self.network.id)
self.debug( self.debug(
"Creating LB rule for IP address: %s with round robin algo" % "Creating LB rule for IP address: %s with round robin algo" %
ip_with_lb_rule.ipaddress.ipaddress) ip_with_lb_rule.ipaddress.ipaddress)
self.services["lbrule"]["alg"] = 'roundrobin' self.services["lbrule"]["alg"] = 'roundrobin'
lb_rule = LoadBalancerRule.create( lb_rule = LoadBalancerRule.create(
self.apiclient, self.apiclient,
self.services["lbrule"], self.services["lbrule"],
ipaddressid=ip_with_lb_rule.ipaddress.id, ipaddressid=ip_with_lb_rule.ipaddress.id,
accountid=self.account.name, accountid=self.account.name,
networkid=self.network.id networkid=self.network.id
) )
lb_rules = LoadBalancerRule.list( lb_rules = LoadBalancerRule.list(
self.apiclient, self.apiclient,
id=lb_rule.id, id=lb_rule.id,
listall=True listall=True
) )
self.assertEqual( self.assertEqual(
isinstance(lb_rules, list), isinstance(lb_rules, list),
True, True,
"List LB rules should return a newly created LB rule" "List LB rules should return a newly created LB rule"
) )
self.debug("Adding %s to the LB rule %s" % ( self.debug("Adding %s to the LB rule %s" % (
self.virtual_machine.name, self.virtual_machine.name,
lb_rule.name lb_rule.name
)) ))
lb_rule.assign(self.apiclient, [self.virtual_machine]) lb_rule.assign(self.apiclient, [self.virtual_machine])
@attr(tags=["ncc"], required_hardware="true") @attr(tags=["ncc"], required_hardware="true")
def test_02_dedicated_another_network(self): def test_02_dedicated_another_network(self):
# Create network # Create network
self.network = Network.create( self.network = Network.create(
self.apiclient, self.apiclient,
self.services["network"], self.services["network"],
accountid=self.account.name, accountid=self.account.name,
domainid=self.account.domainid, domainid=self.account.domainid,
networkofferingid=self.network_offering.id, networkofferingid=self.network_offering.id,
zoneid=self.zone.id zoneid=self.zone.id
) )
self.debug("Created network: %s" % self.network.id) self.debug("Created network: %s" % self.network.id)
self.debug("Trying VM deploy with network created on account: %s" % self.account.name) self.debug("Trying VM deploy with network created on account: %s" % self.account.name)
with self.assertRaises(Exception): with self.assertRaises(Exception):
self.virtual_machine = VirtualMachine.create( self.virtual_machine = VirtualMachine.create(
self.apiclient, self.apiclient,
self.services["small"], self.services["small"],
accountid=self.account.name, accountid=self.account.name,
domainid=self.account.domainid, domainid=self.account.domainid,
networkids=self.network.id, networkids=self.network.id,
zoneid=self.zone.id, zoneid=self.zone.id,
serviceofferingid=self.service_offering.id serviceofferingid=self.service_offering.id
) )
return return

View File

@ -1,323 +1,323 @@
# Licensed to the Apache Software Foundation (ASF) under one # Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file # or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information # distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file # regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the # to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance # "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at # with the License. You may obtain a copy of the License at
# #
# http://www.apache.org/licenses/LICENSE-2.0 # http://www.apache.org/licenses/LICENSE-2.0
# #
# Unless required by applicable law or agreed to in writing, # Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an # software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the # KIND, either express or implied. See the License for the
# specific language governing permissions and limitations # specific language governing permissions and limitations
# under the License. # under the License.
""" """
BVT tests for NCC integration with cloudstack BVT tests for NCC integration with cloudstack
""" """
#Import Local Modules #Import Local Modules
from marvin.cloudstackTestCase import cloudstackTestCase from marvin.cloudstackTestCase import cloudstackTestCase
from marvin.lib.common import get_domain, get_zone, get_template from marvin.lib.common import get_domain, get_zone, get_template
from marvin.lib import ncc from marvin.lib import ncc
from marvin.lib.base import (Account, from marvin.lib.base import (Account,
VirtualMachine, VirtualMachine,
PublicIPAddress, PublicIPAddress,
LoadBalancerRule, LoadBalancerRule,
ServiceOffering, ServiceOffering,
NetworkOffering, NetworkOffering,
Network, Network,
NATRule, NATRule,
PhysicalNetwork, PhysicalNetwork,
NetworkServiceProvider, NetworkServiceProvider,
RegisteredServicePackage) RegisteredServicePackage)
from marvin.lib.utils import cleanup_resources from marvin.lib.utils import cleanup_resources
from nose.plugins.attrib import attr from nose.plugins.attrib import attr
import logging import logging
class TestNccIntegrationShared(cloudstackTestCase): class TestNccIntegrationShared(cloudstackTestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
cls.testClient = super(TestNccIntegrationShared, cls).getClsTestClient() cls.testClient = super(TestNccIntegrationShared, cls).getClsTestClient()
cls.api_client = cls.testClient.getApiClient() cls.api_client = cls.testClient.getApiClient()
cls.services = cls.testClient.getParsedTestDataConfig() cls.services = cls.testClient.getParsedTestDataConfig()
cls._cleanup = [] cls._cleanup = []
cls.logger = logging.getLogger('TestNccIntegrationShared') cls.logger = logging.getLogger('TestNccIntegrationShared')
cls.stream_handler = logging.StreamHandler() cls.stream_handler = logging.StreamHandler()
cls.logger.setLevel(logging.DEBUG) cls.logger.setLevel(logging.DEBUG)
cls.logger.addHandler(cls.stream_handler) cls.logger.addHandler(cls.stream_handler)
# Get Zone, Domain and templates # Get Zone, Domain and templates
cls.domain = get_domain(cls.api_client) cls.domain = get_domain(cls.api_client)
cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
cls.services['mode'] = cls.zone.networktype cls.services['mode'] = cls.zone.networktype
cls.template = get_template( cls.template = get_template(
cls.api_client, cls.api_client,
cls.zone.id, cls.zone.id,
cls.services["ostype"] ) cls.services["ostype"] )
ncc_ip=cls.services["NCC"]["NCCIP"] ncc_ip=cls.services["NCC"]["NCCIP"]
ns_ip=cls.services["NSShared"]["NSIP"] ns_ip=cls.services["NSShared"]["NSIP"]
cls.debug("NS IP: Shared: %s" % ns_ip) cls.debug("NS IP: Shared: %s" % ns_ip)
mgmt_srv_ip = cls.config.__dict__["mgtSvr"][0].__dict__["mgtSvrIp"] mgmt_srv_ip = cls.config.__dict__["mgtSvr"][0].__dict__["mgtSvrIp"]
#ncc_ip = "10.102.195.215" #ncc_ip = "10.102.195.215"
#ns_ip = "10.102.195.210" #ns_ip = "10.102.195.210"
cls.ns = ncc.NCC(ncc_ip, ns_ip, mgmt_srv_ip, logger=cls.logger) cls.ns = ncc.NCC(ncc_ip, ns_ip, mgmt_srv_ip, logger=cls.logger)
cls.ns.registerCCP(cls.api_client) cls.ns.registerCCP(cls.api_client)
cls.ns.registerNS() cls.ns.registerNS()
cls.ns.assignNStoCSZone() cls.ns.assignNStoCSZone()
spname = cls.services["servicepackage_shared"]["name"] spname = cls.services["servicepackage_shared"]["name"]
cls.debug("SPname (Shared): %s" % spname) cls.debug("SPname (Shared): %s" % spname)
#spname="SharedSP9" #spname="SharedSP9"
# Create Service package and get device group id, tenant group id and service package id # Create Service package and get device group id, tenant group id and service package id
# These would be needed later for clean up # These would be needed later for clean up
(cls.dv_group_id, cls.tnt_group_id, cls.srv_pkg_id) = cls.ns.createServicePackages( (cls.dv_group_id, cls.tnt_group_id, cls.srv_pkg_id) = cls.ns.createServicePackages(
spname, spname,
"NetScalerVPX", "NetScalerVPX",
ns_ip) ns_ip)
srv_pkg_list = RegisteredServicePackage.list(cls.api_client) srv_pkg_list = RegisteredServicePackage.list(cls.api_client)
# Choose the one created # Choose the one created
cls.srv_pkg_uuid = None cls.srv_pkg_uuid = None
for sp in srv_pkg_list: for sp in srv_pkg_list:
if sp.name == spname: if sp.name == spname:
cls.srv_pkg_uuid = sp.id cls.srv_pkg_uuid = sp.id
#srv_pkg_id = srv_pkg_list[0].id #srv_pkg_id = srv_pkg_list[0].id
cls.account = Account.create( cls.account = Account.create(
cls.api_client, cls.api_client,
cls.services["account"] cls.services["account"]
) )
cls._cleanup.append(cls.account) cls._cleanup.append(cls.account)
try: try:
cls.services["nw_off_ncc_SharedSP"]["servicepackageuuid"] = cls.srv_pkg_uuid 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.services["nw_off_ncc_SharedSP"]["servicepackagedescription"] = "A NetScalerVPX is shared across all networks."
cls.network_offering = NetworkOffering.create( cls.network_offering = NetworkOffering.create(
cls.api_client, cls.api_client,
cls.services["nw_off_ncc_SharedSP"]) cls.services["nw_off_ncc_SharedSP"])
except Exception as e: except Exception as e:
raise Exception ("Unable to create network offering with Service package % s due to exception % s" raise Exception ("Unable to create network offering with Service package % s due to exception % s"
% (cls.srv_pkg_uuid, e)) % (cls.srv_pkg_uuid, e))
# Network offering should be removed so that service package may be deleted later # Network offering should be removed so that service package may be deleted later
cls._cleanup.append(cls.network_offering) cls._cleanup.append(cls.network_offering)
cls.network_offering.update(cls.api_client, state = "Enabled") cls.network_offering.update(cls.api_client, state = "Enabled")
cls.service_offering_shared = ServiceOffering.create( cls.service_offering_shared = ServiceOffering.create(
cls.api_client, cls.api_client,
cls.services["service_offering"] cls.services["service_offering"]
) )
cls.services["small"]["template"] = cls.template.id cls.services["small"]["template"] = cls.template.id
# Enable Netscaler Service Provider # Enable Netscaler Service Provider
cls.phy_nws = PhysicalNetwork.list(cls.api_client,zoneid=cls.zone.id) cls.phy_nws = PhysicalNetwork.list(cls.api_client,zoneid=cls.zone.id)
if isinstance(cls.phy_nws, list): if isinstance(cls.phy_nws, list):
physical_network = cls.phy_nws[0] physical_network = cls.phy_nws[0]
try: try:
cls.ns_service_provider = NetworkServiceProvider.list(cls.api_client,name='Netscaler') cls.ns_service_provider = NetworkServiceProvider.list(cls.api_client,name='Netscaler')
if isinstance(cls.ns_service_provider, list): if isinstance(cls.ns_service_provider, list):
ns_provider = cls.ns_service_provider[0] ns_provider = cls.ns_service_provider[0]
except: except:
raise Exception ("Netscaler service provider not found!!") raise Exception ("Netscaler service provider not found!!")
try: try:
if ns_provider.state != "Enabled": if ns_provider.state != "Enabled":
NetworkServiceProvider.update(cls.api_client, id=ns_provider.id, physicalnetworkid=physical_network.id, state="Enabled") NetworkServiceProvider.update(cls.api_client, id=ns_provider.id, physicalnetworkid=physical_network.id, state="Enabled")
except: except:
raise Exception ("Enabling Netscaler Service provider failed. Unable to proceed") raise Exception ("Enabling Netscaler Service provider failed. Unable to proceed")
return return
@classmethod @classmethod
def tearDownClass(cls): def tearDownClass(cls):
try: try:
# Cleanup resources used # Cleanup resources used
cleanup_resources(cls.api_client, cls._cleanup) cleanup_resources(cls.api_client, cls._cleanup)
except Exception as e: except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % 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) cls.ns.cleanup_ncc(cls.dv_group_id, cls.srv_pkg_uuid, cls.srv_pkg_id, cls.tnt_group_id)
return return
def setUp(self): def setUp(self):
self.apiclient = self.testClient.getApiClient() self.apiclient = self.testClient.getApiClient()
return return
def tearDown(self): def tearDown(self):
return return
@attr(tags=["ncc"], required_hardware="true") @attr(tags=["ncc"], required_hardware="true")
def test_01_shared_first_network(self): def test_01_shared_first_network(self):
# Create network # Create network
self.debug("Creating network with network offering: %s" % self.network_offering.id) self.debug("Creating network with network offering: %s" % self.network_offering.id)
self.network = Network.create( self.network = Network.create(
self.apiclient, self.apiclient,
self.services["network"], self.services["network"],
accountid=self.account.name, accountid=self.account.name,
domainid=self.account.domainid, domainid=self.account.domainid,
networkofferingid=self.network_offering.id, networkofferingid=self.network_offering.id,
zoneid=self.zone.id zoneid=self.zone.id
) )
self.debug("Created network: %s" % self.network.id) self.debug("Created network: %s" % self.network.id)
self.debug("Trying VM deploy with network created on account: %s" % self.account.name) self.debug("Trying VM deploy with network created on account: %s" % self.account.name)
self.virtual_machine = VirtualMachine.create( self.virtual_machine = VirtualMachine.create(
self.apiclient, self.apiclient,
self.services["small"], self.services["small"],
accountid=self.account.name, accountid=self.account.name,
domainid=self.account.domainid, domainid=self.account.domainid,
zoneid=self.zone.id, zoneid=self.zone.id,
networkids=self.network.id, networkids=self.network.id,
serviceofferingid=self.service_offering_shared.id) serviceofferingid=self.service_offering_shared.id)
self.debug("Deployed VM in network: %s" % self.network.id) self.debug("Deployed VM in network: %s" % self.network.id)
list_vm_response = VirtualMachine.list( list_vm_response = VirtualMachine.list(
self.apiclient, self.apiclient,
id=self.virtual_machine.id id=self.virtual_machine.id
) )
self.debug( self.debug(
"Verify listVirtualMachines response for virtual machine: %s" "Verify listVirtualMachines response for virtual machine: %s"
% self.virtual_machine.id % self.virtual_machine.id
) )
self.assertEqual( self.assertEqual(
isinstance(list_vm_response, list), isinstance(list_vm_response, list),
True, True,
"Check list response returns a valid list") "Check list response returns a valid list")
vm_response = list_vm_response[0] vm_response = list_vm_response[0]
self.assertEqual( self.assertEqual(
vm_response.state, vm_response.state,
"Running", "Running",
"VM state should be running after deployment" "VM state should be running after deployment"
) )
self.debug("Acquiring public IP for network: %s" % self.network.id) self.debug("Acquiring public IP for network: %s" % self.network.id)
ip_with_lb_rule = PublicIPAddress.create( ip_with_lb_rule = PublicIPAddress.create(
self.apiclient, self.apiclient,
accountid=self.account.name, accountid=self.account.name,
zoneid=self.zone.id, zoneid=self.zone.id,
domainid=self.account.domainid, domainid=self.account.domainid,
networkid=self.network.id) networkid=self.network.id)
self.debug( self.debug(
"Creating LB rule for IP address: %s with round robin algo" % "Creating LB rule for IP address: %s with round robin algo" %
ip_with_lb_rule.ipaddress.ipaddress) ip_with_lb_rule.ipaddress.ipaddress)
self.services["lbrule"]["alg"] = 'roundrobin' self.services["lbrule"]["alg"] = 'roundrobin'
lb_rule = LoadBalancerRule.create( lb_rule = LoadBalancerRule.create(
self.apiclient, self.apiclient,
self.services["lbrule"], self.services["lbrule"],
ipaddressid=ip_with_lb_rule.ipaddress.id, ipaddressid=ip_with_lb_rule.ipaddress.id,
accountid=self.account.name, accountid=self.account.name,
networkid=self.network.id networkid=self.network.id
) )
lb_rules = LoadBalancerRule.list( lb_rules = LoadBalancerRule.list(
self.apiclient, self.apiclient,
id=lb_rule.id, id=lb_rule.id,
listall=True listall=True
) )
self.assertEqual( self.assertEqual(
isinstance(lb_rules, list), isinstance(lb_rules, list),
True, True,
"List LB rules should return a newly created LB rule" "List LB rules should return a newly created LB rule"
) )
self.debug("Adding %s to the LB rule %s" % ( self.debug("Adding %s to the LB rule %s" % (
self.virtual_machine.name, self.virtual_machine.name,
lb_rule.name lb_rule.name
)) ))
lb_rule.assign(self.apiclient, [self.virtual_machine]) lb_rule.assign(self.apiclient, [self.virtual_machine])
@attr(tags=["ncc"], required_hardware="true") @attr(tags=["ncc"], required_hardware="true")
def test_02_shared_another_network(self): def test_02_shared_another_network(self):
# Create network # Create network
self.debug("Creating network with network offering: %s" % self.network_offering.id) self.debug("Creating network with network offering: %s" % self.network_offering.id)
self.network = Network.create( self.network = Network.create(
self.apiclient, self.apiclient,
self.services["network"], self.services["network"],
accountid=self.account.name, accountid=self.account.name,
domainid=self.account.domainid, domainid=self.account.domainid,
networkofferingid=self.network_offering.id, networkofferingid=self.network_offering.id,
zoneid=self.zone.id zoneid=self.zone.id
) )
self.debug("Created network: %s" % self.network.id) self.debug("Created network: %s" % self.network.id)
self.debug("Trying VM deploy with network created on account: %s" % self.account.name) self.debug("Trying VM deploy with network created on account: %s" % self.account.name)
self.virtual_machine = VirtualMachine.create( self.virtual_machine = VirtualMachine.create(
self.apiclient, self.apiclient,
self.services["small"], self.services["small"],
accountid=self.account.name, accountid=self.account.name,
domainid=self.account.domainid, domainid=self.account.domainid,
networkids=self.network.id, networkids=self.network.id,
zoneid=self.zone.id, zoneid=self.zone.id,
serviceofferingid=self.service_offering_shared.id serviceofferingid=self.service_offering_shared.id
) )
self.debug("Deployed VM in network: %s" % self.network.id) self.debug("Deployed VM in network: %s" % self.network.id)
list_vm_response = VirtualMachine.list( list_vm_response = VirtualMachine.list(
self.apiclient, self.apiclient,
id=self.virtual_machine.id id=self.virtual_machine.id
) )
self.debug( self.debug(
"Verify listVirtualMachines response for virtual machine: %s" "Verify listVirtualMachines response for virtual machine: %s"
% self.virtual_machine.id % self.virtual_machine.id
) )
self.assertEqual( self.assertEqual(
isinstance(list_vm_response, list), isinstance(list_vm_response, list),
True, True,
"Check list response returns a valid list") "Check list response returns a valid list")
vm_response = list_vm_response[0] vm_response = list_vm_response[0]
self.assertEqual( self.assertEqual(
vm_response.state, vm_response.state,
"Running", "Running",
"VM state should be running after deployment" "VM state should be running after deployment"
) )
self.debug("Aquiring public IP for network: %s" % self.network.id) self.debug("Aquiring public IP for network: %s" % self.network.id)
ip_with_lb_rule = PublicIPAddress.create( ip_with_lb_rule = PublicIPAddress.create(
self.apiclient, self.apiclient,
accountid=self.account.name, accountid=self.account.name,
zoneid=self.zone.id, zoneid=self.zone.id,
domainid=self.account.domainid, domainid=self.account.domainid,
networkid=self.network.id) networkid=self.network.id)
self.debug( self.debug(
"Creating LB rule for IP address: %s with round robin algo" % "Creating LB rule for IP address: %s with round robin algo" %
ip_with_lb_rule.ipaddress.ipaddress) ip_with_lb_rule.ipaddress.ipaddress)
self.services["lbrule"]["alg"] = 'roundrobin' self.services["lbrule"]["alg"] = 'roundrobin'
lb_rule = LoadBalancerRule.create( lb_rule = LoadBalancerRule.create(
self.apiclient, self.apiclient,
self.services["lbrule"], self.services["lbrule"],
ipaddressid=ip_with_lb_rule.ipaddress.id, ipaddressid=ip_with_lb_rule.ipaddress.id,
accountid=self.account.name, accountid=self.account.name,
networkid=self.network.id networkid=self.network.id
) )
lb_rules = LoadBalancerRule.list( lb_rules = LoadBalancerRule.list(
self.apiclient, self.apiclient,
id=lb_rule.id, id=lb_rule.id,
listall=True listall=True
) )
self.assertEqual( self.assertEqual(
isinstance(lb_rules, list), isinstance(lb_rules, list),
True, True,
"List LB rules should return a newly created LB rule" "List LB rules should return a newly created LB rule"
) )
self.debug("Adding %s to the LB rule %s" % ( self.debug("Adding %s to the LB rule %s" % (
self.virtual_machine.name, self.virtual_machine.name,
lb_rule.name lb_rule.name
)) ))
lb_rule.assign(self.apiclient, [self.virtual_machine]) lb_rule.assign(self.apiclient, [self.virtual_machine])
return return