blob: fad93ef58cc4c2e0307e733038c77bb2ff10e851 [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;
Ray Milkey0068fd02018-10-11 15:45:39 -070024import org.apache.karaf.shell.api.action.Completion;
Ray Milkeyd84f89b2018-08-17 14:54:17 -070025import org.apache.karaf.shell.api.action.lifecycle.Service;
26import org.apache.karaf.shell.api.action.Option;
Thomas Vachuska96d55b12015-05-11 08:52:03 -070027import org.onosproject.cli.AbstractShellCommand;
Ray Milkeya4122362015-08-18 15:19:08 -070028import org.onosproject.net.config.Config;
29import org.onosproject.net.config.NetworkConfigService;
30import org.onosproject.net.config.SubjectFactory;
Thomas Vachuska96d55b12015-05-11 08:52:03 -070031
32import static com.google.common.base.Strings.isNullOrEmpty;
kavitha Alagesan1f1fef72016-12-08 17:07:12 +053033import static org.onlab.util.Tools.nullIsIllegal;
Thomas Vachuska96d55b12015-05-11 08:52:03 -070034
35/**
36 * Manages network configuration.
37 */
Ray Milkeyd84f89b2018-08-17 14:54:17 -070038@Service
Thomas Vachuska96d55b12015-05-11 08:52:03 -070039@Command(scope = "onos", name = "netcfg",
40 description = "Manages network configuration")
41public class NetworkConfigCommand extends AbstractShellCommand {
42
kavitha Alagesan1f1fef72016-12-08 17:07:12 +053043 private static final String E_CLASSKEY_NOT_REGISTERED = " is not a registered SubjectClassKey";
44
Thomas Vachuskaea5adc62015-10-07 11:52:30 -070045 @Argument(index = 0, name = "subjectClassKey", description = "Subject class key",
46 required = false, multiValued = false)
Ray Milkey0068fd02018-10-11 15:45:39 -070047 @Completion(ComponentConfigCommandCompleter.class)
Thomas Vachuskaea5adc62015-10-07 11:52:30 -070048 String subjectClassKey = null;
49
50 @Argument(index = 1, name = "subjectKey", description = "Subject key",
Thomas Vachuska96d55b12015-05-11 08:52:03 -070051 required = false, multiValued = false)
Ray Milkey0068fd02018-10-11 15:45:39 -070052 @Completion(ComponentNameCompleter.class)
Thomas Vachuska96d55b12015-05-11 08:52:03 -070053 String subjectKey = null;
54
Thomas Vachuska96d55b12015-05-11 08:52:03 -070055 @Argument(index = 2, name = "configKey", description = "Config key",
56 required = false, multiValued = false)
Ray Milkey0068fd02018-10-11 15:45:39 -070057 @Completion(ConfigKeyCompleter.class)
Thomas Vachuska96d55b12015-05-11 08:52:03 -070058 String configKey = null;
59
Yuta HIGUCHI5d025c32017-03-13 20:32:48 -070060 @Option(name = "--remove",
61 description = "Remove specified configuration tree",
62 required = false)
63 private boolean remove = false;
64
Thomas Vachuska96d55b12015-05-11 08:52:03 -070065 private final ObjectMapper mapper = new ObjectMapper();
66 private NetworkConfigService service;
67
68 @Override
Ray Milkeyd84f89b2018-08-17 14:54:17 -070069 protected void doExecute() {
Thomas Vachuska96d55b12015-05-11 08:52:03 -070070 service = get(NetworkConfigService.class);
Jonathan Hart2ddc4112015-09-16 09:28:07 -070071 JsonNode root = mapper.createObjectNode();
Thomas Vachuskaea5adc62015-10-07 11:52:30 -070072 if (isNullOrEmpty(subjectClassKey)) {
Yuta HIGUCHI5d025c32017-03-13 20:32:48 -070073 if (remove) {
74 service.removeConfig();
75 }
Thomas Vachuska0a400ea2015-09-04 11:25:03 -070076 addAll((ObjectNode) root);
Thomas Vachuska96d55b12015-05-11 08:52:03 -070077 } else {
kavitha Alagesan1f1fef72016-12-08 17:07:12 +053078 SubjectFactory subjectFactory = nullIsIllegal(service.getSubjectFactory(subjectClassKey),
79 subjectClassKey + E_CLASSKEY_NOT_REGISTERED);
Thomas Vachuskaea5adc62015-10-07 11:52:30 -070080 if (isNullOrEmpty(subjectKey)) {
Thomas Vachuska0a400ea2015-09-04 11:25:03 -070081 addSubjectClass((ObjectNode) root, subjectFactory);
Thomas Vachuska96d55b12015-05-11 08:52:03 -070082 } else {
Thomas Vachuskaea5adc62015-10-07 11:52:30 -070083 Object s = subjectFactory.createSubject(subjectKey);
Thomas Vachuska96d55b12015-05-11 08:52:03 -070084 if (isNullOrEmpty(configKey)) {
Yuta HIGUCHI5d025c32017-03-13 20:32:48 -070085 if (remove) {
86 service.removeConfig(s);
87 }
Thomas Vachuska0a400ea2015-09-04 11:25:03 -070088 addSubject((ObjectNode) root, s);
Thomas Vachuska96d55b12015-05-11 08:52:03 -070089 } else {
Yuta HIGUCHI5d025c32017-03-13 20:32:48 -070090 if (remove) {
91 service.removeConfig(subjectClassKey, s, configKey);
92 }
Thomas Vachuskaea5adc62015-10-07 11:52:30 -070093 root = getSubjectConfig(getConfig(s, subjectClassKey, configKey));
Thomas Vachuska96d55b12015-05-11 08:52:03 -070094 }
95 }
96 }
Jonathan Hart2ddc4112015-09-16 09:28:07 -070097
98 try {
99 print("%s", mapper.writerWithDefaultPrettyPrinter().writeValueAsString(root));
100 } catch (JsonProcessingException e) {
Ray Milkey2b4958a2018-02-06 18:59:06 -0800101 throw new IllegalStateException("Error writing JSON to string", e);
Jonathan Hart2ddc4112015-09-16 09:28:07 -0700102 }
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700103 }
104
105 @SuppressWarnings("unchecked")
106 private void addAll(ObjectNode root) {
107 service.getSubjectClasses()
108 .forEach(sc -> {
Jonathan Hart2ddc4112015-09-16 09:28:07 -0700109 SubjectFactory sf = service.getSubjectFactory(sc);
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700110 addSubjectClass(newObject(root, sf.subjectClassKey()), sf);
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700111 });
112 }
113
114 @SuppressWarnings("unchecked")
115 private void addSubjectClass(ObjectNode root, SubjectFactory sf) {
116 service.getSubjects(sf.subjectClass())
Thomas Vachuskaea5adc62015-10-07 11:52:30 -0700117 .forEach(s -> addSubject(newObject(root, sf.subjectKey(s)), s));
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700118 }
119
120 private void addSubject(ObjectNode root, Object s) {
Thomas Vachuskab129fbf2015-07-23 00:49:03 -0700121 service.getConfigs(s).forEach(c -> root.set(c.key(), c.node()));
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700122 }
123
Thomas Vachuska0a400ea2015-09-04 11:25:03 -0700124 private JsonNode getSubjectConfig(Config config) {
Thomas Vachuskab129fbf2015-07-23 00:49:03 -0700125 return config != null ? config.node() : null;
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700126 }
127
Jonathan Hart111b42b2015-07-14 13:28:05 -0700128 private Config getConfig(Object s, String subjectKey, String ck) {
129 Class<? extends Config> configClass = service.getConfigClass(subjectKey, ck);
Thomas Vachuska96d55b12015-05-11 08:52:03 -0700130 return configClass != null ? service.getConfig(s, configClass) : null;
131 }
132
133 private ObjectNode newObject(ObjectNode parent, String key) {
134 ObjectNode node = mapper.createObjectNode();
135 parent.set(key, node);
136 return node;
137 }
138}