Class: Harbor::Project

Inherits:
Object
  • Object
show all
Defined in:
lib/harbor/project.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name:, path:, config_file: "config/deploy.yml", destinations: [], default_destination: nil, description: nil, allowed_operations: nil, allowed_exec_commands: nil, backend: "kamal", coolify: nil) ⇒ Project

Returns a new instance of Project.



8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/harbor/project.rb', line 8

def initialize(name:, path:, config_file: "config/deploy.yml", destinations: [],
               default_destination: nil, description: nil, allowed_operations: nil,
               allowed_exec_commands: nil, backend: "kamal", coolify: nil)
  @name = name
  @path = File.expand_path(path)
  @config_file = config_file
  @destinations = destinations
  @default_destination = default_destination
  @description = description
  @allowed_operations = allowed_operations
  @allowed_exec_commands = allowed_exec_commands
  @backend = backend
  @extra_settings = coolify || {}
end

Instance Attribute Details

#allowed_exec_commandsObject (readonly)

Returns the value of attribute allowed_exec_commands.



5
6
7
# File 'lib/harbor/project.rb', line 5

def allowed_exec_commands
  @allowed_exec_commands
end

#allowed_operationsObject (readonly)

Returns the value of attribute allowed_operations.



5
6
7
# File 'lib/harbor/project.rb', line 5

def allowed_operations
  @allowed_operations
end

#backendObject (readonly)

Returns the value of attribute backend.



5
6
7
# File 'lib/harbor/project.rb', line 5

def backend
  @backend
end

#config_fileObject (readonly)

Returns the value of attribute config_file.



5
6
7
# File 'lib/harbor/project.rb', line 5

def config_file
  @config_file
end

#default_destinationObject (readonly)

Returns the value of attribute default_destination.



5
6
7
# File 'lib/harbor/project.rb', line 5

def default_destination
  @default_destination
end

#descriptionObject (readonly)

Returns the value of attribute description.



5
6
7
# File 'lib/harbor/project.rb', line 5

def description
  @description
end

#destinationsObject (readonly)

Returns the value of attribute destinations.



5
6
7
# File 'lib/harbor/project.rb', line 5

def destinations
  @destinations
end

#nameObject (readonly)

Returns the value of attribute name.



5
6
7
# File 'lib/harbor/project.rb', line 5

def name
  @name
end

#pathObject (readonly)

Returns the value of attribute path.



5
6
7
# File 'lib/harbor/project.rb', line 5

def path
  @path
end

Instance Method Details

#adapterObject



23
24
25
26
27
28
29
30
# File 'lib/harbor/project.rb', line 23

def adapter
  case @backend
  when "coolify"
    CoolifyAdapter.new(self)
  else
    KamalAdapter.new(self)
  end
end

#deploy_yml_pathObject



32
33
34
# File 'lib/harbor/project.rb', line 32

def deploy_yml_path
  File.join(@path, @config_file)
end

#exec_command_allowed?(command) ⇒ Boolean

Returns:

  • (Boolean)


54
55
56
57
58
59
60
61
62
# File 'lib/harbor/project.rb', line 54

def exec_command_allowed?(command)
  # Always reject shell metacharacters regardless of allowlist
  return false if command.nil? || command.empty? || SHELL_METACHARACTERS.match?(command)

  return true if @allowed_exec_commands.nil? || @allowed_exec_commands.empty?

  argv = command.split(/\s+/)
  @allowed_exec_commands.any? { |pattern| command_matches?(argv, pattern) }
end

#operation_allowed?(operation) ⇒ Boolean

Returns:

  • (Boolean)


48
49
50
51
52
# File 'lib/harbor/project.rb', line 48

def operation_allowed?(operation)
  return true if @allowed_operations.nil?

  @allowed_operations.include?(operation.to_s)
end

#resolve_destination(destination = nil) ⇒ Object



40
41
42
43
44
45
46
# File 'lib/harbor/project.rb', line 40

def resolve_destination(destination = nil)
  dest = destination || @default_destination
  if dest.nil? && @destinations.length > 1
    raise ConfigError, "Project '#{@name}' has multiple destinations (#{@destinations.join(', ')}). Specify one with -d."
  end
  dest || @destinations.first
end

#to_hObject



64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/harbor/project.rb', line 64

def to_h
  h = { "path" => @path }
  h["config_file"] = @config_file if @config_file != "config/deploy.yml"
  h["destinations"] = @destinations unless @destinations.empty?
  h["default_destination"] = @default_destination if @default_destination
  h["description"] = @description if @description
  h["allowed_operations"] = @allowed_operations if @allowed_operations
  h["allowed_exec_commands"] = @allowed_exec_commands if @allowed_exec_commands
  h["backend"] = @backend if @backend != "kamal"
  h["coolify"] = @extra_settings unless @extra_settings.empty?
  h
end

#valid?Boolean

Returns:

  • (Boolean)


36
37
38
# File 'lib/harbor/project.rb', line 36

def valid?
  File.directory?(@path) && File.exist?(deploy_yml_path)
end