Toggle navigation
Toggle navigation
This project
Loading...
Sign in
서승완
/
kappa
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Graphs
Network
Create a new issue
Commits
Issue Boards
Authored by
Mitch Garnaat
2015-03-05 09:01:49 -0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
7c0fa2056f6e7efb6cf73c7faf40bdc908740002
7c0fa205
1 parent
89b41b78
Some refactoring. Added a status command. Rewrote the CLI to take more advantage of click.
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
144 additions
and
43 deletions
bin/kappa
kappa/context.py
kappa/event_source.py
kappa/function.py
kappa/stack.py
requirements.txt
setup.py
tests/unit/test_stack.py
bin/kappa
View file @
7c0fa20
...
...
@@ -18,47 +18,96 @@ import click
from
kappa.context
import
Context
@click.command
()
@click.option
(
'--config'
,
help
=
"Path to the Kappa config YAML file"
,
@click.group
()
@click.argument
(
'config'
,
type
=
click
.
File
(
'rb'
),
envvar
=
'KAPPA_CONFIG'
,
default
=
None
)
@click.option
(
'--debug/--no-debug'
,
default
=
False
,
help
=
'Turn on debugging output'
)
@click.argument
(
'command'
,
required
=
True
,
type
=
click
.
Choice
([
'deploy'
,
'test'
,
'tail'
,
'add-event-sources'
,
'delete'
])
)
def
main
(
config
=
None
,
debug
=
False
,
command
=
None
):
ctx
=
Context
(
config
,
debug
)
if
command
==
'deploy'
:
click
.
echo
(
'Deploying ...'
)
ctx
.
deploy
()
click
.
echo
(
'...done'
)
elif
command
==
'test'
:
click
.
echo
(
'Sending test data ...'
)
ctx
.
test
()
click
.
echo
(
'...done'
)
elif
command
==
'tail'
:
events
=
ctx
.
tail
()
for
event
in
events
:
print
(
event
[
'message'
])
elif
command
==
'delete'
:
click
.
echo
(
'Deleting ...'
)
ctx
.
delete
()
click
.
echo
(
'...done'
)
elif
command
==
'add-event-sources'
:
click
.
echo
(
'Adding event sources ...'
)
ctx
.
add_event_sources
()
click
.
echo
(
'...done'
)
@click.pass_context
def
cli
(
ctx
,
config
=
None
,
debug
=
False
):
config
=
config
ctx
.
obj
[
'debug'
]
=
debug
ctx
.
obj
[
'config'
]
=
config
@cli.command
()
@click.pass_context
def
deploy
(
ctx
):
context
=
Context
(
ctx
.
obj
[
'config'
],
ctx
.
obj
[
'debug'
])
click
.
echo
(
'deploying...'
)
context
.
deploy
()
click
.
echo
(
'...done'
)
@cli.command
()
@click.pass_context
def
test
(
ctx
):
context
=
Context
(
ctx
.
obj
[
'config'
],
ctx
.
obj
[
'debug'
])
click
.
echo
(
'testing...'
)
context
.
test
()
click
.
echo
(
'...done'
)
@cli.command
()
@click.pass_context
def
tail
(
ctx
):
context
=
Context
(
ctx
.
obj
[
'config'
],
ctx
.
obj
[
'debug'
])
click
.
echo
(
'tailing logs...'
)
context
.
tail
()
click
.
echo
(
'...done'
)
@cli.command
()
@click.pass_context
def
status
(
ctx
):
context
=
Context
(
ctx
.
obj
[
'config'
],
ctx
.
obj
[
'debug'
])
status
=
context
.
status
()
click
.
echo
(
click
.
style
(
'Stack'
,
bold
=
True
))
if
status
[
'stack'
]:
for
stack
in
status
[
'stack'
][
'Stacks'
]:
line
=
' {}: {}'
.
format
(
stack
[
'StackId'
],
stack
[
'StackStatus'
])
click
.
echo
(
click
.
style
(
line
,
fg
=
'green'
))
else
:
click
.
echo
(
click
.
style
(
' None'
,
fg
=
'green'
))
click
.
echo
(
click
.
style
(
'Function'
,
bold
=
True
))
if
status
[
'function'
]:
line
=
' {}'
.
format
(
status
[
'function'
][
'Configuration'
][
'FunctionName'
])
click
.
echo
(
click
.
style
(
line
,
fg
=
'green'
))
else
:
click
.
echo
(
click
.
style
(
' None'
,
fg
=
'green'
))
click
.
echo
(
click
.
style
(
'Event Sources'
,
bold
=
True
))
if
status
[
'event_sources'
]:
for
event_source
in
status
[
'event_sources'
]:
if
'EventSource'
in
event_source
:
line
=
' {}: {}'
.
format
(
event_source
[
'EventSource'
],
event_source
[
'IsActive'
])
click
.
echo
(
click
.
style
(
line
,
fg
=
'green'
))
else
:
line
=
' {}'
.
format
(
event_source
[
'CloudFunctionConfiguration'
][
'Id'
])
click
.
echo
(
click
.
style
(
line
,
fg
=
'green'
))
else
:
click
.
echo
(
click
.
style
(
' None'
,
fg
=
'green'
))
@cli.command
()
@click.pass_context
def
delete
(
ctx
):
context
=
Context
(
ctx
.
obj
[
'config'
],
ctx
.
obj
[
'debug'
])
click
.
echo
(
'deleting...'
)
context
.
delete
()
click
.
echo
(
'...done'
)
@cli.command
()
@click.pass_context
def
add_event_sources
(
ctx
):
context
=
Context
(
ctx
.
obj
[
'config'
],
ctx
.
obj
[
'debug'
])
click
.
echo
(
'adding event sources...'
)
context
.
add_event_sources
()
click
.
echo
(
'...done'
)
if
__name__
==
'__main__'
:
main
(
)
cli
(
obj
=
{}
)
...
...
kappa/context.py
View file @
7c0fa20
...
...
@@ -108,10 +108,7 @@ class Context(object):
event_source
.
add
(
self
.
function
)
def
deploy
(
self
):
if
self
.
_stack
.
exists
():
self
.
_stack
.
update
()
else
:
self
.
_stack
.
create
()
self
.
_stack
.
update
()
self
.
function
.
upload
()
def
test
(
self
):
...
...
@@ -123,3 +120,14 @@ class Context(object):
def
delete
(
self
):
self
.
_stack
.
delete
()
self
.
function
.
delete
()
for
event_source
in
self
.
event_sources
:
event_source
.
remove
(
self
.
function
)
def
status
(
self
):
status
=
{}
status
[
'stack'
]
=
self
.
_stack
.
status
()
status
[
'function'
]
=
self
.
function
.
status
()
status
[
'event_sources'
]
=
[]
for
event_source
in
self
.
event_sources
:
status
[
'event_sources'
]
.
append
(
event_source
.
status
(
self
.
function
))
return
status
...
...
kappa/event_source.py
View file @
7c0fa20
...
...
@@ -13,6 +13,8 @@
import
logging
from
botocore.exceptions
import
ClientError
import
kappa.aws
LOG
=
logging
.
getLogger
(
__name__
)
...
...
@@ -70,6 +72,17 @@ class KinesisEventSource(EventSource):
LOG
.
debug
(
response
)
return
response
def
status
(
self
,
function
):
LOG
.
debug
(
'getting status for event source
%
s'
,
self
.
arn
)
try
:
response
=
self
.
_lambda
.
get_event_source
(
UUID
=
self
.
_get_uuid
(
function
))
LOG
.
debug
(
response
)
except
ClientError
:
LOG
.
debug
(
'event source
%
s does not exist'
,
self
.
arn
)
response
=
None
return
response
class
S3EventSource
(
EventSource
):
...
...
@@ -112,3 +125,12 @@ class S3EventSource(EventSource):
Bucket
=
self
.
_get_bucket_name
(),
NotificationConfiguration
=
response
)
LOG
.
debug
(
response
)
def
status
(
self
,
function
):
LOG
.
debug
(
'status for s3 notification'
)
response
=
self
.
_s3
.
get_bucket_notification
(
Bucket
=
self
.
_get_bucket_name
())
LOG
.
debug
(
response
)
if
'CloudFunctionConfiguration'
not
in
response
:
response
=
None
return
response
...
...
kappa/function.py
View file @
7c0fa20
...
...
@@ -15,6 +15,8 @@ import logging
import
os
import
zipfile
from
botocore.exceptions
import
ClientError
import
kappa.aws
import
kappa.log
...
...
@@ -148,6 +150,17 @@ class Function(object):
LOG
.
debug
(
response
)
return
response
def
status
(
self
):
LOG
.
debug
(
'getting status for function
%
s'
,
self
.
name
)
try
:
response
=
self
.
_lambda_svc
.
get_function
(
FunctionName
=
self
.
name
)
LOG
.
debug
(
response
)
except
ClientError
:
LOG
.
debug
(
'function
%
s not found'
,
self
.
name
)
response
=
None
return
response
def
invoke_asynch
(
self
,
data_file
):
LOG
.
debug
(
'_invoke_async
%
s'
,
data_file
)
with
open
(
data_file
)
as
fp
:
...
...
kappa/stack.py
View file @
7c0fa20
...
...
@@ -98,7 +98,7 @@ class Stack(object):
msg
=
'Could not create stack
%
s:
%
s'
%
(
self
.
name
,
status
)
raise
ValueError
(
msg
)
def
create
(
self
):
def
_
create
(
self
):
LOG
.
debug
(
'create_stack: stack_name=
%
s'
,
self
.
name
)
template_body
=
open
(
self
.
template_path
)
.
read
()
try
:
...
...
@@ -110,7 +110,7 @@ class Stack(object):
LOG
.
exception
(
'Unable to create stack'
)
self
.
wait
()
def
update
(
self
):
def
_
update
(
self
):
LOG
.
debug
(
'create_stack: stack_name=
%
s'
,
self
.
name
)
template_body
=
open
(
self
.
template_path
)
.
read
()
try
:
...
...
@@ -125,6 +125,15 @@ class Stack(object):
LOG
.
exception
(
'Unable to update stack'
)
self
.
wait
()
def
update
(
self
):
if
self
.
exists
():
self
.
_update
()
else
:
self
.
_create
()
def
status
(
self
):
return
self
.
exists
()
def
delete
(
self
):
LOG
.
debug
(
'delete_stack: stack_name=
%
s'
,
self
.
name
)
try
:
...
...
requirements.txt
View file @
7c0fa20
botocore==0.
82
.0
botocore==0.
94
.0
click==3.3
PyYAML>=3.11
mock>=1.0.1
...
...
setup.py
View file @
7c0fa20
...
...
@@ -5,7 +5,7 @@ from setuptools import setup, find_packages
import
os
requires
=
[
'botocore==0.
82
.0'
,
'botocore==0.
94
.0'
,
'click==3.3'
,
'PyYAML>=3.11'
]
...
...
tests/unit/test_stack.py
View file @
7c0fa20
...
...
@@ -56,10 +56,10 @@ class TestStack(unittest.TestCase):
stack
=
Stack
(
mock_context
,
Config
)
self
.
assertTrue
(
stack
.
exists
())
def
test_
cre
ate
(
self
):
def
test_
upd
ate
(
self
):
mock_context
=
mock
.
Mock
()
stack
=
Stack
(
mock_context
,
Config
)
stack
.
cre
ate
()
stack
.
upd
ate
()
def
test_delete
(
self
):
mock_context
=
mock
.
Mock
()
...
...
Please
register
or
login
to post a comment