fix(tools): безопасная генерация YAML — staging + атомарная замена, без легаси-фолбэков
01_generate_yamls.sh: - генерация в staging-каталог; рабочий каталог не удаляется заранее; атомарная замена (mv) только при полном успехе, старый каталог → бэкап resources_yaml.bak-<UTC> (ротация KEEP_BACKUPS=5); - убран легаси-фолбэк токена 'ls -t ROOT/*.token' (подхватывал чужой токен); - NUBES_API_ENDPOINT обязателен (убран молчаливый PROD-дефолт); - имя сервиса берётся из 2-го поля services_list.txt (убран лишний HTTP-запрос); - убран безусловный rm старого YAML перед генерацией (неатомарность); - удалён дубль SERVICES_FILE_DEFAULT; маркер .stand защищает от чужого стенда; - синхронизированы комментарии (REQUEST_DELAY 0.5, пути, формат списка). yaml-generator/internal/config: - NUBES_API_ENDPOINT обязателен (убран PROD-дефолт); - убран легаси-поиск последнего *.token в корне репо (loadToken/findLatestToken); - убран несуществующий путь provider/devops/config/services_list.txt (теперь требуется явный NUBES_SERVICES_FILE); - удалены мёртвые getenvDefault/findLatestToken. Проверено: bash -n OK, go vet/go build OK.
This commit is contained in:
@@ -30,7 +30,12 @@ type ServiceRef struct {
|
||||
|
||||
// Load читает конфигурацию из переменных окружения и файлов.
|
||||
func Load() (Config, error) {
|
||||
apiEndpoint := getenvDefault("NUBES_API_ENDPOINT", "https://lk-api-gateway.ngcloud.ru/api/v1/svc")
|
||||
// Endpoint ОБЯЗАТЕЛЕН. Легаси-дефолт на PROD gateway удален (2026-09-30):
|
||||
// провайдер не должен молча ходить в прод при незаданном endpoint.
|
||||
apiEndpoint := strings.TrimSpace(os.Getenv("NUBES_API_ENDPOINT"))
|
||||
if apiEndpoint == "" {
|
||||
return Config{}, errors.New("NUBES_API_ENDPOINT is required (no default: refusing to guess a stand endpoint)")
|
||||
}
|
||||
apiEndpoint = normalize.APIEndpoint(apiEndpoint)
|
||||
apiToken, err := loadToken()
|
||||
if err != nil {
|
||||
@@ -51,13 +56,11 @@ func Load() (Config, error) {
|
||||
|
||||
services := []ServiceRef{}
|
||||
if singleID == 0 {
|
||||
// Без per-service ID нужен явный список. Угадывание пути удалено (2026-09-30):
|
||||
// старый дефолт указывал на несуществующий provider/devops/config/services_list.txt.
|
||||
listPath := strings.TrimSpace(os.Getenv("NUBES_SERVICES_FILE"))
|
||||
if listPath == "" {
|
||||
repoRoot, err := FindRepoRoot()
|
||||
if err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
listPath = filepath.Join(repoRoot, "devops", "config", "services_list.txt")
|
||||
return Config{}, errors.New("NUBES_SERVICES_FILE is required when NUBES_SERVICE_ID is not set")
|
||||
}
|
||||
list, err := ReadServicesList(listPath)
|
||||
if err != nil {
|
||||
@@ -76,14 +79,6 @@ func Load() (Config, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getenvDefault(key string, def string) string {
|
||||
val := strings.TrimSpace(os.Getenv(key))
|
||||
if val == "" {
|
||||
return def
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
func loadToken() (string, error) {
|
||||
if tok := strings.TrimSpace(os.Getenv("NUBES_API_TOKEN")); tok != "" {
|
||||
return tok, nil
|
||||
@@ -95,46 +90,9 @@ func loadToken() (string, error) {
|
||||
}
|
||||
return strings.TrimSpace(string(b)), nil
|
||||
}
|
||||
repoRoot, err := FindRepoRoot()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
latest, err := findLatestToken(repoRoot)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if latest == "" {
|
||||
return "", errors.New("NUBES_API_TOKEN or TOKEN_FILE is required")
|
||||
}
|
||||
b, err := os.ReadFile(latest)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return strings.TrimSpace(string(b)), nil
|
||||
}
|
||||
|
||||
func findLatestToken(dir string) (string, error) {
|
||||
entries, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var latest string
|
||||
var latestTime int64
|
||||
for _, e := range entries {
|
||||
if e.IsDir() || !strings.HasSuffix(e.Name(), ".token") {
|
||||
continue
|
||||
}
|
||||
info, err := e.Info()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
mt := info.ModTime().Unix()
|
||||
if mt > latestTime {
|
||||
latestTime = mt
|
||||
latest = filepath.Join(dir, e.Name())
|
||||
}
|
||||
}
|
||||
return latest, nil
|
||||
// Легаси-фолбэк «найти последний *.token в корне репо» удален (2026-09-30):
|
||||
// токенов там нет, а такой поиск мог молча подхватить чужой токен.
|
||||
return "", errors.New("NUBES_API_TOKEN or TOKEN_FILE is required")
|
||||
}
|
||||
|
||||
// ReadServicesList читает список сервисов из файла.
|
||||
|
||||
Reference in New Issue
Block a user