2 * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.netconf.sal.connect.util;
11 import com.google.common.util.concurrent.CheckedFuture;
12 import com.google.common.util.concurrent.FutureCallback;
13 import com.google.common.util.concurrent.Futures;
14 import com.google.common.util.concurrent.ListenableFuture;
15 import com.google.common.util.concurrent.MoreExecutors;
16 import com.google.common.util.concurrent.SettableFuture;
17 import java.util.List;
18 import java.util.stream.Collectors;
19 import javax.annotation.Nullable;
20 import org.opendaylight.aaa.encrypt.AAAEncryptionService;
21 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
22 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
23 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
24 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddKeystoreEntryInput;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddKeystoreEntryOutput;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddKeystoreEntryOutputBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddPrivateKeyInput;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddPrivateKeyOutput;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddPrivateKeyOutputBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddTrustedCertificateInput;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddTrustedCertificateOutput;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.AddTrustedCertificateOutputBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.Keystore;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.KeystoreBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.NetconfKeystoreService;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveKeystoreEntryInput;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveKeystoreEntryOutput;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveKeystoreEntryOutputBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemovePrivateKeyInput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemovePrivateKeyOutput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemovePrivateKeyOutputBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveTrustedCertificateInput;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveTrustedCertificateOutput;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.RemoveTrustedCertificateOutputBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017._private.keys.PrivateKey;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017._private.keys.PrivateKeyKey;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.keystore.entry.KeyCredential;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.keystore.entry.KeyCredentialBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.keystore.entry.KeyCredentialKey;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.trusted.certificates.TrustedCertificate;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.keystore.rev171017.trusted.certificates.TrustedCertificateKey;
53 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
54 import org.opendaylight.yangtools.yang.common.RpcResult;
55 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
59 public class NetconfSalKeystoreService implements NetconfKeystoreService {
61 private static final Logger LOG = LoggerFactory.getLogger(NetconfSalKeystoreService.class);
63 private final DataBroker dataBroker;
64 private final AAAEncryptionService encryptionService;
66 private final InstanceIdentifier<Keystore> keystoreIid = InstanceIdentifier.create(Keystore.class);
68 public NetconfSalKeystoreService(final DataBroker dataBroker,
69 final AAAEncryptionService encryptionService) {
70 LOG.info("Starting NETCONF keystore service.");
72 this.dataBroker = dataBroker;
73 this.encryptionService = encryptionService;
78 private void initKeystore() {
79 final Keystore keystore = new KeystoreBuilder().build();
81 final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
82 writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, keystoreIid, keystore);
84 final CheckedFuture<Void, TransactionCommitFailedException> submit = writeTransaction.submit();
88 LOG.debug("init keystore done");
89 } catch (TransactionCommitFailedException exception) {
90 LOG.error("Unable to initialize Netconf key-pair store.", exception);
95 public ListenableFuture<RpcResult<RemoveKeystoreEntryOutput>> removeKeystoreEntry(
96 final RemoveKeystoreEntryInput input) {
97 LOG.debug("Removing keypairs: {}", input);
99 final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
100 final List<String> ids = input.getKeyId();
102 for (final String id : ids) {
103 writeTransaction.delete(LogicalDatastoreType.CONFIGURATION,
104 keystoreIid.child(KeyCredential.class, new KeyCredentialKey(id)));
107 final SettableFuture<RpcResult<RemoveKeystoreEntryOutput>> rpcResult = SettableFuture.create();
109 final ListenableFuture<Void> submit = writeTransaction.submit();
110 Futures.addCallback(submit, new FutureCallback<Void>() {
112 public void onSuccess(@Nullable final Void result) {
113 LOG.debug("remove-key-pair success. Input: {}");
114 rpcResult.set(RpcResultBuilder.success(new RemoveKeystoreEntryOutputBuilder().build()).build());
118 public void onFailure(final Throwable throwable) {
119 LOG.warn("remove-key-pair failed. Input: {}", input, throwable);
120 rpcResult.setException(throwable);
122 }, MoreExecutors.directExecutor());
128 public ListenableFuture<RpcResult<AddKeystoreEntryOutput>> addKeystoreEntry(final AddKeystoreEntryInput input) {
129 LOG.debug("Adding keypairs: {}", input);
131 final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
132 final List<KeyCredential> keypairs = input.getKeyCredential().stream().map(keypair ->
133 new KeyCredentialBuilder(keypair)
134 .setPrivateKey(encryptionService.encrypt(keypair.getPrivateKey()))
135 .setPassphrase(encryptionService.encrypt(keypair.getPassphrase()))
136 .build()).collect(Collectors.toList());
138 for (KeyCredential keypair : keypairs) {
139 writeTransaction.merge(LogicalDatastoreType.CONFIGURATION,
140 keystoreIid.child(KeyCredential.class, keypair.getKey()), keypair);
143 final SettableFuture<RpcResult<AddKeystoreEntryOutput>> rpcResult = SettableFuture.create();
145 final ListenableFuture<Void> submit = writeTransaction.submit();
146 Futures.addCallback(submit, new FutureCallback<Void>() {
148 public void onSuccess(@Nullable final Void result) {
149 LOG.debug("add-key-pair success. Input: {}");
150 rpcResult.set(RpcResultBuilder.success(new AddKeystoreEntryOutputBuilder().build()).build());
154 public void onFailure(final Throwable throwable) {
155 LOG.warn("add-key-pair failed. Input: {}", input, throwable);
156 rpcResult.setException(throwable);
158 }, MoreExecutors.directExecutor());
164 public ListenableFuture<RpcResult<AddTrustedCertificateOutput>> addTrustedCertificate(
165 final AddTrustedCertificateInput input) {
166 final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
168 for (TrustedCertificate certificate : input.getTrustedCertificate()) {
169 writeTransaction.merge(LogicalDatastoreType.CONFIGURATION,
170 keystoreIid.child(TrustedCertificate.class, certificate.getKey()), certificate);
173 final SettableFuture<RpcResult<AddTrustedCertificateOutput>> rpcResult = SettableFuture.create();
175 final ListenableFuture<Void> submit = writeTransaction.submit();
176 Futures.addCallback(submit, new FutureCallback<Void>() {
178 public void onSuccess(@Nullable final Void result) {
179 LOG.debug("add-trusted-certificate success. Input: {}", input);
180 rpcResult.set(RpcResultBuilder.success(new AddTrustedCertificateOutputBuilder().build()).build());
184 public void onFailure(final Throwable throwable) {
185 LOG.warn("add-trusted-certificate failed. Input: {}", input, throwable);
186 rpcResult.setException(throwable);
188 }, MoreExecutors.directExecutor());
194 public ListenableFuture<RpcResult<RemoveTrustedCertificateOutput>> removeTrustedCertificate(
195 final RemoveTrustedCertificateInput input) {
196 final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
197 final List<String> names = input.getName();
199 for (final String name : names) {
200 writeTransaction.delete(LogicalDatastoreType.CONFIGURATION,
201 keystoreIid.child(TrustedCertificate.class, new TrustedCertificateKey(name)));
204 final SettableFuture<RpcResult<RemoveTrustedCertificateOutput>> rpcResult = SettableFuture.create();
206 final ListenableFuture<Void> submit = writeTransaction.submit();
207 Futures.addCallback(submit, new FutureCallback<Void>() {
209 public void onSuccess(@Nullable final Void result) {
210 LOG.debug("remove-trusted-certificate success. Input: {}", input);
211 rpcResult.set(RpcResultBuilder.success(new RemoveTrustedCertificateOutputBuilder().build()).build());
215 public void onFailure(final Throwable throwable) {
216 LOG.warn("remove-trusted-certificate failed. Input: {}", input, throwable);
217 rpcResult.setException(throwable);
219 }, MoreExecutors.directExecutor());
225 public ListenableFuture<RpcResult<AddPrivateKeyOutput>> addPrivateKey(final AddPrivateKeyInput input) {
226 final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
228 for (PrivateKey key: input.getPrivateKey()) {
229 writeTransaction.merge(LogicalDatastoreType.CONFIGURATION,
230 keystoreIid.child(PrivateKey.class, key.getKey()), key);
233 final SettableFuture<RpcResult<AddPrivateKeyOutput>> rpcResult = SettableFuture.create();
235 final ListenableFuture<Void> submit = writeTransaction.submit();
236 Futures.addCallback(submit, new FutureCallback<Void>() {
238 public void onSuccess(@Nullable final Void result) {
239 LOG.debug("add-private-key success. Input: {}", input);
240 rpcResult.set(RpcResultBuilder.success(new AddPrivateKeyOutputBuilder().build()).build());
244 public void onFailure(final Throwable throwable) {
245 LOG.warn("add-private-key failed. Input: {}", input, throwable);
246 rpcResult.setException(throwable);
248 }, MoreExecutors.directExecutor());
254 public ListenableFuture<RpcResult<RemovePrivateKeyOutput>> removePrivateKey(final RemovePrivateKeyInput input) {
255 final WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
256 final List<String> names = input.getName();
258 for (final String name : names) {
259 writeTransaction.delete(LogicalDatastoreType.CONFIGURATION,
260 keystoreIid.child(PrivateKey.class, new PrivateKeyKey(name)));
263 final SettableFuture<RpcResult<RemovePrivateKeyOutput>> rpcResult = SettableFuture.create();
265 final ListenableFuture<Void> submit = writeTransaction.submit();
266 Futures.addCallback(submit, new FutureCallback<Void>() {
268 public void onSuccess(@Nullable final Void result) {
269 LOG.debug("remove-private-key success. Input: {}", input);
270 rpcResult.set(RpcResultBuilder.success(new RemovePrivateKeyOutputBuilder().build()).build());
274 public void onFailure(final Throwable throwable) {
275 LOG.warn("remove-private-key failed. Input: {}", input, throwable);
276 rpcResult.setException(throwable);
278 }, MoreExecutors.directExecutor());