blob: b1550905930a02da6f3667905779ea2842936420 [file] [log] [blame]
Thomas Vachuska96d55b12015-05-11 08:52:03 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Thomas Vachuska96d55b12015-05-11 08:52:03 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.cli.cfg;
17
Jonathan Hart2ddc4112015-09-16 09:28:07 -070018import com.fasterxml.jackson.core.JsonProcessingException;
Thomas Vachuska0a400ea2015-09-04 11:25:03 -070019import com.fasterxml.jackson.databind.JsonNode;
Thomas Vachuska96d55b12015-05-11 08:52:03 -070020import com.fasterxml.jackson.databind.ObjectMapper;
21import com.fasterxml.jackson.databind.node.ObjectNode;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070022import org.apache.karaf.shell.api.action.Argument;
23import org.apache.karaf.shell.api.action.Command;
24import org.apache.karaf.shell.api.action.lifecycle.Service;
25import org.apache.karaf.shell.api.action.Option;
Thomas Vachuska96d55b12015-05-11 08:52:03 -070026import org.onosproject.cli.AbstractShellCommand;
Ray Milkeya4122362015-08-18 15:19:08 -070027import org.onosproject.net.config.Config;
28import org.onosproject.net.config.NetworkConfigService;
29import org.onosproject.net.config.SubjectFactory;
Thomas Vachuska96d55b12015-05-11 08:52:03 -070030
31import static com.google.common.base.Strings.isNullOrEmpty;
kavitha Alagesan1f1fef72016-12-08 17:07:12 +053032import static org.onlab.util.Tools.nullIsIllegal;
Thomas Vachuska96d55b12015-05-11 08:52:03 -070033
34/**
35 * Manages network configuration.
36 */
Ray Milkeyd84f89b2018-08-17 14:54:17 -070037@Service
Thomas Vachuska96d55b12015-05-11 08:52:03 -070038@Command(scope = "onos", name = "netcfg",
39 description = "Manages network configuration")
40public class NetworkConfigCommand extends AbstractShellCommand {
41
kavitha Alagesan1f1fef72016-12-08 17:07:12 +053042 private static final String E_CLASSKEY_NOT_REGISTERED = " is not a registered SubjectClassKey";
43
Thomas Vachuskaea5adc62015-10-07 11:52:30 -070044 @Argument(index = 0, name = "subjectClassKey", description = "Subject class key",
45 required = false, multiValued = false)
46 String subjectClassKey = null;
47
48 @Argument(index = 1, name = "subjectKey", description = "Subject key",
Thomas Vachuska96d55b12015-05-11 08:52:03 -070049 required = false, multiValued = false)
50 String subjectKey = null;
51
Thomas Vachuska96d55b12015-05-11 08:52:03 -070052 @Argument(index = 2, name = "configKey", description = "Config key",
53 required = false, multiValued = false)
54 String configKey = null;
55
Yuta HIGUCHI5d025c32017-03-13 20:32:48 -070056 @Option(name = "--remove",
57 description = "Remove specified configuration tree",
58 required = false)
59 private boolean remove = false;
60
Thomas Vachuska96d55b12015-05-11 08:52:03 -070061 private final ObjectMapper mapper = new ObjectMapper();
62 private NetworkConfigService service;
63
64 @Override
Ray Milkeyd84f89b2018-08-17 14:54:17 -070065 protected void doExecute() {
Thomas Vachuska96d55b12015-05-11 08:52:03 -070066 service = get(NetworkConfigService.class);
Jonathan Hart2ddc4112015-09-16 09:28:07 -070067 JsonNode root = mapper.createObjectNode();
Thomas Vachuskaea5adc62015-10-07 11:52:30 -070068 if (isNullOrEmpty(subjectClassKey)) {
Yuta HIGUCHI5d025c32017-03-13 20:32:48 -070069 if (remove) {
70 service.removeConfig();
71 }
Thomas Vachuska0a400ea2015-09-04 11:25:03 -070072 addAll((ObjectNode) root);
Thomas Vachuska96d55b12015-05-11 08:52:03 -070073 } else {
kavitha Alagesan1f1fef72016-12-08 17:07:12 +053074 SubjectFactory subjectFactory = nullIsIllegal(service.getSubjectFactory(subjectClassKey),
75 subjectClassKey + E_CLASSKEY_NOT_REGISTERED);
Thomas Vachuskaea5adc62015-10-07 11:52:30 -070076 if (isNullOrEmpty(subjectKey)) {
Thomas Vachuska0a400ea2015-09-04 11:25:03 -070077 addSubjectClass((ObjectNode) root, subjectFactory);
Thomas Vachuska96d55b12015-05-11 08:52:03 -070078 } else {
Thomas Vachuskaea5adc62015-10-07 11:52:30 -070079 Object s = subjectFactory.createSubject(subjectKey);
Thomas Vachuska96d55b12015-05-11 08:52:03 -070080 if (isNullOrEmpty(configKey)) {
Yuta HIGUCHI5d025c32017-03-13 20:32:48 -070081 if (remove) {
82 service.removeConfig(s);
83 }
Thomas Vachuska0a400ea2015-09-04 11:25:03 -070084 addSubject((ObjectNode) root, s);
Thomas Vachuska96d55b12015-05-11 08:52:03 -070085 } else {
Yuta HIGUCHI5d025c32017-03-13 20:32:48 -070086 if (remove) {
87 service.removeConfig(subjectClassKey, s, configKey);
88 }
Thomas Vachuskaea5adc62015-10-07 11:52:30 -070089 root = getSubjectConfig(getConfig(s, subjectClassKey, configKey));
Thomas Vachuska96d55b12015-05-11 08:52:03 -070090 }
91 }
92 }
Jonathan Hart2ddc4112015-09-16 09:28:07 -070093
94 try {
95 print("%s", mapper.writerWithDefaultPrettyPrinter().writeValueAsString(root));
96 } catch (JsonProcessingException e) {
Ray Milkey2b4958a2018-02-06 18:59:06 -080097 throw new IllegalStateException("Error writing JSON to string", e);
Jonathan Hart2ddc4112015-09-16 09:28:07 -070098 }
Thomas Vachuska96d55b12015-05-11 08:52:03 -070099 }
100
101 @SuppressWarnings("unchecked")
102 private void addAll(ObjectNode root) {
103 service.getSubjectClasses()
104 .forEach(sc -> {
Jonathan Hart2ddc4112015-09-16 09:28:07 -0700105 SubjectFactory sf = service.getSubjectFactory(sc);
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700106 addSubjectClass(newObject(root, sf.subjectClassKey()), sf);
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700107 });
108 }
109
110 @SuppressWarnings("unchecked")
111 private void addSubjectClass(ObjectNode root, SubjectFactory sf) {
112 service.getSubjects(sf.subjectClass())
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700113 .forEach(s -> addSubject(newObject(root, sf.subjectKey(s)), s));
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700114 }
115
116 private void addSubject(ObjectNode root, Object s) {
Thomas Vachuskab129fbf2015-07-23 00:49:03 -0700117 service.getConfigs(s).forEach(c -> root.set(c.key(), c.node()));
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700118 }
119
Thomas Vachuska0a400ea2015-09-04 11:25:03 -0700120 private JsonNode getSubjectConfig(Config config) {
Thomas Vachuskab129fbf2015-07-23 00:49:03 -0700121 return config != null ? config.node() : null;
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700122 }
123
Jonathan Hart111b42b2015-07-14 13:28:05 -0700124 private Config getConfig(Object s, String subjectKey, String ck) {
125 Class<? extends Config> configClass = service.getConfigClass(subjectKey, ck);
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700126 return configClass != null ? service.getConfig(s, configClass) : null;
127 }
128
129 private ObjectNode newObject(ObjectNode parent, String key) {
130 ObjectNode node = mapper.createObjectNode();
131 parent.set(key, node);
132 return node;
133 }
134}