Class: Pvectl::Config::Store

Inherits:
Object
  • Object
show all
Defined in:
lib/pvectl/config/store.rb

Overview

Handles YAML configuration file persistence.

Store manages saving configuration to YAML files with proper secure file permissions. It ensures config files are created with mode 0600 (owner read/write only) and directories with mode 0700 (owner access only).

Examples:

Saving configuration

store = Store.new
store.save("~/.pvectl/config", config_hash)

Updating current context

store.update_current_context("~/.pvectl/config", "production")

Constant Summary collapse

SECURE_MODE =

Secure file permissions (owner read/write only)

0o600
SECURE_DIR_MODE =

Secure directory permissions (owner access only)

0o700

Instance Method Summary collapse

Instance Method Details

#save(path, config) ⇒ void

This method returns an undefined value.

Saves configuration to a YAML file with secure permissions.

Creates the parent directory if it doesn’t exist, with secure permissions. The config file is written with mode 0600.

Parameters:

  • path (String)

    path to configuration file

  • config (Hash)

    configuration to save

Raises:

  • (Errno::EACCES)

    if permission denied



38
39
40
41
42
43
44
45
46
47
48
# File 'lib/pvectl/config/store.rb', line 38

def save(path, config)
  dir = File.dirname(path)

  unless File.directory?(dir)
    FileUtils.mkdir_p(dir)
    File.chmod(SECURE_DIR_MODE, dir)
  end

  File.write(path, YAML.dump(config))
  File.chmod(SECURE_MODE, path)
end

#update_current_context(path, context_name) ⇒ void

This method returns an undefined value.

Updates only the current-context in an existing config file.

Preserves all other configuration data and file permissions.

Parameters:

  • path (String)

    path to configuration file

  • context_name (String)

    new current context name

Raises:



58
59
60
61
62
63
64
65
66
67
68
# File 'lib/pvectl/config/store.rb', line 58

def update_current_context(path, context_name)
  raise ConfigNotFoundError, "Configuration file not found: #{path}" unless File.exist?(path)

  config = YAML.safe_load(File.read(path), permitted_classes: [Symbol])
  config["current-context"] = context_name

  # Preserve original permissions
  mode = File.stat(path).mode & 0o777
  File.write(path, YAML.dump(config))
  File.chmod(mode, path)
end

#upsert_cluster(path, cluster) ⇒ void

This method returns an undefined value.

Adds or updates a cluster in the configuration file.

If a cluster with the same name exists, it is replaced. Otherwise, the new cluster is appended.

Parameters:

  • path (String)

    path to configuration file

  • cluster (Models::Cluster)

    cluster to add or update

Raises:



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/pvectl/config/store.rb', line 109

def upsert_cluster(path, cluster)
  raise ConfigNotFoundError, "Configuration file not found: #{path}" unless File.exist?(path)

  config = YAML.safe_load(File.read(path), permitted_classes: [Symbol])
  clusters = config["clusters"] ||= []

  # Find existing cluster index
  existing_index = clusters.find_index { |c| c["name"] == cluster.name }

  if existing_index
    clusters[existing_index] = cluster.to_hash
  else
    clusters << cluster.to_hash
  end

  # Preserve original permissions
  mode = File.stat(path).mode & 0o777
  File.write(path, YAML.dump(config))
  File.chmod(mode, path)
end

#upsert_context(path, context) ⇒ void

This method returns an undefined value.

Adds or updates a context in the configuration file.

If a context with the same name exists, it is replaced. Otherwise, the new context is appended.

Parameters:

  • path (String)

    path to configuration file

  • context (Models::Context)

    context to add or update

Raises:



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/pvectl/config/store.rb', line 79

def upsert_context(path, context)
  raise ConfigNotFoundError, "Configuration file not found: #{path}" unless File.exist?(path)

  config = YAML.safe_load(File.read(path), permitted_classes: [Symbol])
  contexts = config["contexts"] ||= []

  # Find existing context index
  existing_index = contexts.find_index { |c| c["name"] == context.name }

  if existing_index
    contexts[existing_index] = context.to_hash
  else
    contexts << context.to_hash
  end

  # Preserve original permissions
  mode = File.stat(path).mode & 0o777
  File.write(path, YAML.dump(config))
  File.chmod(mode, path)
end

#upsert_user(path, user) ⇒ void

This method returns an undefined value.

Adds or updates a user in the configuration file.

If a user with the same name exists, it is replaced. Otherwise, the new user is appended.

Parameters:

  • path (String)

    path to configuration file

  • user (Models::User)

    user to add or update

Raises:



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/pvectl/config/store.rb', line 139

def upsert_user(path, user)
  raise ConfigNotFoundError, "Configuration file not found: #{path}" unless File.exist?(path)

  config = YAML.safe_load(File.read(path), permitted_classes: [Symbol])
  users = config["users"] ||= []

  # Find existing user index
  existing_index = users.find_index { |u| u["name"] == user.name }

  if existing_index
    users[existing_index] = user.to_hash
  else
    users << user.to_hash
  end

  # Preserve original permissions
  mode = File.stat(path).mode & 0o777
  File.write(path, YAML.dump(config))
  File.chmod(mode, path)
end