github.com/nuvolaris/nuv@v0.0.0-20240511174247-a74e3a52bfd8/config/config_map_builder.go (about)

     1  // Licensed to the Apache Software Foundation (ASF) under one
     2  // or more contributor license agreements.  See the NOTICE file
     3  // distributed with this work for additional information
     4  // regarding copyright ownership.  The ASF licenses this file
     5  // to you under the Apache License, Version 2.0 (the
     6  // "License"); you may not use this file except in compliance
     7  // with the License.  You may obtain a copy of the License at
     8  //
     9  //   http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing,
    12  // software distributed under the License is distributed on an
    13  // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    14  // KIND, either express or implied.  See the License for the
    15  // specific language governing permissions and limitations
    16  // under the License.
    17  
    18  package config
    19  
    20  import (
    21  	"encoding/json"
    22  	"log"
    23  	"os"
    24  )
    25  
    26  type configMapBuilder struct {
    27  	configJsonPath string
    28  	nuvRootPath    string
    29  	pluginNuvRoots map[string]string
    30  }
    31  
    32  func NewConfigMapBuilder() *configMapBuilder {
    33  	return &configMapBuilder{
    34  		pluginNuvRoots: make(map[string]string),
    35  	}
    36  }
    37  
    38  // WithConfigJson adds a config.json file that will be read and used
    39  // to build a ConfigMap. If there both a config.json and a nuvroot.json are
    40  // added, the 2 configs will be merged. It assumes the input file
    41  // is valid.
    42  func (b *configMapBuilder) WithConfigJson(file string) *configMapBuilder {
    43  	b.configJsonPath = file
    44  	return b
    45  }
    46  
    47  // WithNuvRoot works like WithConfigJson, with the difference that
    48  // the NuvRoot is read and only it's inner "config":{} object is parsed
    49  // ignoring the rest of the content.
    50  func (b *configMapBuilder) WithNuvRoot(file string) *configMapBuilder {
    51  	b.nuvRootPath = file
    52  	return b
    53  }
    54  
    55  // WithPluginNuvRoots works like WithPluginNuvRoot, but it allows to add multiple
    56  // plugin nuvroot.json files at once.
    57  func (b *configMapBuilder) WithPluginNuvRoots(nrts map[string]string) *configMapBuilder {
    58  	b.pluginNuvRoots = nrts
    59  	return b
    60  }
    61  
    62  func (b *configMapBuilder) Build() (ConfigMap, error) {
    63  	configJsonMap, err := readConfig(b.configJsonPath, fromConfigJson)
    64  	if err != nil {
    65  		return ConfigMap{}, err
    66  	}
    67  
    68  	nuvRootMap, err := readConfig(b.nuvRootPath, fromNuvRoot)
    69  	if err != nil {
    70  		return ConfigMap{}, err
    71  	}
    72  
    73  	pluginNuvRootConfigs := make(map[string]map[string]interface{}, 0)
    74  	for plgName, nuvRootPath := range b.pluginNuvRoots {
    75  		pluginNuvRootMap, err := readConfig(nuvRootPath, fromNuvRoot)
    76  		if err != nil {
    77  			return ConfigMap{}, err
    78  		}
    79  		pluginNuvRootConfigs[plgName] = pluginNuvRootMap
    80  	}
    81  
    82  	return ConfigMap{
    83  		pluginNuvRootConfigs: pluginNuvRootConfigs,
    84  		nuvRootConfig:        nuvRootMap,
    85  		config:               configJsonMap,
    86  		configPath:           b.configJsonPath,
    87  	}, nil
    88  }
    89  
    90  func readConfig(path string, read func(string) (map[string]interface{}, error)) (map[string]interface{}, error) {
    91  	if path == "" {
    92  		return make(map[string]interface{}), nil
    93  	}
    94  
    95  	_, err := os.Stat(path)
    96  	if os.IsNotExist(err) {
    97  		return make(map[string]interface{}), nil
    98  	}
    99  	if err != nil {
   100  		return nil, err
   101  	}
   102  
   103  	cMap, err := read(path)
   104  	if err != nil {
   105  		return nil, err
   106  	}
   107  
   108  	return cMap, nil
   109  }
   110  
   111  func fromConfigJson(configPath string) (map[string]interface{}, error) {
   112  	data := make(map[string]interface{})
   113  	json_buf, err := os.ReadFile(configPath)
   114  	if err != nil {
   115  		return data, err
   116  	}
   117  	if err := json.Unmarshal(json_buf, &data); err != nil {
   118  		if data == nil {
   119  			return data, err
   120  		}
   121  		log.Println("config.json parsed with an error", err)
   122  	}
   123  
   124  	return data, nil
   125  }
   126  
   127  func fromNuvRoot(nuvRootPath string) (map[string]interface{}, error) {
   128  	data := make(map[string]interface{})
   129  	json_buf, err := os.ReadFile(nuvRootPath)
   130  	if err != nil {
   131  		return data, err
   132  	}
   133  	if err := json.Unmarshal(json_buf, &data); err != nil {
   134  		if data == nil {
   135  			return data, err
   136  		}
   137  		log.Println("nuvroot.json parsed with an error", err)
   138  	}
   139  
   140  	cm, ok := data["config"].(map[string]interface{})
   141  	if !ok {
   142  		return nil, nil
   143  	}
   144  	return cm, nil
   145  }