github.com/deemoprobe/k8s-first-commit@v0.0.0-20230430165612-a541f1982be3/pkg/proxy/config/file.go (about)

     1  /*
     2  Copyright 2014 Google Inc. All rights reserved.
     3  
     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  */
    16  
    17  // Reads the configuration from the file. Example file for two services [nodejs & mysql]
    18  //{"Services": [
    19  //   {
    20  //      "Name":"nodejs",
    21  //      "Port":10000,
    22  //      "Endpoints":["10.240.180.168:8000", "10.240.254.199:8000", "10.240.62.150:8000"]
    23  //   },
    24  //   {
    25  //      "Name":"mysql",
    26  //      "Port":10001,
    27  //      "Endpoints":["10.240.180.168:9000", "10.240.254.199:9000", "10.240.62.150:9000"]
    28  //   }
    29  //]
    30  //}
    31  package config
    32  
    33  import (
    34  	"bytes"
    35  	"encoding/json"
    36  	"io/ioutil"
    37  	"log"
    38  	"reflect"
    39  	"time"
    40  
    41  	"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
    42  )
    43  
    44  // TODO: kill this struct.
    45  type ServiceJSON struct {
    46  	Name      string
    47  	Port      int
    48  	Endpoints []string
    49  }
    50  type ConfigFile struct {
    51  	Services []ServiceJSON
    52  }
    53  
    54  type ConfigSourceFile struct {
    55  	serviceChannel   chan ServiceUpdate
    56  	endpointsChannel chan EndpointsUpdate
    57  	filename         string
    58  }
    59  
    60  func NewConfigSourceFile(filename string, serviceChannel chan ServiceUpdate, endpointsChannel chan EndpointsUpdate) ConfigSourceFile {
    61  	config := ConfigSourceFile{
    62  		filename:         filename,
    63  		serviceChannel:   serviceChannel,
    64  		endpointsChannel: endpointsChannel,
    65  	}
    66  	go config.Run()
    67  	return config
    68  }
    69  
    70  func (impl ConfigSourceFile) Run() {
    71  	log.Printf("Watching file %s", impl.filename)
    72  	var lastData []byte
    73  	var lastServices []api.Service
    74  	var lastEndpoints []api.Endpoints
    75  
    76  	for {
    77  		data, err := ioutil.ReadFile(impl.filename)
    78  		if err != nil {
    79  			log.Printf("Couldn't read file: %s : %v", impl.filename, err)
    80  		} else {
    81  			var config ConfigFile
    82  			err = json.Unmarshal(data, &config)
    83  			if err != nil {
    84  				log.Printf("Couldn't unmarshal configuration from file : %s %v", data, err)
    85  			} else {
    86  				if !bytes.Equal(lastData, data) {
    87  					lastData = data
    88  					// Ok, we have a valid configuration, send to channel for
    89  					// rejiggering.
    90  					newServices := make([]api.Service, len(config.Services))
    91  					newEndpoints := make([]api.Endpoints, len(config.Services))
    92  					for i, service := range config.Services {
    93  						newServices[i] = api.Service{JSONBase: api.JSONBase{ID: service.Name}, Port: service.Port}
    94  						newEndpoints[i] = api.Endpoints{Name: service.Name, Endpoints: service.Endpoints}
    95  					}
    96  					if !reflect.DeepEqual(lastServices, newServices) {
    97  						serviceUpdate := ServiceUpdate{Op: SET, Services: newServices}
    98  						impl.serviceChannel <- serviceUpdate
    99  						lastServices = newServices
   100  					}
   101  					if !reflect.DeepEqual(lastEndpoints, newEndpoints) {
   102  						endpointsUpdate := EndpointsUpdate{Op: SET, Endpoints: newEndpoints}
   103  						impl.endpointsChannel <- endpointsUpdate
   104  						lastEndpoints = newEndpoints
   105  					}
   106  				}
   107  			}
   108  		}
   109  		time.Sleep(5 * time.Second)
   110  	}
   111  }