2019-05-28 18:51:53 +00:00
package metadata
import (
"context"
2020-02-13 22:55:19 +00:00
"fmt"
"io/ioutil"
"net/http"
"os"
2019-05-28 18:51:53 +00:00
"strings"
2020-02-13 22:55:19 +00:00
"time"
"github.com/sirupsen/logrus"
2019-05-28 18:51:53 +00:00
mVersion "github.com/mcuadros/go-version"
2020-02-13 22:55:19 +00:00
"github.com/rancher/rke/data"
v3 "github.com/rancher/types/apis/management.cattle.io/v3"
"github.com/rancher/types/kdm"
)
const (
RancherMetadataURLEnv = "RANCHER_METADATA_URL"
2019-05-28 18:51:53 +00:00
)
var (
RKEVersion string
DefaultK8sVersion string
K8sVersionToTemplates map [ string ] map [ string ] string
K8sVersionToRKESystemImages map [ string ] v3 . RKESystemImages
K8sVersionToServiceOptions map [ string ] v3 . KubernetesServicesOptions
2019-07-15 17:58:09 +00:00
K8sVersionToDockerVersions map [ string ] [ ] string
2019-05-28 18:51:53 +00:00
K8sVersionsCurrent [ ] string
K8sBadVersions = map [ string ] bool { }
2019-07-05 04:23:48 +00:00
K8sVersionToWindowsServiceOptions map [ string ] v3 . KubernetesServicesOptions
2020-02-13 22:55:19 +00:00
c = http . Client {
Timeout : time . Second * 30 ,
}
2019-05-28 18:51:53 +00:00
)
func InitMetadata ( ctx context . Context ) error {
2020-02-13 22:55:19 +00:00
data , err := loadData ( )
if err != nil {
return fmt . Errorf ( "failed to load data.json, error: %v" , err )
}
initK8sRKESystemImages ( data )
initAddonTemplates ( data )
initServiceOptions ( data )
initDockerOptions ( data )
2019-05-28 18:51:53 +00:00
return nil
}
2020-02-13 22:55:19 +00:00
// this method loads metadata from three place, if RANCHER_METADATA_URL is provided then load data from specified location. Otherwise load data from bindata.
func loadData ( ) ( kdm . Data , error ) {
var b [ ] byte
var err error
u := os . Getenv ( RancherMetadataURLEnv )
if u != "" {
logrus . Debugf ( "Loading data.json from %s, timestamp: %s" , u , time . Now ( ) . Format ( time . RFC822 ) )
b , err = readFile ( u )
if err != nil {
return kdm . Data { } , err
}
} else {
logrus . Debugf ( "Logging data.json from local source, timestamp: %s" , time . Now ( ) . Format ( time . RFC822 ) )
b , err = data . Asset ( "data/data.json" )
if err != nil {
return kdm . Data { } , err
}
}
logrus . Debugf ( "data.json content: %v" , string ( b ) )
return kdm . FromData ( b )
}
func readFile ( file string ) ( [ ] byte , error ) {
if strings . HasPrefix ( file , "http" ) {
resp , err := c . Get ( file )
if err != nil {
return nil , err
}
defer resp . Body . Close ( )
return ioutil . ReadAll ( resp . Body )
}
return ioutil . ReadFile ( file )
}
2019-08-22 17:00:18 +00:00
const RKEVersionDev = "v0.2.3"
2019-05-28 18:51:53 +00:00
2020-02-13 22:55:19 +00:00
func initAddonTemplates ( data kdm . Data ) {
K8sVersionToTemplates = data . K8sVersionedTemplates
2019-05-28 18:51:53 +00:00
}
2020-02-13 22:55:19 +00:00
func initServiceOptions ( data kdm . Data ) {
K8sVersionToServiceOptions = interface { } ( data . K8sVersionServiceOptions ) . ( map [ string ] v3 . KubernetesServicesOptions )
K8sVersionToWindowsServiceOptions = data . K8sVersionWindowsServiceOptions
2019-05-28 18:51:53 +00:00
}
2020-02-13 22:55:19 +00:00
func initDockerOptions ( data kdm . Data ) {
K8sVersionToDockerVersions = data . K8sVersionDockerInfo
2019-07-15 17:58:09 +00:00
}
2020-02-13 22:55:19 +00:00
func initK8sRKESystemImages ( data kdm . Data ) {
2019-05-28 18:51:53 +00:00
K8sVersionToRKESystemImages = map [ string ] v3 . RKESystemImages { }
2020-02-13 22:55:19 +00:00
rkeData := data
2019-05-28 18:51:53 +00:00
// non released versions
if RKEVersion == "" {
RKEVersion = RKEVersionDev
}
DefaultK8sVersion = rkeData . RKEDefaultK8sVersions [ "default" ]
2019-08-22 17:00:18 +00:00
if defaultK8sVersion , ok := rkeData . RKEDefaultK8sVersions [ RKEVersion [ 1 : ] ] ; ok {
2019-05-28 18:51:53 +00:00
DefaultK8sVersion = defaultK8sVersion
}
maxVersionForMajorK8sVersion := map [ string ] string { }
for k8sVersion , systemImages := range rkeData . K8sVersionRKESystemImages {
rkeVersionInfo , ok := rkeData . K8sVersionInfo [ k8sVersion ]
if ok {
// RKEVersion = 0.2.4, DeprecateRKEVersion = 0.2.2
if rkeVersionInfo . DeprecateRKEVersion != "" && mVersion . Compare ( RKEVersion , rkeVersionInfo . DeprecateRKEVersion , ">=" ) {
K8sBadVersions [ k8sVersion ] = true
continue
}
// RKEVersion = 0.2.4, MinVersion = 0.2.5, don't store
lowerThanMin := rkeVersionInfo . MinRKEVersion != "" && mVersion . Compare ( RKEVersion , rkeVersionInfo . MinRKEVersion , "<" )
if lowerThanMin {
continue
}
}
// store all for upgrades
K8sVersionToRKESystemImages [ k8sVersion ] = interface { } ( systemImages ) . ( v3 . RKESystemImages )
majorVersion := getTagMajorVersion ( k8sVersion )
maxVersionInfo , ok := rkeData . K8sVersionInfo [ majorVersion ]
if ok {
// RKEVersion = 0.2.4, MaxVersion = 0.2.3, don't use in current
greaterThanMax := maxVersionInfo . MaxRKEVersion != "" && mVersion . Compare ( RKEVersion , maxVersionInfo . MaxRKEVersion , ">" )
if greaterThanMax {
continue
}
}
2019-08-22 00:01:55 +00:00
if curr , ok := maxVersionForMajorK8sVersion [ majorVersion ] ; ! ok || mVersion . Compare ( k8sVersion , curr , ">" ) {
2019-05-28 18:51:53 +00:00
maxVersionForMajorK8sVersion [ majorVersion ] = k8sVersion
}
}
for _ , k8sVersion := range maxVersionForMajorK8sVersion {
K8sVersionsCurrent = append ( K8sVersionsCurrent , k8sVersion )
}
}
func getTagMajorVersion ( tag string ) string {
splitTag := strings . Split ( tag , "." )
if len ( splitTag ) < 2 {
return ""
}
return strings . Join ( splitTag [ : 2 ] , "." )
}