• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

aws / aws-codedeploy-agent / 4600315001

pending completion
4600315001

push

github

GitHub
Updating latest version info for master branch

1129 of 2362 relevant lines covered (47.8%)

2.1 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

31.48
/lib/instance_agent/plugins/codedeploy/deployment_specification.rb
1
require 'openssl'
1✔
2
require 'instance_metadata'
1✔
3
require 'open-uri'
1✔
4

5
module InstanceAgent
1✔
6
  module Plugins
1✔
7
    module CodeDeployPlugin
1✔
8
      class DeploymentSpecification
1✔
9
        DEFAULT_FILE_EXISTS_BEHAVIOR = 'DISALLOW'
1✔
10

11
        attr_accessor :deployment_id, :deployment_group_id, :deployment_group_name, :revision, :revision_source, :application_name, :deployment_type, :deployment_creator
1✔
12
        attr_accessor :bucket, :key, :bundle_type, :version, :etag
1✔
13
        attr_accessor :external_account, :repository, :commit_id, :anonymous, :external_auth_token
1✔
14
        attr_accessor :file_exists_behavior
1✔
15
        attr_accessor :local_location, :all_possible_lifecycle_events
1✔
16
        attr_accessor :app_spec_path
1✔
17
        class << self
1✔
18
          attr_accessor :cert_store
1✔
19
        end
20

21
        def self.init_cert_store(ca_chain_path)
1✔
22
          @cert_store = OpenSSL::X509::Store.new
1✔
23
          begin
24
            @cert_store.add_file ca_chain_path
1✔
25
          rescue OpenSSL::X509::StoreError => e
26
            raise "Could not load certificate store '#{ca_chain_path}'.\nCaused by: #{e.inspect}"
×
27
          end
28
          return @cert_store
1✔
29
        end
30

31
        @cert_store = init_cert_store(File.expand_path('../../../../certs/host-agent-deployment-signer-ca-chain.pem', File.dirname(__FILE__)))
1✔
32

33
        def initialize(data)
1✔
34
          raise 'Deployment Spec has no DeploymentId' unless property_set?(data, "DeploymentId")
×
35
          raise 'Deployment Spec has no DeploymentGroupId' unless property_set?(data, "DeploymentGroupId")
×
36
          raise 'Deployment Spec has no DeploymentGroupName' unless property_set?(data, "DeploymentGroupName")
×
37
          raise 'Deployment Spec has no ApplicationName' unless property_set?(data, "ApplicationName")
×
38

39
          @application_name = data["ApplicationName"]
×
40
          @deployment_group_name = data["DeploymentGroupName"]
×
41

42
          if data["DeploymentId"].start_with?("arn:")
×
43
            @deployment_id = getDeploymentIdFromArn(data["DeploymentId"])
×
44
          else
45
            @deployment_id = data["DeploymentId"]
×
46
          end
47
          @deployment_group_id = data["DeploymentGroupId"]
×
48
          @deployment_creator = data["DeploymentCreator"] || "user"
×
49
          @deployment_type = data["DeploymentType"] || "IN_PLACE"
×
50

51
          if property_set?(data, "AppSpecFilename")
×
52
            @app_spec_path = data["AppSpecFilename"]
×
53
          else
54
            @app_spec_path = "appspec.yml"
×
55
          end
56

57
          raise 'Must specify a revison' unless data["Revision"]
×
58
          @revision_source = data["Revision"]["RevisionType"]
×
59
          raise 'Must specify a revision source' unless @revision_source
×
60

61
          @file_exists_behavior = DEFAULT_FILE_EXISTS_BEHAVIOR
×
62
          if property_set?(data, "AgentActionOverrides")
×
63
            agentActionsOverrides = data["AgentActionOverrides"]
×
64
            if property_set?(agentActionsOverrides,  "AgentOverrides")
×
65
              agentActionsOverridesMap = agentActionsOverrides["AgentOverrides"]
×
66
              if property_set?(agentActionsOverridesMap, "FileExistsBehavior")
×
67
                @file_exists_behavior = agentActionsOverridesMap["FileExistsBehavior"].upcase
×
68
              end
69
            end
70
          end
71

72
          if property_set?(data, 'AllPossibleLifecycleEvents')
×
73
            @all_possible_lifecycle_events = data['AllPossibleLifecycleEvents']
×
74
          end
75

76
          case @revision_source
×
77
          when 'S3'
78
            @revision = data["Revision"]["S3Revision"]
×
79
            raise 'S3Revision in Deployment Spec must specify Bucket, Key and BundleType' unless valid_s3_revision?(@revision)
×
80
            raise 'BundleType in S3Revision must be tar, tgz or zip' unless valid_bundle_type?(@revision)
×
81

82
            @bucket = @revision["Bucket"]
×
83
            @key = @revision["Key"]
×
84
            @bundle_type = @revision["BundleType"]
×
85
            @version = @revision["Version"]
×
86
            @etag = @revision["ETag"]
×
87
          when 'GitHub'
88
            @revision = data["Revision"]["GitHubRevision"]
×
89
            raise 'GitHubRevision in Deployment Spec must specify Account, Repository and CommitId' unless valid_github_revision?(revision)
×
90
            @external_account = revision["Account"]
×
91
            @repository = revision["Repository"]
×
92
            @commit_id = revision["CommitId"]
×
93
            @external_auth_token = data["GitHubAccessToken"]
×
94
            @anonymous = @external_auth_token.nil?
×
95
            @bundle_type = @revision["BundleType"]
×
96
          when 'Local File', 'Local Directory'
97
            @revision = data["Revision"]["LocalRevision"]
×
98
            raise 'LocalRevision in Deployment Spec must specify Location and BundleType' unless valid_local_revision?(revision)
×
99
            raise 'BundleType in LocalRevision must be tar, tgz, zip, or directory' unless valid_local_bundle_type?(@revision)
×
100

101
            @local_location = @revision["Location"]
×
102
            @bundle_type = @revision["BundleType"]
×
103
          else
104
            raise 'Exactly one of S3Revision, GitHubRevision, or LocalRevision must be specified'
×
105
          end
106
        end
107
        # Decrypts the envelope /deployment specs
108
        # Params:
109
        # envelope: deployment specification that's to be checked and decrypted
110
        def self.parse(envelope)
1✔
111
          raise 'Provided deployment spec was nil' if envelope.nil?
×
112

113
          case envelope.format
×
114
          when "PKCS7/JSON"
115
            pkcs7 = OpenSSL::PKCS7.new(envelope.payload)
×
116
            pkcs7.verify([], @cert_store, nil, OpenSSL::PKCS7::NOVERIFY)
×
117
            # NOTE: the pkcs7.data field is only populated AFTER pkcs7.verify() is called!
118
            parse_deployment_spec_data(pkcs7.data)
×
119
          when "TEXT/JSON"
120
            raise "Unsupported DeploymentSpecification format: #{envelope.format}" unless AWS::CodeDeploy::Local::Deployer.running_as_developer_utility?
×
121
            # We only allow json unsigned messages from the local developer utility (codedeploy-local cli)
122
            # This is because the local cli cannot actually sign messages since it doens't have the private key
123
            # that the CodeDeploy service has.
124
            parse_deployment_spec_data(envelope.payload)
×
125
          else
126
            raise "Unsupported DeploymentSpecification format: #{envelope.format}"
×
127
          end
128
        end
129

130
        private
1✔
131
        def self.parse_deployment_spec_data(deployment_spec_data)
1✔
132
            deployment_spec = JSON.parse(deployment_spec_data)
×
133

134
            sanitized_spec = deployment_spec.clone
×
135
            sanitized_spec["GitHubAccessToken"] &&= "REDACTED"
×
136
            InstanceAgent::Log.debug("#{self.to_s}: Parse: #{sanitized_spec}")
×
137

138
            new(deployment_spec)
×
139
        end
140

141
        def property_set?(propertyHash, property)
1✔
142
          propertyHash.has_key?(property) && !propertyHash[property].nil? && !propertyHash[property].empty?
×
143
        end
144

145
        def valid_s3_revision?(revision)
1✔
146
          revision.nil? || %w(Bucket Key BundleType).all? { |k| revision.has_key?(k) }
×
147
        end
148

149
        def valid_github_revision?(revision)
1✔
150
          required_fields = %w(Account Repository CommitId)
×
151
          if !(revision.nil? || revision['Anonymous'].nil? || revision['Anonymous'])
×
152
            required_fields << 'OAuthToken'
×
153
          end
154
          revision.nil? || required_fields.all? { |k| revision.has_key?(k) }
×
155
        end
156

157
        def valid_local_revision?(revision)
1✔
158
          revision.nil? || %w(Location BundleType).all? { |k| revision.has_key?(k) }
×
159
        end
160

161
        private
1✔
162
        def valid_bundle_type?(revision)
1✔
163
          revision.nil? || %w(tar zip tgz).any? { |k| revision["BundleType"] == k }
×
164
        end
165

166
        def valid_local_bundle_type?(revision)
1✔
167
          revision.nil? || %w(tar zip tgz directory).any? { |k| revision["BundleType"] == k }
×
168
        end
169

170
        private
1✔
171
        def getDeploymentIdFromArn(arn)
1✔
172
          # example arn format: "arn:aws:codedeploy:us-east-1:123412341234:deployment/12341234-1234-1234-1234-123412341234"
173
          arn.split(":", 6)[5].split("/",2)[1]
×
174
        end
175
      end
176
    end
177
  end
178
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc