github.com/cs3org/reva/v2@v2.27.7/pkg/metrics/driver/xcloud/xcloud.go (about) 1 // Copyright 2018-2020 CERN 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // In applying this license, CERN does not waive the privileges and immunities 16 // granted to it by virtue of its status as an Intergovernmental Organization 17 // or submit itself to any jurisdiction. 18 19 package json 20 21 import ( 22 "crypto/tls" 23 "encoding/json" 24 "errors" 25 "fmt" 26 "io" 27 "net/http" 28 "os" 29 "sync" 30 "time" 31 32 "github.com/cs3org/reva/v2/pkg/metrics/driver/registry" 33 34 "github.com/rs/zerolog" 35 36 "github.com/cs3org/reva/v2/pkg/logger" 37 "github.com/cs3org/reva/v2/pkg/metrics/config" 38 ) 39 40 var log zerolog.Logger 41 42 func init() { 43 log = logger.New().With().Int("pid", os.Getpid()).Logger() 44 driver := &CloudDriver{CloudData: &CloudData{}} 45 registry.Register(driverName(), driver) 46 } 47 48 func driverName() string { 49 return "xcloud" 50 } 51 52 // CloudDriver is the driver to use for Sciencemesh apps 53 type CloudDriver struct { 54 instance string 55 pullInterval int 56 CloudData *CloudData 57 sync.Mutex 58 client *http.Client 59 } 60 61 func (d *CloudDriver) refresh() error { 62 // endpoint example: https://mybox.com or https://mybox.com/owncloud 63 endpoint := fmt.Sprintf("%s/index.php/apps/sciencemesh/internal_metrics", d.instance) 64 65 req, err := http.NewRequest("GET", endpoint, nil) 66 if err != nil { 67 log.Err(err).Msgf("xcloud: error creating request to %s", d.instance) 68 return err 69 } 70 71 resp, err := d.client.Do(req) 72 if err != nil { 73 log.Err(err).Msgf("xcloud: error getting internal metrics from %s", d.instance) 74 return err 75 } 76 77 if resp.StatusCode != http.StatusOK { 78 err := fmt.Errorf("xcloud: error getting internal metrics from %s. http status code (%d)", d.instance, resp.StatusCode) 79 log.Err(err).Msgf("xcloud: error getting internal metrics from %s", d.instance) 80 return err 81 } 82 defer resp.Body.Close() 83 84 // read response body 85 data, err := io.ReadAll(resp.Body) 86 if err != nil { 87 log.Err(err).Msgf("xcloud: error reading resp body from internal metrics from %s", d.instance) 88 return err 89 } 90 91 cd := &CloudData{} 92 if err := json.Unmarshal(data, cd); err != nil { 93 log.Err(err).Msgf("xcloud: error parsing body from internal metrics: body(%s)", string(data)) 94 return err 95 } 96 97 d.Lock() 98 defer d.Unlock() 99 d.CloudData = cd 100 log.Info().Msgf("xcloud: received internal metrics from cloud provider: %+v", cd) 101 102 return nil 103 } 104 105 // Configure configures this driver 106 func (d *CloudDriver) Configure(c *config.Config) error { 107 if c.XcloudInstance == "" { 108 err := errors.New("xcloud: missing xcloud_instance config parameter") 109 return err 110 } 111 112 if c.XcloudPullInterval == 0 { 113 c.XcloudPullInterval = 5 // seconds 114 } 115 116 d.instance = c.XcloudInstance 117 d.pullInterval = c.XcloudPullInterval 118 119 tr := &http.Transport{ 120 TLSClientConfig: &tls.Config{InsecureSkipVerify: c.InsecureSkipVerify}, 121 } 122 client := &http.Client{Transport: tr} 123 124 d.client = client 125 126 ticker := time.NewTicker(time.Duration(d.pullInterval) * time.Second) 127 quit := make(chan struct{}) 128 go func() { 129 for { 130 select { 131 case <-ticker.C: 132 err := d.refresh() 133 if err != nil { 134 log.Err(err).Msgf("xcloud: error from refresh goroutine") 135 } 136 case <-quit: 137 ticker.Stop() 138 return 139 } 140 } 141 }() 142 143 return nil 144 } 145 146 // GetNumUsers returns the number of site users 147 func (d *CloudDriver) GetNumUsers() int64 { 148 return d.CloudData.Metrics.TotalUsers 149 } 150 151 // GetNumGroups returns the number of site groups 152 func (d *CloudDriver) GetNumGroups() int64 { 153 return d.CloudData.Metrics.TotalGroups 154 } 155 156 // GetAmountStorage returns the amount of site storage used 157 func (d *CloudDriver) GetAmountStorage() int64 { 158 return d.CloudData.Metrics.TotalStorage 159 } 160 161 // CloudData represents the information obtained from the sciencemesh app 162 type CloudData struct { 163 Metrics CloudDataMetrics `json:"metrics"` 164 Settings CloudDataSettings `json:"settings"` 165 } 166 167 // CloudDataMetrics reprents the metrics gathered from the sciencemesh app 168 type CloudDataMetrics struct { 169 TotalUsers int64 `json:"numusers"` 170 TotalGroups int64 `json:"numgroups"` 171 TotalStorage int64 `json:"numstorage"` 172 } 173 174 // CloudDataSettings represents the metrics gathered 175 type CloudDataSettings struct { 176 IOPUrl string `json:"iopurl"` 177 Sitename string `json:"sitename"` 178 Siteurl string `json:"siteurl"` 179 Country string `json:"country"` 180 }