github.com/hazelops/ize@v1.1.12-0.20230915191306-97d7c0e48f11/internal/requirements/requirements.go (about) 1 package requirements 2 3 import ( 4 "errors" 5 "fmt" 6 "github.com/Masterminds/semver" 7 "github.com/pterm/pterm" 8 "github.com/sirupsen/logrus" 9 "github.com/spf13/viper" 10 "os" 11 "path/filepath" 12 "strings" 13 ) 14 15 type requirements struct { 16 configFile bool 17 ssmplugin bool 18 structure bool 19 nvm bool 20 } 21 22 func CheckRequirements(options ...Option) error { 23 r := requirements{} 24 for _, opt := range options { 25 opt(&r) 26 } 27 28 if r.nvm { 29 err := checkNVM() 30 if err != nil { 31 return err 32 } 33 } 34 35 if r.structure { 36 if !isStructured() { 37 pterm.Warning.Println("is not an ize-structured directory. Please run ize init or cd into an ize-structured directory.") 38 } 39 } 40 41 if r.ssmplugin { 42 if err := checkSessionManagerPlugin(); err != nil { 43 return err 44 } 45 } 46 47 switch viper.GetString("prefer_runtime") { 48 case "native": 49 logrus.Debug("use native runtime") 50 case "docker": 51 if err := checkDocker(); err != nil { 52 return err 53 } 54 logrus.Debug("use docker runtime") 55 default: 56 return fmt.Errorf("unknown runtime type: %s", viper.GetString("prefer_runtime")) 57 } 58 59 if len(viper.ConfigFileUsed()) == 0 && r.configFile { 60 return fmt.Errorf("this command requires a config file. Please add ize.toml to %s", viper.GetString("env_dir")) 61 } 62 63 return nil 64 } 65 66 type Option func(*requirements) 67 68 func WithIzeStructure() Option { 69 return func(r *requirements) { 70 r.structure = true 71 } 72 } 73 74 func WithConfigFile() Option { 75 return func(r *requirements) { 76 r.configFile = true 77 } 78 } 79 80 func WithSSMPlugin() Option { 81 return func(r *requirements) { 82 r.ssmplugin = true 83 } 84 } 85 86 func WithNVM() Option { 87 return func(r *requirements) { 88 r.nvm = true 89 } 90 } 91 92 func checkNVM() error { 93 if len(os.Getenv("NVM_DIR")) == 0 { 94 return errors.New("nvm is not installed (visit https://github.com/nvm-sh/nvm)") 95 } 96 97 return nil 98 } 99 100 func checkDocker() error { 101 exist, _ := CheckCommand("docker", []string{"info"}) 102 if !exist { 103 return errors.New("docker is not running or is not installed (visit https://www.docker.com/get-started)") 104 } 105 106 return nil 107 } 108 109 func isStructured() bool { 110 var isStructured = false 111 112 cwd, err := os.Getwd() 113 if err != nil { 114 logrus.Fatalln("can't initialize config: %w", err) 115 } 116 117 _, err = os.Stat(filepath.Join(cwd, ".ize")) 118 if !os.IsNotExist(err) { 119 isStructured = true 120 } 121 122 _, err = os.Stat(filepath.Join(cwd, ".infra")) 123 if !os.IsNotExist(err) { 124 isStructured = true 125 } 126 127 return isStructured 128 } 129 130 func checkSessionManagerPlugin() error { 131 exist, _ := CheckCommand("session-manager-plugin", []string{}) 132 if !exist { 133 pterm.Warning.Println("SSM Agent plugin is not installed. Trying to install SSM Agent plugin") 134 135 var pyVersion string 136 137 exist, pyVersion := CheckCommand("python3", []string{"--version"}) 138 if !exist { 139 exist, pyVersion = CheckCommand("python", []string{"--version"}) 140 if !exist { 141 return errors.New("python is not installed") 142 } 143 144 c, err := semver.NewConstraint("<= 2.6.5") 145 if err != nil { 146 return err 147 } 148 149 v, err := semver.NewVersion(strings.TrimSpace(strings.Split(pyVersion, " ")[1])) 150 if err != nil { 151 return err 152 } 153 154 if c.Check(v) { 155 return fmt.Errorf("python version %s below required %s", v.String(), "2.6.5") 156 } 157 return errors.New("python is not installed") 158 } 159 160 c, err := semver.NewConstraint("<= 3.3.0") 161 if err != nil { 162 return err 163 } 164 165 v, err := semver.NewVersion(strings.TrimSpace(strings.Split(pyVersion, " ")[1])) 166 if err != nil { 167 return err 168 } 169 170 if c.Check(v) { 171 return fmt.Errorf("python version %s below required %s", v.String(), "3.3.0") 172 } 173 174 pterm.DefaultSection.Println("Installing SSM Agent plugin") 175 176 err = downloadSSMAgentPlugin() 177 if err != nil { 178 return fmt.Errorf("download SSM Agent plugin error: %v (visit https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html)", err) 179 } 180 181 pterm.Success.Println("Downloading SSM Agent plugin") 182 183 err = installSSMAgent() 184 if err != nil { 185 return fmt.Errorf("install SSM Agent plugin error: %v (visit https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html)", err) 186 } 187 188 pterm.Success.Println("Installing SSM Agent plugin") 189 190 err = cleanupSSMAgent() 191 if err != nil { 192 return fmt.Errorf("cleanup SSM Agent plugin error: %v (visit https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html)", err) 193 } 194 195 pterm.Success.Println("Cleanup Session Manager plugin installation package") 196 197 exist, _ = CheckCommand("session-manager-plugin", []string{}) 198 if !exist { 199 return fmt.Errorf("check SSM Agent plugin error: %v (visit https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html)", err) 200 } 201 } 202 203 return nil 204 }