Exemplo n.º 1
0
def r_create():

    args_rules = [Rules.LABEL.value, Rules.PUBLIC_KEY.value]

    try:
        ret = dict()
        ret['state'] = ji.Common.exchange_state(20000)

        ji.Check.previewing(args_rules, request.json)

        ssh_key = SSHKey()

        ssh_key.label = request.json.get('label')
        ssh_key.public_key = request.json.get('public_key')

        if ssh_key.exist_by('public_key'):
            ret['state'] = ji.Common.exchange_state(40901)
            ret['state']['sub']['zh-cn'] = ''.join(
                [ret['state']['sub']['zh-cn'], ': ', ssh_key.public_key])
            return ret

        ssh_key.create()

        return ret

    except ji.PreviewingError, e:
        return json.loads(e.message)
Exemplo n.º 2
0
def post(capsule_id, user):
    sshkey_data = request.get_json()
    capsule = _get_capsule(capsule_id, user)

    for public_key in sshkey_data:
        if not valid_sshkey(public_key):
            raise BadRequest(description=f"'{public_key}' is not "
                             "a valid ssh public key")

        for key in capsule.authorized_keys:
            if public_key == key.public_key:
                raise Conflict(description="'public_key' already exist "
                               "for this capsule")

        sshkey = SSHKey(public_key=public_key)
        capsule.authorized_keys.append(sshkey)

    db.session.commit()

    now = datetime.datetime.now()
    if now > (capsule.no_update + datetime.timedelta(hours=24)):
        nats.publish_webapp_present(capsule)

    result = Capsule.query.filter_by(id=capsule_id).first()
    return capsule_output_schema.dump(result), 201, {
        'Location': f'{request.base_url}/capsules/{capsule.id}',
    }
Exemplo n.º 3
0
def get_user_ssh_keys(username):
    username = pipes.quote(username)

    keyFile = open("/home/" + username + "/.ssh/authorized_keys", "r")
    keys = []

    for line in keyFile.read().split("\n"):
        if line:
            k = sshpubkeys.SSHKey(line)
            keys.append(SSHKey(k.comment, k.hash_md5()))

    keyFile.close()

    return keys
Exemplo n.º 4
0
def create_ssh_key(request):
    if request.method == 'POST':
        form = SSHKeyForm(request.POST,request.FILES)
        if form.is_valid():
            key = SSHKey(name=form.cleaned_data['name'],key=form.cleaned_data['rsa_key'],user=request.user)
#             key = form.save(commit=False)
#             key.user=request.user
            key.save()
            from settings.settings import AUTHORIZED_KEYS_FILE
            import subprocess
#            subprocess.check_call(['/bin/chmod','600',AUTHORIZED_KEYS_FILE])
            auth_keys = open(AUTHORIZED_KEYS_FILE, "a")
            auth_keys.write(key.create_authorized_key()+'\n')
            auth_keys.close()
#            subprocess.check_call(['/bin/chmod','400',AUTHORIZED_KEYS_FILE])
            return HttpResponseRedirect(reverse('list_ssh_keys'))
    else:
        form = SSHKeyForm()
    return render(request, 'ssh/new_key.html', {'form': form})
Exemplo n.º 5
0
def post(user):
    sshkey_data = request.get_json()
    # data = sshkey_schema.load(sshkey_data)

    if 'public_key' not in sshkey_data:
        raise BadRequest("The key 'public_key' is required.")

    public_key = sshkey_data["public_key"]

    if not valid_sshkey(public_key):
        raise BadRequest(description=f"'{public_key}' is not "
                         "a valid ssh public key")

    sshkey = SSHKey(public_key=public_key, user_id=user.id)
    db.session.add(sshkey)
    db.session.commit()

    nats_publish_webapp_present(user)

    result = SSHKey.query.get(sshkey.id)
    return sshkey_schema.dump(result), 201, {
        'Location': f'{request.base_url}/sshkeys/{sshkey.id}',
    }
Exemplo n.º 6
0
def r_update(_id):

    ssh_key = SSHKey()

    args_rules = [Rules.ID.value]

    if 'label' in request.json:
        args_rules.append(Rules.LABEL.value, )

    if 'public_key' in request.json:
        args_rules.append(Rules.PUBLIC_KEY.value, )

    if args_rules.__len__() < 2:
        ret = dict()
        ret['state'] = ji.Common.exchange_state(20000)
        return ret

    request.json['id'] = _id

    try:
        ji.Check.previewing(args_rules, request.json)
        ssh_key.id = request.json.get('id')

        ssh_key.get()
        ssh_key.label = request.json.get('label', ssh_key.label)
        ssh_key.public_key = request.json.get('public_key', ssh_key.public_key)

        ssh_key.update()
        ssh_key.get()

        ret = dict()
        ret['state'] = ji.Common.exchange_state(20000)
        ret['data'] = ssh_key.__dict__
        return ret
    except ji.PreviewingError, e:
        return json.loads(e.message)
Exemplo n.º 7
0
    def __init__(self, db):

        self.validation_rule1 = AvailableOptionValidationRule(
            type=ValidationRuleEnum.min,
            arg="1",
        )

        self.validation_rule2 = AvailableOptionValidationRule(
            type=ValidationRuleEnum.max,
            arg="42",
        )

        self.validation_rule1bis = AvailableOptionValidationRule(
            type=ValidationRuleEnum.min,
            arg="1",
        )

        self.validation_rule2bis = AvailableOptionValidationRule(
            type=ValidationRuleEnum.max,
            arg="42",
        )

        self.validation_rule3 = AvailableOptionValidationRule(
            type=ValidationRuleEnum.regex,
            arg="^[a-z0-9][-a-z0-9]*[a-z0-9]$",
        )

        self.validation_rule4 = AvailableOptionValidationRule(
            type=ValidationRuleEnum.eq,
            arg="foobar",
        )

        self.validation_rule5 = AvailableOptionValidationRule(
            type=ValidationRuleEnum.neq,
            arg="barfoo",
        )

        self.validation_rule6 = AvailableOptionValidationRule(
            type=ValidationRuleEnum.format,
            arg="json",
        )

        self.validation_rule7 = AvailableOptionValidationRule(
            type=ValidationRuleEnum.into,
            arg="[a, b, c]",
        )

        self.available_opt1 = AvailableOption(
            access_level=RoleEnum.user,
            tag="Apache",
            field_name="vhost.conf",
            value_type=OptionValueTypeEnum.base64,
            field_description="Apache2 vhost configuration file.",
            default_value="",
        )

        self.available_opt2 = AvailableOption(
            access_level=RoleEnum.user,
            tag="PHP",
            field_name="worker",
            value_type=OptionValueTypeEnum.integer,
            field_description="PHP worker count.",
            default_value="6",
            validation_rules=[
                self.validation_rule1,
                self.validation_rule2,
            ],
        )

        self.available_opt2bis = AvailableOption(
            access_level=RoleEnum.user,
            tag="PHP",
            field_name="test_min_max",
            value_type=OptionValueTypeEnum.integer,
            field_description="Test min and max option rules",
            default_value="6",
            validation_rules=[
                self.validation_rule1bis,
                self.validation_rule2bis,
            ],
        )

        self.available_opt3 = AvailableOption(
            access_level=RoleEnum.user,
            tag="SQL",
            field_name="my.cnf",
            value_type=OptionValueTypeEnum.base64,
            field_description="MySQL configuration file.",
        )

        self.available_opt4 = AvailableOption(
            access_level=RoleEnum.admin,
            tag="PHP",
            field_name="test_regex",
            value_type=OptionValueTypeEnum.string,
            field_description="Test regex option rule",
            validation_rules=[
                self.validation_rule3,
            ]
        )

        self.available_opt5 = AvailableOption(
            access_level=RoleEnum.admin,
            tag="PHP",
            field_name="test_eq",
            value_type=OptionValueTypeEnum.string,
            field_description="Test eq option rule",
            validation_rules=[
                self.validation_rule4,
            ]
        )

        self.available_opt6 = AvailableOption(
            access_level=RoleEnum.admin,
            tag="PHP",
            field_name="test_neq",
            value_type=OptionValueTypeEnum.string,
            field_description="Test neq option rule",
            validation_rules=[
                self.validation_rule5,
            ]
        )

        self.available_opt7 = AvailableOption(
            access_level=RoleEnum.admin,
            tag="PHP",
            field_name="test_format",
            value_type=OptionValueTypeEnum.string,
            field_description="Test format option rule",
            validation_rules=[
                self.validation_rule6,
            ]
        )

        self.available_opt8 = AvailableOption(
            access_level=RoleEnum.admin,
            tag="PHP",
            field_name="test_into",
            value_type=OptionValueTypeEnum.string,
            field_description="Test into option rule",
            validation_rules=[
                self.validation_rule7,
            ]
        )

        self.runtime1 = Runtime(
            name="apache-2.4 php-7.2.x",
            description="Stack web classique Apache 2.4 + PHP 7.2.x",
            fam="Apache PHP",
            runtime_type=RuntimeTypeEnum.webapp,
            available_opts=[
                self.available_opt1,
                self.available_opt2,
            ],
        )

        self.runtime2 = Runtime(
            name="MariaDB 10.1",
            description="SQL server",
            fam="SQL",
            runtime_type=RuntimeTypeEnum.addon,
            available_opts=[
                self.available_opt3,
            ],
            uri_template='{"pattern": "mysql://{udbname}:{password}@'
                         'host:port/{udbname}",'
                         '"variables": [{"length": 16, "name": "udbname", '
                         '"src": "capsule", "unique": true, "set_name": true},'
                         '{"length": 32, "name": "password", '
                         '"set_name": false, "src": "random", '
                         '"unique": false}]}',
        )

        self.runtime3 = Runtime(
            name="MariaDB 12.1",
            description="SQL server",
            fam="SQL",
            runtime_type=RuntimeTypeEnum.addon,
        )

        self.runtime4 = Runtime(
            name="apache-3.1 php-9.3.x",
            description="Stack web futuriste Apache 3.1 + PHP 9.3.x",
            fam="Apache PHP",
            runtime_type=RuntimeTypeEnum.webapp,
            available_opts=[
                self.available_opt2bis,
                self.available_opt4,
                self.available_opt5,
                self.available_opt6,
                self.available_opt7,
                self.available_opt8,
            ],
        )

        self.fqdn1 = FQDN(
            name="main.fqdn.ac-versailles.fr",
            alias=False,
        )
        self.fqdn2 = FQDN(
            name="secondary.fqdn.ac-versailles.fr",
            alias=True,
        )

        self.option1 = Option(
            field_name="worker",
            tag="PHP",
            value="42",
            value_type='integer',
        )

        self.cron1 = Cron(
            command="rm -rf *",
            hour="*/6",
            minute="15",
            month="*",
        )

        self.webapp1 = WebApp(
            env='{"HTTP_PROXY": "http://*****:*****@doe",
        )

        self.sshkey2 = SSHKey(
            public_key="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC/YCx71smBufMXF"
                       "thQQsjSW18adRCpI5L+I8z4qtx+8SQeTSFWZF/E9QSgG6UoajwzCb"
                       "5oQM/+M9Hmel1rSUUfjGx8HQV4smVbCRTgRGDJTpFhbvoeO0AC6YJ"
                       "6n/eBzu0zKVlW0UqMqJU1cQLWgnFfSDURmzLHlnPn467uXPx5Pw=="
                       " jane@doe",
        )

        self.sshkey3 = SSHKey(
            public_key="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDCVu8lOZxm+7fjM"
                       "QpdNuU2HinAhWmmEtYcX9wxCcBs14GmDrDSOhZB61bq9vdzkSlV0W"
                       "st711mUlEZlXh/999NL7iAy6COKYxsEmRgbCU+9k8rBsSTDcXS6MW"
                       "+aJI4vnqMgVSGwBDgxZs4X2mthYhCitgbk9D3WbstAinUkhEtzQ=="
                       " phpseclib-generated-key"
        )

        token = "KDCte1raIV-ItPQf-sf_tapY4q-kLmvlcJ9yUKPlqbo"
        hashed_token = sha512(token.encode('ascii')).hexdigest()
        self.apptoken1 = AppToken(
            app="My super app",
            token=hashed_token)

        # Users.
        self.admin_user = User(
            name="admin_user", role=RoleEnum.admin)
        self.superadmin_user = User(
            name="superadmin_user", role=RoleEnum.superadmin)
        self.fake_user = User(
            name="fake_user", role=RoleEnum.user)
        self.user1 = User(
            name="user1", role=RoleEnum.user)
        self.user2 = User(
            name="user2", role=RoleEnum.user)
        self.user3 = User(
            name="user3", role=RoleEnum.user)

        self.user1.public_keys.append(self.sshkey1)
        self.user2.public_keys.append(self.sshkey2)

        self.user3.apptokens.append(self.apptoken1)

        self.capsule1 = Capsule(
            name="test-default-capsule",
            owners=[
                self.user1,
                self.user2,
            ],
            webapp=self.webapp1,
            addons=[
                self.addon1,
            ],
            authorized_keys=[
                self.sshkey2,
                self.sshkey3,
            ],
            fqdns=[
                self.fqdn1,
                self.fqdn2,
            ],
            force_redirect_https=True,
            enable_https=True,
        )

        array_obj = []

        for name, value in vars(self).items():
            array_obj.append(value)

        db.session.add_all(array_obj)
        db.session.commit()

        # Just handy in test functions.
        self.users = [
            self.admin_user,
            self.superadmin_user,
            self.fake_user,
            self.user1,
            self.user2,
            self.user3,
        ]

        self.runtimes = [
            self.runtime1,
            self.runtime2,
            self.runtime3,
            self.runtime4,
        ]
Exemplo n.º 8
0
def post():
    capsule_data = request.get_json()
    data = capsule_input_schema.load(capsule_data)

    cluster_parts = getClusterPartsUsage("")
    if 'size' in data:
        proposed_parts = SizeEnum.getparts(data['size'])
    else:
        proposed_parts = SizeEnum.getparts(SizeEnum.tiny)
    target_parts = cluster_parts + proposed_parts
    if target_parts > current_app.config['CLUSTER_PARTS']:
        msg = 'Please set a lower size for this capsule or prepare '\
              'some Bitcoins... :-)'
        raise PaymentRequired(description=msg)

    try:  # Check if owners exist on Keycloak
        check_owners_on_keycloak(data['owners'])
    except KeycloakUserNotFound as e:
        raise BadRequest(
            description=f'{e.missing_username} is an invalid user.')

    # Get existent users, create the others
    for i, owner in enumerate(data['owners']):
        user = User.query.filter_by(name=owner).one_or_none()
        if user is None:  # User does not exist in DB
            data['owners'][i] = User(name=owner, role=RoleEnum.user)
        else:
            data['owners'][i] = user

    # Get existent ssh keys, create the others
    if 'authorized_keys' in data:
        for i, public_key in enumerate(data['authorized_keys']):
            sshkey = SSHKey.query\
                .filter_by(public_key=public_key).one_or_none()
            if sshkey is None:
                data['authorized_keys'][i] = SSHKey(public_key=public_key)
            else:
                data['authorized_keys'][i] = sshkey

    capsule_name = data['name']

    # https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-label-names
    if not is_valid_name(capsule_name):
        msg = f'The capsule name "{capsule_name}" is invalid: only lowercase '\
            'alphanumeric characters or "-" are allowed, the first and the '\
            'last characters must be alphanumeric, the name must have at '\
            'least 2 characters and less than 64 characters.'
        raise BadRequest(description=msg)

    newArgs = dict()
    if "fqdns" in data:
        fqdns_list = [e['name'] for e in data["fqdns"]]
        if len(fqdns_list) != len(set(fqdns_list)):
            raise BadRequest(description='Repetitions are not '
                             'allowed for FQDNs')
        try:
            fqdns = FQDN.create(data["fqdns"])
        except FQDNAlreadyExists as e:
            raise BadRequest(description=f'{e.existing_fqdn} already exists.')
        data.pop("fqdns")
        newArgs["fqdns"] = fqdns

    caps = Capsule.query.filter_by(name=capsule_name).limit(1).one_or_none()
    if caps is not None:
        raise BadRequest(description=f'{capsule_name} already exists.')

    capsule = Capsule(**data, **newArgs)
    db.session.add(capsule)
    db.session.commit()

    caps = Capsule.query.filter_by(id=capsule.id).first()
    result = capsule_output_schema.dump(caps)

    return result, 201, {
        'Location': f'{request.base_url}/capsules/{capsule.id}',
    }
Exemplo n.º 9
0
def r_bind(ssh_key_id, uuids):

    args_rules = [Rules.SSH_KEY_ID_EXT.value, Rules.UUIDS.value]

    try:
        ji.Check.previewing(args_rules, {
            'ssh_key_id': ssh_key_id,
            'uuids': uuids
        })

        ret = dict()
        ret['state'] = ji.Common.exchange_state(20000)

        ssh_key = SSHKey()
        ssh_key.id = ssh_key_id

        # 判断 ssh_key id 为 ssh_key_id 的对象是否存在
        if not ssh_key.exist():
            ret['state'] = ji.Common.exchange_state(40401)
            ret['state']['sub']['zh-cn'] = ''.join(
                [ret['state']['sub']['zh-cn'], ': ssh_key_id: ', ssh_key_id])
            return ret

        # 获取已经和该 ssh_key 绑定过的 guest uuid 集合,用于判断是否已经绑定过该 ssh_key,避免重复绑定
        rows, _ = SSHKeyGuestMapping.get_by_filter(
            filter_str=':'.join(['ssh_key_id', 'eq', ssh_key_id]))

        guests_uuid = list()
        for row in rows:
            guests_uuid.append(row['guest_uuid'])

        ssh_key_guest_mapping = SSHKeyGuestMapping()
        for uuid in uuids.split(','):
            # 如果已经绑定过,则忽略
            if uuid in guests_uuid:
                continue

            ssh_key_guest_mapping.ssh_key_id = ssh_key_id
            ssh_key_guest_mapping.guest_uuid = uuid
            ssh_key_guest_mapping.create()

            update_ssh_key(uuid=uuid)

        # 返回执行结果
        rows, _ = SSHKeyGuestMapping.get_by_filter(
            filter_str=':'.join(['ssh_key_id', 'eq', ssh_key_id]))
        guests_uuid = list()
        for row in rows:
            guests_uuid.append(row['guest_uuid'])

        if guests_uuid.__len__() == 0:
            guests_uuid.append('_')

        request.__setattr__(
            'args',
            ImmutableMultiDict([
                ('filter', ':'.join(['uuid', 'in', ','.join(guests_uuid)])),
                ('page_size', 10000)
            ]))

        return guest_base.get_by_filter()
    except ji.PreviewingError, e:
        return json.loads(e.message)