diff options
Diffstat (limited to 'netbox-client/lighty')
5 files changed, 494 insertions, 0 deletions
diff --git a/netbox-client/lighty/pom.xml b/netbox-client/lighty/pom.xml new file mode 100755 index 000000000..18db29466 --- /dev/null +++ b/netbox-client/lighty/pom.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onap.ccsdk.parent</groupId> + <artifactId>binding-parent</artifactId> + <version>1.4.0-SNAPSHOT</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>netbox-client-lighty</artifactId> + <version>0.6.0-SNAPSHOT</version> + <packaging>jar</packaging> + + <name>ccsdk-sli-adaptors :: netbox-client :: ${project.artifactId}</name> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>ccsdk-lighty-dependency-versions</artifactId> + <version>${project.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> + + <dependencies> + <dependency> + <groupId>io.lighty.core</groupId> + <artifactId>lighty-controller</artifactId> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>netbox-client-provider</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> +</project> diff --git a/netbox-client/lighty/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxClientImplLighty.java b/netbox-client/lighty/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxClientImplLighty.java new file mode 100644 index 000000000..2658c06cc --- /dev/null +++ b/netbox-client/lighty/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxClientImplLighty.java @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2018 Bell Canada. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.ccsdk.sli.adaptors.netbox.impl; + +import com.google.common.collect.Lists; +import com.google.gson.JsonSyntaxException; +import java.io.IOException; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Map; +import javax.sql.rowset.CachedRowSet; +import org.apache.http.HttpResponse; +import org.apache.http.util.EntityUtils; +import org.onap.ccsdk.sli.adaptors.netbox.api.NetboxClient; +import org.onap.ccsdk.sli.adaptors.netbox.model.IPAddress; +import org.onap.ccsdk.sli.adaptors.netbox.model.IPStatus; +import org.onap.ccsdk.sli.core.dblib.DbLibService; +import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; +import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus; +import org.onap.ccsdk.sli.core.slipluginutils.SliPluginUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * THIS CLASS IS A COPY OF {@link NetboxClientImpl} WITH REMOVED OSGi DEPENDENCIES + */ +public class NetboxClientImplLighty implements NetboxClient { + + private static final Logger LOG = LoggerFactory.getLogger(NetboxClientImplLighty.class); + + // Netbox URI + + private static final String NEXT_AVAILABLE_IP_IN_PREFIX_PATH = "/api/ipam/prefixes/%s/available-ips/"; + private static final String IP_ADDRESS_PATH = "/api/ipam/ip-addresses/%s/"; + + // Netbox Payload + + private static final String ASSIGN_IP_ADDRESS_PAYLOAD = "{\n" + + " \"custom_fields\": {\n" + + " \"external-key\": \"%s\",\n" + + " \"resource-name\": \"%s\"\n" + + " }\n" + + "}"; + + // Service Logic Context input variables and exception + + private static final String SERVICE_INSTANCE_ID_PROP = "service_instance_id"; + private static final String VF_MODULE_ID_PROP = "vf_module_id"; + private static final String EXTERNAL_KEY_PROP = "external_key"; + private static final String SQL_EXCEPTION_MESSAGE = "Caught SQL exception"; + + // SQL statement + + private static final String ASSIGN_IP_SQL_STATEMENT = + "INSERT INTO IPAM_IP_ASSIGNEMENT (service_instance_id, vf_module_id, prefix_id, ip_address_id, ip_address, ip_status, ip_response_json, external_key, ip_address_type) \n" + + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; + private static final String UNASSIGN_IP_SQL_STATEMENT = + "UPDATE IPAM_IP_ASSIGNEMENT SET ip_status = ? WHERE service_instance_id = ? AND external_key = ?"; + private static final String GET_IP_ADDRESS_ID_SQL_STATEMENT = + "SELECT ip_address_id FROM IPAM_IP_ASSIGNEMENT WHERE service_instance_id = ? AND external_key = ?"; + + private final NetboxHttpClientLighty client; + private final DbLibService dbLibService; + + public NetboxClientImplLighty(final NetboxHttpClientLighty client, final DbLibService dbLibService) { + this.client = client; + this.dbLibService = dbLibService; + } + + @Override + public QueryStatus assignIpAddress(final Map<String, String> parameters, final SvcLogicContext ctx) { + + try { + SliPluginUtils + .checkParameters(parameters, + new String[]{SERVICE_INSTANCE_ID_PROP, VF_MODULE_ID_PROP, "prefix_id", "resource_name", + EXTERNAL_KEY_PROP}, LOG); + } catch (SvcLogicException e) { + return QueryStatus.FAILURE; + } + + final String serviceInstanceId = parameters.get(SERVICE_INSTANCE_ID_PROP); + final String vfModuleId = parameters.get(VF_MODULE_ID_PROP); + final String prefixId = parameters.get("prefix_id"); + final String resourceName = parameters.get("resource_name"); + final String externalKey = parameters.get(EXTERNAL_KEY_PROP); + + HttpResponse httpResp; + try { + httpResp = client + .post(String.format(NEXT_AVAILABLE_IP_IN_PREFIX_PATH, prefixId), + String.format(ASSIGN_IP_ADDRESS_PAYLOAD, externalKey, resourceName)); + } catch (IOException e) { + LOG.error("Fail to assign IP for Prefix(id={}). {}", prefixId, e.getMessage(), e.getCause()); + return QueryStatus.FAILURE; + } + + String ipamRespJson; + try { + ipamRespJson = EntityUtils.toString(httpResp.getEntity(), "UTF-8"); + } catch (IOException e) { + LOG.error("Fail to parse IPAM response for assign in Prefix(id={}). Response={}", prefixId, + httpResp.getEntity(), e); + return QueryStatus.FAILURE; + } + + if (httpResp.getStatusLine().getStatusCode() != 201) { + LOG.error("Fail to assign IP for Prefix(id={}). HTTP code 201!={}. Response={}", prefixId, + httpResp.getStatusLine().getStatusCode(), ipamRespJson); + return QueryStatus.FAILURE; + } + + IPAddress ipAddress; + try { + ipAddress = IPAddress.fromJson(ipamRespJson); + } catch (JsonSyntaxException e) { + LOG.error("Fail to parse IPAM JSON reponse to IPAddress POJO. IPAM JSON Response={}", ipamRespJson, e); + return QueryStatus.FAILURE; + } + + ArrayList<String> args = Lists.newArrayList( + serviceInstanceId, + vfModuleId, + String.valueOf(prefixId), + String.valueOf(ipAddress.getId()), + ipAddress.getAddress(), + IPStatus.ASSIGNED.name(), + ipamRespJson, + externalKey, + resourceName); + + try { + dbLibService.writeData(ASSIGN_IP_SQL_STATEMENT, args, null); + } catch (SQLException e) { + LOG.error(SQL_EXCEPTION_MESSAGE, e); + return QueryStatus.FAILURE; + } + + ctx.setAttribute("self_serve_netbox_ip_assignement.ip-address", ipAddress.getAddress()); + + return QueryStatus.SUCCESS; + } + + @Override + public QueryStatus unassignIpAddress(final Map<String, String> parameters, final SvcLogicContext ctx) { + try { + SliPluginUtils + .checkParameters(parameters, new String[]{SERVICE_INSTANCE_ID_PROP, EXTERNAL_KEY_PROP}, + LOG); + } catch (SvcLogicException e) { + return QueryStatus.FAILURE; + } + + final String serviceInstanceId = parameters.get(SERVICE_INSTANCE_ID_PROP); + final String externalKey = parameters.get(EXTERNAL_KEY_PROP); + + String ipAddressId; + ArrayList<String> args = Lists.newArrayList( + serviceInstanceId, + externalKey); + try (CachedRowSet row = dbLibService.getData(GET_IP_ADDRESS_ID_SQL_STATEMENT, args, null)) { + if (row.next()) { + ipAddressId = row.getString("ip_address_id"); + } else { + throw new SQLException("Data not found."); + } + } catch (SQLException e) { + LOG.error(SQL_EXCEPTION_MESSAGE, e); + return QueryStatus.FAILURE; + } + + HttpResponse httpResp; + try { + httpResp = client.delete(String.format(IP_ADDRESS_PATH, ipAddressId)); + } catch (IOException e) { + LOG.error("Fail to unassign IP for IPAddress(id= " + ipAddressId + "). " + e.getMessage(), + e.getCause()); + return QueryStatus.FAILURE; + } + + if (httpResp.getStatusLine().getStatusCode() - 200 >= 100) { + LOG.error("Fail to unassign IP for IPAddress(id={}). HTTP code={}.", ipAddressId, + httpResp.getStatusLine().getStatusCode()); + return QueryStatus.FAILURE; + } + + args.clear(); + args = Lists.newArrayList( + IPStatus.DELETED.name(), + serviceInstanceId, + externalKey); + + try { + dbLibService.writeData(UNASSIGN_IP_SQL_STATEMENT, args, null); + } catch (SQLException e) { + LOG.error(SQL_EXCEPTION_MESSAGE, e); + return QueryStatus.FAILURE; + } + + return QueryStatus.SUCCESS; + } +} diff --git a/netbox-client/lighty/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxHttpClientLighty.java b/netbox-client/lighty/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxHttpClientLighty.java new file mode 100644 index 000000000..388486c4f --- /dev/null +++ b/netbox-client/lighty/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxHttpClientLighty.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2018 Bell Canada. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.ccsdk.sli.adaptors.netbox.impl; + +import static org.apache.http.HttpHeaders.ACCEPT; +import static org.apache.http.HttpHeaders.AUTHORIZATION; +import static org.apache.http.HttpHeaders.CONTENT_TYPE; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import javax.net.ssl.SSLContext; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.ssl.SSLContexts; +import org.apache.http.ssl.TrustStrategy; +import org.onap.ccsdk.sli.adaptors.netbox.property.NetboxPropertiesLighty; + +/** + * THIS CLASS IS A COPY OF {@link NetboxHttpClient} WITH REMOVED OSGi DEPENDENCIES + */ +public class NetboxHttpClientLighty implements AutoCloseable { + + private static final String APPLICATION_JSON = "application/json"; + + private final CloseableHttpClient client; + private final String url; + private final String token; + + // Used by the blueprint container + public NetboxHttpClientLighty(NetboxPropertiesLighty properties) { + this(properties.getHost(), properties.getApiKey()); + } + + NetboxHttpClientLighty(final String url, final String token) { + this.url = url; + this.token = token; + + final TrustStrategy acceptingTrustStrategy = (certificate, authType) -> true; + final SSLContext sslContext; + try { + sslContext = SSLContexts.custom() + .loadTrustMaterial(null, acceptingTrustStrategy).build(); + } catch (final NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) { + throw new IllegalStateException("Can't create http client", e); + } + client = HttpClientBuilder.create() + .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE) + .setSSLContext(sslContext) + .build(); + } + + @Override + public void close() throws IOException { + client.close(); + } + + HttpResponse post(final String uri, final String requestBody) throws IOException { + final HttpPost request = new HttpPost(url + uri); + setHeaders(request); + request.setEntity(new StringEntity(requestBody, Charset.forName("UTF-8"))); + return client.execute(request); + } + + HttpResponse delete(final String uri) throws IOException { + final HttpDelete request = new HttpDelete(url + uri); + setHeaders(request); + return client.execute(request); + } + + private void setHeaders(final HttpRequestBase request) { + request.addHeader(ACCEPT, APPLICATION_JSON); + request.addHeader(CONTENT_TYPE, APPLICATION_JSON); + request.addHeader(AUTHORIZATION, "Token " + token); + } +} diff --git a/netbox-client/lighty/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/lighty/NetboxClientModule.java b/netbox-client/lighty/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/lighty/NetboxClientModule.java new file mode 100644 index 000000000..13f7963bb --- /dev/null +++ b/netbox-client/lighty/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/lighty/NetboxClientModule.java @@ -0,0 +1,70 @@ +/* + * ============LICENSE_START========================================== + * Copyright (c) 2019 PANTHEON.tech s.r.o. + * =================================================================== + * Licensed 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. + * ============LICENSE_END============================================ + * + */ +package org.onap.ccsdk.sli.adaptors.netbox.lighty; + +import io.lighty.core.controller.api.AbstractLightyModule; +import java.io.IOException; +import org.onap.ccsdk.sli.adaptors.netbox.api.NetboxClient; +import org.onap.ccsdk.sli.adaptors.netbox.impl.NetboxClientImplLighty; +import org.onap.ccsdk.sli.adaptors.netbox.impl.NetboxHttpClientLighty; +import org.onap.ccsdk.sli.adaptors.netbox.property.NetboxPropertiesLighty; +import org.onap.ccsdk.sli.core.dblib.DbLibService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The implementation of the {@link io.lighty.core.controller.api.LightyModule} that manages and provides services from + * the netbox-client-provider artifact. + */ +public class NetboxClientModule extends AbstractLightyModule { + + private static final Logger LOG = LoggerFactory.getLogger(NetboxClientModule.class); + + private final DbLibService dbLibService; + + private NetboxPropertiesLighty netboxProperties; + private NetboxHttpClientLighty netboxHttpClient; + private NetboxClientImplLighty netboxClient; + + public NetboxClientModule(DbLibService dbLibService) { + this.dbLibService = dbLibService; + } + + @Override + protected boolean initProcedure() { + this.netboxProperties = new NetboxPropertiesLighty(); + this.netboxHttpClient = new NetboxHttpClientLighty(netboxProperties); + this.netboxClient = new NetboxClientImplLighty(netboxHttpClient, dbLibService); + return true; + } + + @Override + protected boolean stopProcedure() { + try { + netboxHttpClient.close(); + } catch (IOException e) { + LOG.error("Exception thrown while closing {}!", netboxHttpClient.getClass(), e); + return false; + } + return true; + } + + public NetboxClient getNetboxClient() { + return netboxClient; + } + +} diff --git a/netbox-client/lighty/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/property/NetboxPropertiesLighty.java b/netbox-client/lighty/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/property/NetboxPropertiesLighty.java new file mode 100644 index 000000000..15759c721 --- /dev/null +++ b/netbox-client/lighty/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/property/NetboxPropertiesLighty.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2018 Bell Canada. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.ccsdk.sli.adaptors.netbox.property; + +import java.io.FileInputStream; +import java.util.Properties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * THIS CLASS IS A COPY OF {@link NetboxProperties} WITH REMOVED OSGi DEPENDENCIES + */ +public class NetboxPropertiesLighty { + + private static final Logger LOG = LoggerFactory.getLogger(NetboxPropertiesLighty.class); + + private static final String NETBOX_PROPERTY_FILE_NAME = "netbox.properties"; + private static final String DEFAULT_PROPERTIES_DIR = "/opt/onap/ccsdk/data/properties"; + private static final String PROPERTIES_DIR_KEY = "SDNC_CONFIG_DIR"; + + private static final String NETBOX_URL_PROP = "org.onap.ccsdk.sli.adaptors.netbox.url"; + private static final String NETBOX_API_KEY_PROP = "org.onap.ccsdk.sli.adaptors.netbox.apikey"; + + private Properties properties; + + public NetboxPropertiesLighty() { + loadProps(); + } + + public String getHost() { + return properties.getProperty(NETBOX_URL_PROP); + } + + public String getApiKey() { + return properties.getProperty(NETBOX_API_KEY_PROP); + } + + private void loadProps() { + properties = new Properties(); + // Try to load config from dir + final String ccsdkConfigDir = + System.getProperty(PROPERTIES_DIR_KEY, DEFAULT_PROPERTIES_DIR) + "/" + NETBOX_PROPERTY_FILE_NAME; + LOG.info("Loading properties from file {}", ccsdkConfigDir); + try (FileInputStream in = new FileInputStream(ccsdkConfigDir)) { + properties.load(in); + LOG.info("Loaded {} properties from file {}", properties.size(), ccsdkConfigDir); + } catch (Exception e) { + LOG.error("Failed to load properties for file: {} " + NETBOX_PROPERTY_FILE_NAME, e); + } + } +} |