github.com/fnproject/cli@v0.0.0-20240508150455-e5d88bd86117/commands/migrate.go (about) 1 /* 2 * Copyright (c) 2019, 2020 Oracle and/or its affiliates. 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 package commands 18 19 import ( 20 "errors" 21 "fmt" 22 "io/ioutil" 23 "os" 24 "path/filepath" 25 26 "github.com/fnproject/cli/common" 27 "github.com/fnproject/cli/config" 28 yamltojson "github.com/ghodss/yaml" 29 "github.com/mitchellh/mapstructure" 30 "github.com/urfave/cli" 31 yaml "gopkg.in/yaml.v2" 32 ) 33 34 const ( 35 MigrateSuccessMessage = "Successfully migrated func.yaml and created a back up func.yaml.bak" 36 MigrateFailureMessage = "you have an up to date func.yaml file and do not need to migrate" 37 ) 38 39 type migrateFnCmd struct { 40 newFF *common.FuncFileV20180708 41 } 42 43 func MigrateCommand() cli.Command { 44 m := &migrateFnCmd{newFF: &common.FuncFileV20180708{}} 45 46 return cli.Command{ 47 Name: "migrate", 48 Usage: "\tMigrate a local func.yaml file to the latest version", 49 Category: "DEVELOPMENT COMMANDS", 50 Aliases: []string{"m"}, 51 Description: "This command will detect the version of a func.yaml file and update it to match the latest version supported by the Fn CLI.\n\tAny old or unsupported attributes will be removed, and any new ones may be added.\n\tThe current func.yaml will be renamed to func.yaml.bak and a new func.yaml created.", 52 Action: m.migrate, 53 } 54 } 55 56 func (m *migrateFnCmd) migrate(c *cli.Context) error { 57 var err error 58 oldFF, err := common.ReadInFuncFile() 59 if err != nil { 60 return err 61 } 62 63 version := common.GetFuncYamlVersion(oldFF) 64 if version == common.LatestYamlVersion { 65 return errors.New(MigrateFailureMessage) 66 } 67 68 err = backUpYamlFile(oldFF) 69 if err != nil { 70 return err 71 } 72 73 b, err := m.creatFuncFileBytes(oldFF) 74 if err != nil { 75 return err 76 } 77 78 err = vaidateFuncFileSchema(b) 79 if err != nil { 80 return err 81 } 82 83 err = writeYamlFile(b, "func.yaml") 84 if err != nil { 85 return err 86 } 87 88 fmt.Println(MigrateSuccessMessage) 89 return nil 90 } 91 92 func backUpYamlFile(ff map[string]interface{}) error { 93 b, err := yaml.Marshal(ff) 94 if err != nil { 95 return err 96 } 97 98 return writeYamlFile(b, "func.yaml.bak") 99 } 100 101 func (m *migrateFnCmd) decodeFuncFile(oldFF map[string]interface{}) ([]byte, error) { 102 _ = mapstructure.Decode(oldFF, &m.newFF) 103 return yaml.Marshal(oldFF) 104 } 105 106 func (m *migrateFnCmd) creatFuncFileBytes(oldFF map[string]interface{}) ([]byte, error) { 107 b, err := m.decodeFuncFile(oldFF) 108 if err != nil { 109 return nil, err 110 } 111 112 err = vaidateFuncFileSchema(b) 113 if err != nil { 114 return nil, err 115 } 116 117 m.newFF.Schema_version = 20180708 118 trig := make([]common.Trigger, 1) 119 120 var trigName, trigSource string 121 122 if oldFF["name"] != nil { 123 trigName = oldFF["name"].(string) 124 trigSource = "/" + oldFF["name"].(string) 125 } 126 127 trigType := "http" 128 129 trig[0] = common.Trigger{ 130 trigName, 131 trigType, 132 trigSource, 133 } 134 m.newFF.Triggers = trig 135 136 return yaml.Marshal(m.newFF) 137 } 138 139 func vaidateFuncFileSchema(b []byte) error { 140 jsonB, err := yamltojson.YAMLToJSON(b) 141 if err != nil { 142 return err 143 } 144 145 err = ioutil.WriteFile("temp.json", jsonB, config.ReadWritePerms) 146 if err != nil { 147 return err 148 } 149 defer os.Remove("temp.json") 150 151 err = common.ValidateFileAgainstSchema("temp.json", common.V20180708Schema) 152 if err != nil { 153 return err 154 } 155 156 return nil 157 } 158 159 func writeYamlFile(b []byte, filename string) error { 160 wd := common.GetWd() 161 fpath := filepath.Join(wd, filename) 162 163 return ioutil.WriteFile(fpath, b, config.ReadWritePerms) 164 }